Removed input.h, queue.h, spy.h and sysmetrics.h and moved their
[wine] / windows / class.c
1 /*
2  * Window classes functions
3  *
4  * Copyright 1993, 1996 Alexandre Julliard
5  *           1998 Juergen Schmied (jsch)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * FIXME: In win32 all classes are local. They are registered at
22  *        program start. Processes CANNOT share classes. (Source: some
23  *        win31->NT migration book)
24  *
25  * FIXME: There seems to be a general problem with hInstance in WINE
26  *   classes are getting registered with wrong hInstance.
27  */
28
29 #include "config.h"
30 #include "wine/port.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "wine/winbase16.h"
36 #include "winerror.h"
37 #include "windef.h"
38 #include "wingdi.h"
39 #include "wine/winuser16.h"
40 #include "wownt32.h"
41 #include "wine/unicode.h"
42 #include "win.h"
43 #include "user.h"
44 #include "controls.h"
45 #include "dce.h"
46 #include "winproc.h"
47 #include "wine/debug.h"
48
49 WINE_DEFAULT_DEBUG_CHANNEL(class);
50
51 typedef struct tagCLASS
52 {
53     struct tagCLASS *next;          /* Next class */
54     struct tagCLASS *prev;          /* Prev class */
55     UINT             cWindows;      /* Count of existing windows */
56     UINT             style;         /* Class style */
57     WNDPROC          winprocA;      /* Window procedure (ASCII) */
58     WNDPROC          winprocW;      /* Window procedure (Unicode) */
59     INT              cbClsExtra;    /* Class extra bytes */
60     INT              cbWndExtra;    /* Window extra bytes */
61     LPWSTR           menuName;      /* Default menu name (Unicode followed by ASCII) */
62     SEGPTR           segMenuName;   /* Default menu name as SEGPTR */
63     struct tagDCE   *dce;           /* Class DCE (if CS_CLASSDC) */
64     HINSTANCE        hInstance;     /* Module that created the task */
65     HICON            hIcon;         /* Default icon */
66     HICON            hIconSm;       /* Default small icon */
67     HCURSOR          hCursor;       /* Default cursor */
68     HBRUSH           hbrBackground; /* Default background */
69     ATOM             atomName;      /* Name of the class */
70 } CLASS;
71
72 static CLASS *firstClass;
73
74 /***********************************************************************
75  *           get_class_ptr
76  */
77 static CLASS *get_class_ptr( HWND hwnd, BOOL write_access )
78 {
79     WND *ptr = WIN_GetPtr( hwnd );
80
81     if (ptr)
82     {
83         if (ptr != WND_OTHER_PROCESS) return ptr->class;
84         if (IsWindow( hwnd )) /* check other processes */
85         {
86             if (write_access)
87             {
88                 /* modifying classes in other processes is not allowed */
89                 SetLastError( ERROR_ACCESS_DENIED );
90                 return NULL;
91             }
92             FIXME( "reading from class of other process window %p\n", hwnd );
93             /* DbgBreakPoint(); */
94         }
95     }
96     SetLastError( ERROR_INVALID_WINDOW_HANDLE );
97     return NULL;
98 }
99
100
101 /***********************************************************************
102  *           release_class_ptr
103  */
104 inline static void release_class_ptr( CLASS *ptr )
105 {
106     USER_Unlock();
107 }
108
109
110 /***********************************************************************
111  *           CLASS_GetProc
112  *
113  * Get the class winproc for a given proc type
114  */
115 static WNDPROC16 CLASS_GetProc( CLASS *classPtr, WINDOWPROCTYPE type )
116 {
117     WNDPROC proc = classPtr->winprocA;
118
119     if (classPtr->winprocW)
120     {
121         /* if we have a Unicode proc, use it if we have no ASCII proc
122          * or if we have both and Unicode was requested
123          */
124         if (!proc || type == WIN_PROC_32W) proc = classPtr->winprocW;
125     }
126     return WINPROC_GetProc( proc, type );
127 }
128
129
130 /***********************************************************************
131  *           CLASS_SetProc
132  *
133  * Set the class winproc for a given proc type.
134  * Returns the previous window proc.
135  */
136 static WNDPROC16 CLASS_SetProc( CLASS *classPtr, WNDPROC newproc, WINDOWPROCTYPE type )
137 {
138     WNDPROC *proc = &classPtr->winprocA;
139     WNDPROC16 ret;
140
141     if (classPtr->winprocW)
142     {
143         /* if we have a Unicode proc, use it if we have no ASCII proc
144          * or if we have both and Unicode was requested
145          */
146         if (!*proc || type == WIN_PROC_32W) proc = &classPtr->winprocW;
147     }
148     ret = WINPROC_GetProc( *proc, type );
149     WINPROC_SetProc( proc, newproc, type, WIN_PROC_CLASS );
150     /* now free the one that we didn't set */
151     if (classPtr->winprocA && classPtr->winprocW)
152     {
153         if (proc == &classPtr->winprocA)
154         {
155             WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS );
156             classPtr->winprocW = 0;
157         }
158         else
159         {
160             WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS );
161             classPtr->winprocA = 0;
162         }
163     }
164     return ret;
165 }
166
167
168 /***********************************************************************
169  *           CLASS_GetMenuNameA
170  *
171  * Get the menu name as a ASCII string.
172  */
173 inline static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
174 {
175     if (!HIWORD(classPtr->menuName)) return (LPSTR)classPtr->menuName;
176     return (LPSTR)(classPtr->menuName + strlenW(classPtr->menuName) + 1);
177 }
178
179
180 /***********************************************************************
181  *           CLASS_GetMenuName16
182  *
183  * Get the menu name as a SEGPTR.
184  */
185 inline static SEGPTR CLASS_GetMenuName16( CLASS *classPtr )
186 {
187     if (!HIWORD(classPtr->menuName)) return (SEGPTR)classPtr->menuName;
188     if (!classPtr->segMenuName)
189         classPtr->segMenuName = MapLS( CLASS_GetMenuNameA(classPtr) );
190     return classPtr->segMenuName;
191 }
192
193
194 /***********************************************************************
195  *           CLASS_GetMenuNameW
196  *
197  * Get the menu name as a Unicode string.
198  */
199 inline static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
200 {
201     return classPtr->menuName;
202 }
203
204
205 /***********************************************************************
206  *           CLASS_SetMenuNameA
207  *
208  * Set the menu name in a class structure by copying the string.
209  */
210 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
211 {
212     UnMapLS( classPtr->segMenuName );
213     classPtr->segMenuName = 0;
214     if (HIWORD(classPtr->menuName)) HeapFree( GetProcessHeap(), 0, classPtr->menuName );
215     if (HIWORD(name))
216     {
217         DWORD lenA = strlen(name) + 1;
218         DWORD lenW = MultiByteToWideChar( CP_ACP, 0, name, lenA, NULL, 0 );
219         classPtr->menuName = HeapAlloc( GetProcessHeap(), 0, lenA + lenW*sizeof(WCHAR) );
220         MultiByteToWideChar( CP_ACP, 0, name, lenA, classPtr->menuName, lenW );
221         memcpy( classPtr->menuName + lenW, name, lenA );
222     }
223     else classPtr->menuName = (LPWSTR)name;
224 }
225
226
227 /***********************************************************************
228  *           CLASS_SetMenuNameW
229  *
230  * Set the menu name in a class structure by copying the string.
231  */
232 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
233 {
234     UnMapLS( classPtr->segMenuName );
235     classPtr->segMenuName = 0;
236     if (HIWORD(classPtr->menuName)) HeapFree( GetProcessHeap(), 0, classPtr->menuName );
237     if (HIWORD(name))
238     {
239         DWORD lenW = strlenW(name) + 1;
240         DWORD lenA = WideCharToMultiByte( CP_ACP, 0, name, lenW, NULL, 0, NULL, NULL );
241         classPtr->menuName = HeapAlloc( GetProcessHeap(), 0, lenA + lenW*sizeof(WCHAR) );
242         memcpy( classPtr->menuName, name, lenW*sizeof(WCHAR) );
243         WideCharToMultiByte( CP_ACP, 0, name, lenW,
244                              (char *)(classPtr->menuName + lenW), lenA, NULL, NULL );
245     }
246     else classPtr->menuName = (LPWSTR)name;
247 }
248
249
250 /***********************************************************************
251  *           CLASS_FreeClass
252  *
253  * Free a class structure.
254  */
255 static BOOL CLASS_FreeClass( CLASS *classPtr )
256 {
257     TRACE("%p\n", classPtr);
258
259     /* Check if we can remove this class */
260
261     if (classPtr->cWindows > 0)
262     {
263         SetLastError( ERROR_CLASS_HAS_WINDOWS );
264         return FALSE;
265     }
266
267     /* Remove the class from the linked list */
268
269     if (classPtr->next) classPtr->next->prev = classPtr->prev;
270     if (classPtr->prev) classPtr->prev->next = classPtr->next;
271     else firstClass = classPtr->next;
272
273     /* Delete the class */
274
275     if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
276     if (classPtr->hbrBackground > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1))
277         DeleteObject( classPtr->hbrBackground );
278     GlobalDeleteAtom( classPtr->atomName );
279     WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS );
280     WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS );
281     UnMapLS( classPtr->segMenuName );
282     HeapFree( GetProcessHeap(), 0, classPtr->menuName );
283     HeapFree( GetProcessHeap(), 0, classPtr );
284     return TRUE;
285 }
286
287
288 /***********************************************************************
289  *           CLASS_FreeModuleClasses
290  */
291 void CLASS_FreeModuleClasses( HMODULE16 hModule )
292 {
293     CLASS *ptr, *next;
294
295     TRACE("0x%08x\n", hModule);
296
297     USER_Lock();
298     for (ptr = firstClass; ptr; ptr = next)
299     {
300         next = ptr->next;
301         if (ptr->hInstance == HINSTANCE_32(hModule)) CLASS_FreeClass( ptr );
302     }
303     USER_Unlock();
304 }
305
306
307 /***********************************************************************
308  *           CLASS_FindClassByAtom
309  *
310  * Return a pointer to the class.
311  * hinstance has been normalized by the caller.
312  *
313  * NOTES
314  *  980805 a local class will be found now if registred with hInst=0
315  *  and looed up with a hInst!=0. msmoney does it (jsch)
316  *
317  *  Local class registered with a USER instance handle are found as if
318  *  they were global classes.
319  */
320 static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
321 {
322     CLASS * class, *tclass = 0, *user_class = 0;
323     HINSTANCE16 hUser = GetModuleHandle16("USER");
324
325     TRACE("0x%08x %p\n", atom, hinstance);
326
327     /* First search task-specific classes */
328
329     for (class = firstClass; (class); class = class->next)
330     {
331         if (class->style & CS_GLOBALCLASS) continue;
332         if (class->atomName == atom)
333         {
334             if (hinstance==class->hInstance || hinstance == (HINSTANCE)0xffff)
335             {
336                 TRACE("-- found local %p\n", class);
337                 return class;
338             }
339             if (class->hInstance == 0) tclass = class;
340             else if(class->hInstance == HINSTANCE_32(hUser))
341             {
342                 user_class = class;
343             }
344         }
345     }
346
347     /* Then search global classes */
348
349     for (class = firstClass; (class); class = class->next)
350     {
351         if (!(class->style & CS_GLOBALCLASS)) continue;
352         if (class->atomName == atom)
353         {
354             TRACE("-- found global %p\n", class);
355             return class;
356         }
357     }
358
359     /* Check if there was a local class registered with USER */
360     if( user_class )
361     {
362         TRACE("--found local USER class %p\n", user_class);
363         return user_class;
364     }
365
366     /* Then check if there was a local class with hInst=0*/
367     if ( tclass )
368     {
369         WARN("-- found local Class registred with hInst=0\n");
370         return tclass;
371     }
372
373     TRACE("-- not found\n");
374     return 0;
375 }
376
377
378 /***********************************************************************
379  *           CLASS_RegisterClass
380  *
381  * The real RegisterClass() functionality.
382  */
383 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
384                                    DWORD style, INT classExtra, INT winExtra )
385 {
386     CLASS *classPtr;
387
388     TRACE("atom=0x%x hinst=%p style=0x%lx clExtr=0x%x winExtr=0x%x\n",
389           atom, hInstance, style, classExtra, winExtra );
390
391    /* Check if a class with this name already exists */
392     classPtr = CLASS_FindClassByAtom( atom, hInstance );
393     if (classPtr)
394     {
395         /* Class can be created only if it is local and */
396         /* if the class with the same name is global.   */
397
398         if ((style & CS_GLOBALCLASS) || !(classPtr->style & CS_GLOBALCLASS))
399         {
400             SetLastError( ERROR_CLASS_ALREADY_EXISTS );
401             return NULL;
402         }
403     }
404
405     /* Fix the extra bytes value */
406
407     if (classExtra < 0) classExtra = 0;
408     else if (classExtra > 40)  /* Extra bytes are limited to 40 in Win32 */
409         WARN("Class extra bytes %d is > 40\n", classExtra);
410     if (winExtra < 0) winExtra = 0;
411     else if (winExtra > 40)    /* Extra bytes are limited to 40 in Win32 */
412         WARN("Win extra bytes %d is > 40\n", winExtra );
413
414     /* Create the class */
415
416     classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
417     if (!classPtr) return NULL;
418     classPtr->style       = style;
419     classPtr->cbWndExtra  = winExtra;
420     classPtr->cbClsExtra  = classExtra;
421     classPtr->hInstance   = hInstance;
422     classPtr->atomName    = atom;
423     classPtr->dce         = (style & CS_CLASSDC) ? DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
424
425     /* Other non-null values must be set by caller */
426
427     if ((classPtr->next = firstClass)) firstClass->prev = classPtr;
428     firstClass = classPtr;
429     return classPtr;
430 }
431
432
433 /***********************************************************************
434  *           CLASS_UnregisterClass
435  *
436  * The real UnregisterClass() functionality.
437  */
438 static BOOL CLASS_UnregisterClass( ATOM atom, HINSTANCE hInstance )
439 {
440     CLASS *classPtr;
441     BOOL ret = FALSE;
442
443     USER_Lock();
444     if (atom &&
445         (classPtr = CLASS_FindClassByAtom( atom, hInstance )) &&
446         (!hInstance || classPtr->hInstance == hInstance))
447     {
448         ret = CLASS_FreeClass( classPtr );
449     }
450     else SetLastError( ERROR_CLASS_DOES_NOT_EXIST );
451
452     USER_Unlock();
453     return ret;
454 }
455
456
457 /***********************************************************************
458  *           CLASS_RegisterBuiltinClass
459  *
460  * Register a builtin control class.
461  * This allows having both ASCII and Unicode winprocs for the same class.
462  */
463 ATOM CLASS_RegisterBuiltinClass( const struct builtin_class_descr *descr )
464 {
465     ATOM atom;
466     CLASS *classPtr;
467
468     if (!(atom = GlobalAddAtomA( descr->name ))) return 0;
469
470     if (!(classPtr = CLASS_RegisterClass( atom, 0, descr->style, 0, descr->extra )))
471     {
472         GlobalDeleteAtom( atom );
473         return 0;
474     }
475
476     classPtr->hCursor       = LoadCursorA( 0, descr->cursor );
477     classPtr->hbrBackground = descr->brush;
478
479     if (descr->procA) WINPROC_SetProc( &classPtr->winprocA, descr->procA,
480                                        WIN_PROC_32A, WIN_PROC_CLASS );
481     if (descr->procW) WINPROC_SetProc( &classPtr->winprocW, descr->procW,
482                                        WIN_PROC_32W, WIN_PROC_CLASS );
483     return atom;
484 }
485
486
487 /***********************************************************************
488  *           CLASS_AddWindow
489  *
490  * Add a new window using this class, and return the necessary
491  * information for creating the window.
492  */
493 CLASS *CLASS_AddWindow( ATOM atom, HINSTANCE inst, WINDOWPROCTYPE type,
494                         INT *winExtra, WNDPROC *winproc, DWORD *style, struct tagDCE **dce )
495 {
496     CLASS *class;
497     if (type == WIN_PROC_16) inst = HINSTANCE_32(GetExePtr(HINSTANCE_16(inst)));
498
499     if (!(class = CLASS_FindClassByAtom( atom, inst ))) return NULL;
500     class->cWindows++;
501
502     if (type == WIN_PROC_32W)
503     {
504         if (!(*winproc = class->winprocW)) *winproc = class->winprocA;
505     }
506     else
507     {
508         if (!(*winproc = class->winprocA)) *winproc = class->winprocW;
509     }
510     *winExtra = class->cbWndExtra;
511     *style = class->style;
512     *dce = class->dce;
513     return class;
514 }
515
516
517 /***********************************************************************
518  *           CLASS_RemoveWindow
519  *
520  * Remove a window from the class window count.
521  */
522 void CLASS_RemoveWindow( CLASS *cls )
523 {
524     if (cls && cls->cWindows) cls->cWindows--;
525 }
526
527
528 /***********************************************************************
529  *              RegisterClass (USER.57)
530  */
531 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
532 {
533     ATOM atom;
534     CLASS *classPtr;
535     int iSmIconWidth, iSmIconHeight;
536     HINSTANCE hInstance = HINSTANCE_32(GetExePtr(wc->hInstance));
537
538     if (!(atom = GlobalAddAtomA( MapSL(wc->lpszClassName) ))) return 0;
539     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
540                                           wc->cbClsExtra, wc->cbWndExtra )))
541     {
542         GlobalDeleteAtom( atom );
543         return 0;
544     }
545
546     TRACE("atom=%04x wndproc=%08lx hinst=%p bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
547           atom, (DWORD)wc->lpfnWndProc, hInstance,
548           wc->hbrBackground, wc->style, wc->cbClsExtra,
549           wc->cbWndExtra, classPtr,
550           HIWORD(wc->lpszClassName) ? (char *)MapSL(wc->lpszClassName) : "" );
551
552     iSmIconWidth  = GetSystemMetrics(SM_CXSMICON);
553     iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
554
555     classPtr->hIcon         = HICON_32(wc->hIcon);
556     classPtr->hIconSm       = CopyImage(classPtr->hIcon, IMAGE_ICON,
557                                         iSmIconWidth, iSmIconHeight,
558                                         LR_COPYFROMRESOURCE);
559     classPtr->hCursor       = HCURSOR_32(wc->hCursor);
560     classPtr->hbrBackground = HBRUSH_32(wc->hbrBackground);
561
562     WINPROC_SetProc( &classPtr->winprocA, (WNDPROC)wc->lpfnWndProc,
563                      WIN_PROC_16, WIN_PROC_CLASS );
564     CLASS_SetMenuNameA( classPtr, MapSL(wc->lpszMenuName) );
565
566     return atom;
567 }
568
569
570 /***********************************************************************
571  *              RegisterClassA (USER32.@)
572  * RETURNS
573  *      >0: Unique identifier
574  *      0: Failure
575  */
576 ATOM WINAPI RegisterClassA( const WNDCLASSA* wc ) /* [in] Address of structure with class data */
577 {
578     ATOM atom;
579     int iSmIconWidth, iSmIconHeight;
580     CLASS *classPtr;
581
582     if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
583
584     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
585                                           wc->cbClsExtra, wc->cbWndExtra )))
586     {
587         GlobalDeleteAtom( atom );
588         return 0;
589     }
590
591     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
592           atom, wc->lpfnWndProc, wc->hInstance,
593           wc->hbrBackground, wc->style, wc->cbClsExtra,
594           wc->cbWndExtra, classPtr,
595           HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
596
597     iSmIconWidth  = GetSystemMetrics(SM_CXSMICON);
598     iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
599
600     classPtr->hIcon         = wc->hIcon;
601     classPtr->hIconSm       = CopyImage(wc->hIcon, IMAGE_ICON,
602                                         iSmIconWidth, iSmIconHeight,
603                                         LR_COPYFROMRESOURCE);
604     classPtr->hCursor       = wc->hCursor;
605     classPtr->hbrBackground = wc->hbrBackground;
606
607     WINPROC_SetProc( &classPtr->winprocA, wc->lpfnWndProc,
608                      WIN_PROC_32A, WIN_PROC_CLASS );
609     CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
610     return atom;
611 }
612
613
614 /***********************************************************************
615  *              RegisterClassW (USER32.@)
616  */
617 ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
618 {
619     ATOM atom;
620     int iSmIconWidth, iSmIconHeight;
621     CLASS *classPtr;
622
623     if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
624
625     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
626                                           wc->cbClsExtra, wc->cbWndExtra )))
627     {
628         GlobalDeleteAtom( atom );
629         return 0;
630     }
631
632     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
633           atom, wc->lpfnWndProc, wc->hInstance,
634           wc->hbrBackground, wc->style, wc->cbClsExtra,
635           wc->cbWndExtra, classPtr );
636
637     iSmIconWidth  = GetSystemMetrics(SM_CXSMICON);
638     iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
639
640     classPtr->hIcon         = wc->hIcon;
641     classPtr->hIconSm       = CopyImage(wc->hIcon, IMAGE_ICON,
642                                         iSmIconWidth, iSmIconHeight,
643                                         LR_COPYFROMRESOURCE);
644     classPtr->hCursor       = wc->hCursor;
645     classPtr->hbrBackground = wc->hbrBackground;
646
647     WINPROC_SetProc( &classPtr->winprocW, wc->lpfnWndProc,
648                      WIN_PROC_32W, WIN_PROC_CLASS );
649     CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
650     return atom;
651 }
652
653
654 /***********************************************************************
655  *              RegisterClassEx (USER.397)
656  */
657 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
658 {
659     ATOM atom;
660     CLASS *classPtr;
661     HINSTANCE hInstance = HINSTANCE_32(GetExePtr( wc->hInstance ));
662
663     if (!(atom = GlobalAddAtomA( MapSL(wc->lpszClassName) ))) return 0;
664     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
665                                           wc->cbClsExtra, wc->cbWndExtra )))
666     {
667         GlobalDeleteAtom( atom );
668         return 0;
669     }
670
671     TRACE("atom=%04x wndproc=%p hinst=%p bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
672           atom, wc->lpfnWndProc, hInstance,
673           wc->hbrBackground, wc->style, wc->cbClsExtra,
674           wc->cbWndExtra, classPtr );
675
676     classPtr->hIcon         = HICON_32(wc->hIcon);
677     classPtr->hIconSm       = HICON_32(wc->hIconSm);
678     classPtr->hCursor       = HCURSOR_32(wc->hCursor);
679     classPtr->hbrBackground = HBRUSH_32(wc->hbrBackground);
680
681     WINPROC_SetProc( &classPtr->winprocA, (WNDPROC)wc->lpfnWndProc,
682                      WIN_PROC_16, WIN_PROC_CLASS );
683     CLASS_SetMenuNameA( classPtr, MapSL(wc->lpszMenuName) );
684     return atom;
685 }
686
687
688 /***********************************************************************
689  *              RegisterClassExA (USER32.@)
690  */
691 ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
692 {
693     ATOM atom;
694     CLASS *classPtr;
695
696     if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
697
698     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
699                                           wc->cbClsExtra, wc->cbWndExtra )))
700     {
701         GlobalDeleteAtom( atom );
702         return 0;
703     }
704
705     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
706           atom, wc->lpfnWndProc, wc->hInstance,
707           wc->hbrBackground, wc->style, wc->cbClsExtra,
708           wc->cbWndExtra, classPtr );
709
710     classPtr->hIcon         = wc->hIcon;
711     classPtr->hIconSm       = wc->hIconSm;
712     classPtr->hCursor       = wc->hCursor;
713     classPtr->hbrBackground = wc->hbrBackground;
714     WINPROC_SetProc( &classPtr->winprocA, wc->lpfnWndProc, WIN_PROC_32A, WIN_PROC_CLASS );
715     CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
716     return atom;
717 }
718
719
720 /***********************************************************************
721  *              RegisterClassExW (USER32.@)
722  */
723 ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
724 {
725     ATOM atom;
726     CLASS *classPtr;
727
728     if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
729
730     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
731                                           wc->cbClsExtra, wc->cbWndExtra )))
732     {
733         GlobalDeleteAtom( atom );
734         return 0;
735     }
736
737     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
738           atom, wc->lpfnWndProc, wc->hInstance,
739           wc->hbrBackground, wc->style, wc->cbClsExtra,
740           wc->cbWndExtra, classPtr );
741
742     classPtr->hIcon         = wc->hIcon;
743     classPtr->hIconSm       = wc->hIconSm;
744     classPtr->hCursor       = wc->hCursor;
745     classPtr->hbrBackground = wc->hbrBackground;
746     WINPROC_SetProc( &classPtr->winprocW, wc->lpfnWndProc, WIN_PROC_32W, WIN_PROC_CLASS );
747     CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
748     return atom;
749 }
750
751
752 /***********************************************************************
753  *              UnregisterClass (USER.403)
754  */
755 BOOL16 WINAPI UnregisterClass16( LPCSTR className, HINSTANCE16 hInstance )
756 {
757     return UnregisterClassA( className, HINSTANCE_32(GetExePtr( hInstance )) );
758 }
759
760 /***********************************************************************
761  *              UnregisterClassA (USER32.@)
762  *
763  */
764 BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
765 {
766     TRACE("%s %p\n",debugstr_a(className), hInstance);
767     return CLASS_UnregisterClass( GlobalFindAtomA( className ), hInstance );
768 }
769
770 /***********************************************************************
771  *              UnregisterClassW (USER32.@)
772  */
773 BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
774 {
775     TRACE("%s %p\n",debugstr_w(className), hInstance);
776     return CLASS_UnregisterClass( GlobalFindAtomW( className ), hInstance );
777 }
778
779
780 /***********************************************************************
781  *              GetClassWord (USER32.@)
782  */
783 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
784 {
785     CLASS *class;
786     WORD retvalue = 0;
787
788     if (offset < 0) return GetClassLongA( hwnd, offset );
789
790     TRACE("%p %x\n",hwnd, offset);
791
792     if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
793
794     if (offset <= class->cbClsExtra - sizeof(WORD))
795         memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) );
796     else
797         SetLastError( ERROR_INVALID_INDEX );
798     release_class_ptr( class );
799     return retvalue;
800 }
801
802
803 /***********************************************************************
804  *              GetClassLong (USER.131)
805  */
806 LONG WINAPI GetClassLong16( HWND16 hwnd16, INT16 offset )
807 {
808     CLASS *class;
809     LONG ret;
810     HWND hwnd = (HWND)(ULONG_PTR)hwnd16;  /* no need for full handle */
811
812     TRACE("%p %d\n",hwnd, offset);
813
814     switch( offset )
815     {
816     case GCL_WNDPROC:
817         if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
818         ret = (LONG)CLASS_GetProc( class, WIN_PROC_16 );
819         release_class_ptr( class );
820         return ret;
821     case GCL_MENUNAME:
822         if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
823         ret = (LONG)CLASS_GetMenuName16( class );
824         release_class_ptr( class );
825         return ret;
826     default:
827         return GetClassLongA( hwnd, offset );
828     }
829 }
830
831
832 /***********************************************************************
833  *              GetClassLongW (USER32.@)
834  */
835 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
836 {
837     CLASS *class;
838     LONG retvalue = 0;
839
840     TRACE("%p %d\n", hwnd, offset);
841
842     if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
843
844     if (offset >= 0)
845     {
846         if (offset <= class->cbClsExtra - sizeof(LONG))
847             memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) );
848         else
849             SetLastError( ERROR_INVALID_INDEX );
850         release_class_ptr( class );
851         return retvalue;
852     }
853
854     switch(offset)
855     {
856     case GCL_HBRBACKGROUND:
857         retvalue = (LONG)class->hbrBackground;
858         break;
859     case GCL_HCURSOR:
860         retvalue = (LONG)class->hCursor;
861         break;
862     case GCL_HICON:
863         retvalue = (LONG)class->hIcon;
864         break;
865     case GCL_HICONSM:
866         retvalue = (LONG)class->hIconSm;
867         break;
868     case GCL_STYLE:
869         retvalue = (LONG)class->style;
870         break;
871     case GCL_CBWNDEXTRA:
872         retvalue = (LONG)class->cbWndExtra;
873         break;
874     case GCL_CBCLSEXTRA:
875         retvalue = (LONG)class->cbClsExtra;
876         break;
877     case GCL_HMODULE:
878         retvalue = (LONG)class->hInstance;
879         break;
880     case GCL_WNDPROC:
881         retvalue = (LONG)CLASS_GetProc( class, WIN_PROC_32W );
882         break;
883     case GCL_MENUNAME:
884         retvalue = (LONG)CLASS_GetMenuNameW( class );
885         break;
886     case GCW_ATOM:
887         retvalue = (DWORD)class->atomName;
888         break;
889     default:
890         SetLastError( ERROR_INVALID_INDEX );
891         break;
892     }
893     release_class_ptr( class );
894     return retvalue;
895 }
896
897
898 /***********************************************************************
899  *              GetClassLongA (USER32.@)
900  */
901 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
902 {
903     CLASS *class;
904     LONG retvalue;
905
906     if (offset != GCL_WNDPROC && offset != GCL_MENUNAME)
907         return GetClassLongW( hwnd, offset );
908
909     TRACE("%p %d\n", hwnd, offset);
910
911     if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
912
913     if (offset == GCL_WNDPROC)
914         retvalue = (LONG)CLASS_GetProc( class, WIN_PROC_32A );
915     else  /* GCL_MENUNAME */
916         retvalue = (LONG)CLASS_GetMenuNameA( class );
917
918     release_class_ptr( class );
919     return retvalue;
920 }
921
922
923 /***********************************************************************
924  *              SetClassWord (USER32.@)
925  */
926 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
927 {
928     CLASS *class;
929     WORD retval = 0;
930
931     if (offset < 0) return SetClassLongA( hwnd, offset, (DWORD)newval );
932
933     TRACE("%p %d %x\n", hwnd, offset, newval);
934
935     if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
936
937     if (offset <= class->cbClsExtra - sizeof(WORD))
938     {
939         void *ptr = (char *)(class + 1) + offset;
940         memcpy( &retval, ptr, sizeof(retval) );
941         memcpy( ptr, &newval, sizeof(newval) );
942     }
943     else SetLastError( ERROR_INVALID_INDEX );
944
945     release_class_ptr( class );
946     return retval;
947 }
948
949
950 /***********************************************************************
951  *              SetClassLong (USER.132)
952  */
953 LONG WINAPI SetClassLong16( HWND16 hwnd16, INT16 offset, LONG newval )
954 {
955     CLASS *class;
956     LONG retval;
957     HWND hwnd = (HWND)(ULONG_PTR)hwnd16;  /* no need for full handle */
958
959     TRACE("%p %d %lx\n", hwnd, offset, newval);
960
961     switch(offset)
962     {
963     case GCL_WNDPROC:
964         if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
965         retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_16 );
966         release_class_ptr( class );
967         return retval;
968     case GCL_MENUNAME:
969         newval = (LONG)MapSL( newval );
970         /* fall through */
971     default:
972         return SetClassLongA( hwnd, offset, newval );
973     }
974 }
975
976
977 /***********************************************************************
978  *              SetClassLongW (USER32.@)
979  */
980 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
981 {
982     CLASS *class;
983     LONG retval = 0;
984
985     TRACE("%p %d %lx\n", hwnd, offset, newval);
986
987     if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
988
989     if (offset >= 0)
990     {
991         if (offset <= class->cbClsExtra - sizeof(LONG))
992         {
993             void *ptr = (char *)(class + 1) + offset;
994             memcpy( &retval, ptr, sizeof(retval) );
995             memcpy( ptr, &newval, sizeof(newval) );
996         }
997         else SetLastError( ERROR_INVALID_INDEX );
998     }
999     else switch(offset)
1000     {
1001     case GCL_MENUNAME:
1002         CLASS_SetMenuNameW( class, (LPCWSTR)newval );
1003         retval = 0;  /* Old value is now meaningless anyway */
1004         break;
1005     case GCL_WNDPROC:
1006         retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_32W );
1007         break;
1008     case GCL_HBRBACKGROUND:
1009         retval = (LONG)class->hbrBackground;
1010         class->hbrBackground = (HBRUSH)newval;
1011         break;
1012     case GCL_HCURSOR:
1013         retval = (LONG)class->hCursor;
1014         class->hCursor = (HCURSOR)newval;
1015         break;
1016     case GCL_HICON:
1017         retval = (LONG)class->hIcon;
1018         class->hIcon = (HICON)newval;
1019         break;
1020     case GCL_HICONSM:
1021         retval = (LONG)class->hIconSm;
1022         class->hIconSm = (HICON)newval;
1023         break;
1024     case GCL_STYLE:
1025         retval = (LONG)class->style;
1026         class->style = newval;
1027         break;
1028     case GCL_CBWNDEXTRA:
1029         retval = (LONG)class->cbWndExtra;
1030         class->cbWndExtra = newval;
1031         break;
1032     case GCL_HMODULE:
1033         retval = (LONG)class->hInstance;
1034         class->hInstance = (HINSTANCE)newval;
1035         break;
1036     case GCW_ATOM:
1037         retval = (DWORD)class->atomName;
1038         class->atomName = newval;
1039         break;
1040     case GCL_CBCLSEXTRA:  /* cannot change this one */
1041         SetLastError( ERROR_INVALID_PARAMETER );
1042         break;
1043     default:
1044         SetLastError( ERROR_INVALID_INDEX );
1045         break;
1046     }
1047     release_class_ptr( class );
1048     return retval;
1049 }
1050
1051
1052 /***********************************************************************
1053  *              SetClassLongA (USER32.@)
1054  */
1055 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
1056 {
1057     CLASS *class;
1058     LONG retval;
1059
1060     if (offset != GCL_WNDPROC && offset != GCL_MENUNAME)
1061         return SetClassLongW( hwnd, offset, newval );
1062
1063     TRACE("%p %d %lx\n", hwnd, offset, newval);
1064
1065     if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
1066
1067     if (offset == GCL_WNDPROC)
1068         retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_32A );
1069     else  /* GCL_MENUNAME */
1070     {
1071         CLASS_SetMenuNameA( class, (LPCSTR)newval );
1072         retval = 0;  /* Old value is now meaningless anyway */
1073     }
1074     release_class_ptr( class );
1075     return retval;
1076 }
1077
1078
1079 /***********************************************************************
1080  *              GetClassNameA (USER32.@)
1081  */
1082 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1083 {
1084     INT ret = GlobalGetAtomNameA( GetClassLongA( hwnd, GCW_ATOM ), buffer, count );
1085
1086     TRACE("%p %s %x\n",hwnd, debugstr_a(buffer), count);
1087     return ret;
1088 }
1089
1090
1091 /***********************************************************************
1092  *              GetClassNameW (USER32.@)
1093  */
1094 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1095 {
1096     INT ret = GlobalGetAtomNameW( GetClassLongW( hwnd, GCW_ATOM ), buffer, count );
1097
1098     TRACE("%p %s %x\n",hwnd, debugstr_w(buffer), count);
1099     return ret;
1100 }
1101
1102
1103 /***********************************************************************
1104  *              GetClassInfo (USER.404)
1105  */
1106 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInst16, SEGPTR name, WNDCLASS16 *wc )
1107 {
1108     ATOM atom;
1109     CLASS *classPtr;
1110     HINSTANCE hInstance = HINSTANCE_32(GetExePtr( hInst16 ));
1111
1112     TRACE("%p %s %p\n",hInstance, debugstr_a(MapSL(name)), wc);
1113
1114     if (!(atom = GlobalFindAtomA( MapSL(name) )) ||
1115         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1116         return FALSE;
1117     if ((hInstance != classPtr->hInstance) &&
1118         !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1119         return FALSE;
1120     wc->style         = (UINT16)classPtr->style;
1121     wc->lpfnWndProc   = CLASS_GetProc( classPtr, WIN_PROC_16 );
1122     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1123     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1124     wc->hInstance     = classPtr->style & CS_GLOBALCLASS ? GetModuleHandle16("USER") : HINSTANCE_16(classPtr->hInstance);
1125     wc->hIcon         = HICON_16(classPtr->hIcon);
1126     wc->hCursor       = HCURSOR_16(classPtr->hCursor);
1127     wc->hbrBackground = HBRUSH_16(classPtr->hbrBackground);
1128     wc->lpszClassName = name;
1129     wc->lpszMenuName  = CLASS_GetMenuName16( classPtr );
1130     return TRUE;
1131 }
1132
1133
1134 /***********************************************************************
1135  *              GetClassInfoA (USER32.@)
1136  */
1137 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1138                                WNDCLASSA *wc )
1139 {
1140     ATOM atom;
1141     CLASS *classPtr;
1142
1143     TRACE("%p %p %p\n",hInstance, name, wc);
1144
1145     /* workaround: if hInstance=NULL you expect to get the system classes
1146     but this classes (as example from comctl32.dll SysListView) won't be
1147     registered with hInstance=NULL in WINE because of the late loading
1148     of this dll. fixes file dialogs in WinWord95 (jsch)*/
1149
1150     if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1151         return FALSE;
1152
1153     if (!(classPtr->style & CS_GLOBALCLASS) &&
1154         classPtr->hInstance &&
1155         (hInstance != classPtr->hInstance))
1156     {
1157         if (hInstance) return FALSE;
1158         WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1159     }
1160
1161     wc->style         = classPtr->style;
1162     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
1163     wc->cbClsExtra    = classPtr->cbClsExtra;
1164     wc->cbWndExtra    = classPtr->cbWndExtra;
1165     wc->hInstance     = hInstance;
1166     wc->hIcon         = (HICON)classPtr->hIcon;
1167     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1168     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1169     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1170     wc->lpszClassName = name;
1171     return TRUE;
1172 }
1173
1174
1175 /***********************************************************************
1176  *              GetClassInfoW (USER32.@)
1177  */
1178 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1179                                WNDCLASSW *wc )
1180 {
1181     ATOM atom;
1182     CLASS *classPtr;
1183
1184     TRACE("%p %p %p\n",hInstance, name, wc);
1185
1186     if (        !(atom=GlobalFindAtomW(name)) ||
1187                 !(classPtr=CLASS_FindClassByAtom(atom,hInstance))
1188     )
1189         return FALSE;
1190
1191     if (!(classPtr->style & CS_GLOBALCLASS) &&
1192         classPtr->hInstance &&
1193         (hInstance != classPtr->hInstance))
1194     {
1195         if (hInstance) return FALSE;
1196         WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name));
1197     }
1198     wc->style         = classPtr->style;
1199     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
1200     wc->cbClsExtra    = classPtr->cbClsExtra;
1201     wc->cbWndExtra    = classPtr->cbWndExtra;
1202     wc->hInstance     = hInstance;
1203     wc->hIcon         = (HICON)classPtr->hIcon;
1204     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1205     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1206     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1207     wc->lpszClassName = name;
1208     return TRUE;
1209 }
1210
1211
1212 /***********************************************************************
1213  *              GetClassInfoEx (USER.398)
1214  *
1215  * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1216  * same in Win16 as in Win32. --AJ
1217  */
1218 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInst16, SEGPTR name, WNDCLASSEX16 *wc )
1219 {
1220     ATOM atom;
1221     CLASS *classPtr;
1222     HINSTANCE hInstance = HINSTANCE_32(GetExePtr( hInst16 ));
1223
1224     TRACE("%p %s %p\n",hInstance,debugstr_a( MapSL(name) ), wc);
1225
1226     if (!(atom = GlobalFindAtomA( MapSL(name) )) ||
1227         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1228         (hInstance != classPtr->hInstance)) return FALSE;
1229     wc->style         = classPtr->style;
1230     wc->lpfnWndProc   = CLASS_GetProc( classPtr, WIN_PROC_16 );
1231     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1232     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1233     wc->hInstance     = HINSTANCE_16(classPtr->hInstance);
1234     wc->hIcon         = HICON_16(classPtr->hIcon);
1235     wc->hIconSm       = HICON_16(classPtr->hIconSm);
1236     wc->hCursor       = HCURSOR_16(classPtr->hCursor);
1237     wc->hbrBackground = HBRUSH_16(classPtr->hbrBackground);
1238     wc->lpszClassName = (SEGPTR)0;
1239     wc->lpszMenuName  = CLASS_GetMenuName16( classPtr );
1240     wc->lpszClassName = name;
1241
1242     /* We must return the atom of the class here instead of just TRUE. */
1243     return atom;
1244 }
1245
1246
1247 /***********************************************************************
1248  *              GetClassInfoExA (USER32.@)
1249  */
1250 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1251                                  WNDCLASSEXA *wc )
1252 {
1253     ATOM atom;
1254     CLASS *classPtr;
1255
1256     TRACE("%p %p %p\n",hInstance, name, wc);
1257
1258     if (!(atom = GlobalFindAtomA( name )) ||
1259         !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1260         /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1261     wc->style         = classPtr->style;
1262     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
1263     wc->cbClsExtra    = classPtr->cbClsExtra;
1264     wc->cbWndExtra    = classPtr->cbWndExtra;
1265     wc->hInstance     = classPtr->hInstance;
1266     wc->hIcon         = (HICON)classPtr->hIcon;
1267     wc->hIconSm       = (HICON)classPtr->hIconSm;
1268     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1269     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1270     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1271     wc->lpszClassName = name;
1272
1273     /* We must return the atom of the class here instead of just TRUE. */
1274     return atom;
1275 }
1276
1277
1278 /***********************************************************************
1279  *              GetClassInfoExW (USER32.@)
1280  */
1281 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1282                                  WNDCLASSEXW *wc )
1283 {
1284     ATOM atom;
1285     CLASS *classPtr;
1286
1287     TRACE("%p %p %p\n",hInstance, name, wc);
1288
1289     if (!(atom = GlobalFindAtomW( name )) ||
1290         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1291         (hInstance != classPtr->hInstance)) return FALSE;
1292     wc->style         = classPtr->style;
1293     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
1294     wc->cbClsExtra    = classPtr->cbClsExtra;
1295     wc->cbWndExtra    = classPtr->cbWndExtra;
1296     wc->hInstance     = classPtr->hInstance;
1297     wc->hIcon         = (HICON)classPtr->hIcon;
1298     wc->hIconSm       = (HICON)classPtr->hIconSm;
1299     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1300     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1301     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1302     wc->lpszClassName = name;
1303
1304     /* We must return the atom of the class here instead of just TRUE. */
1305     return atom;
1306 }
1307
1308
1309 #if 0  /* toolhelp is in kernel, so this cannot work */
1310
1311 /***********************************************************************
1312  *              ClassFirst (TOOLHELP.69)
1313  */
1314 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1315 {
1316     TRACE("%p\n",pClassEntry);
1317     pClassEntry->wNext = 1;
1318     return ClassNext16( pClassEntry );
1319 }
1320
1321
1322 /***********************************************************************
1323  *              ClassNext (TOOLHELP.70)
1324  */
1325 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1326 {
1327     int i;
1328     CLASS *class = firstClass;
1329
1330     TRACE("%p\n",pClassEntry);
1331
1332     if (!pClassEntry->wNext) return FALSE;
1333     for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1334     if (!class)
1335     {
1336         pClassEntry->wNext = 0;
1337         return FALSE;
1338     }
1339     pClassEntry->hInst = class->hInstance;
1340     pClassEntry->wNext++;
1341     GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1342                           sizeof(pClassEntry->szClassName) );
1343     return TRUE;
1344 }
1345 #endif