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