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