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