Made all 16<->32 HWND conversions use explicit functions instead of
[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 /***********************************************************************
702  *              GetClassWord (USER32.@)
703  */
704 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
705 {
706     WND * wndPtr;
707     WORD retvalue = 0;
708     
709     TRACE("%x %x\n",hwnd, offset);
710     
711     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
712     if (offset >= 0)
713     {
714         if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
715         {
716             retvalue = GET_WORD((char *)(wndPtr->class + 1) + offset);
717             goto END;
718         }
719     }
720     else switch(offset)
721     {
722         case GCW_ATOM:
723             retvalue = wndPtr->class->atomName;
724             goto END;
725         case GCL_HBRBACKGROUND:
726         case GCL_HCURSOR:
727         case GCL_HICON:
728         case GCL_HICONSM:
729         case GCL_STYLE:
730         case GCL_CBWNDEXTRA:
731         case GCL_CBCLSEXTRA:
732         case GCL_HMODULE:
733             retvalue = (WORD)GetClassLongA( hwnd, offset );
734             goto END;
735     }
736
737     WARN("Invalid offset %d\n", offset);
738  END:
739     WIN_ReleaseWndPtr(wndPtr);
740     return retvalue;
741 }
742
743
744 /***********************************************************************
745  *              GetClassLong (USER.131)
746  */
747 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
748 {
749     WND *wndPtr;
750     LONG ret;
751
752     TRACE("%x %x\n",hwnd, offset);
753
754     switch( offset )
755     {
756     case GCL_WNDPROC:
757         if (!(wndPtr = WIN_FindWndPtr16( hwnd ))) return 0;
758         ret = (LONG)CLASS_GetProc( wndPtr->class, WIN_PROC_16 );
759         WIN_ReleaseWndPtr(wndPtr);
760         return ret;
761     case GCL_MENUNAME:
762         ret = GetClassLongA( WIN_Handle32(hwnd), offset );
763         return (LONG)SEGPTR_GET( (void *)ret );
764     default:
765         return GetClassLongA( WIN_Handle32(hwnd), offset );
766     }
767 }
768
769
770 /***********************************************************************
771  *              GetClassLongA (USER32.@)
772  */
773 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
774 {
775     WND * wndPtr;
776     LONG retvalue;
777     
778     TRACE("%x %x\n",hwnd, offset);
779     
780     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
781     if (offset >= 0)
782     {
783         if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
784         {
785             retvalue = GET_DWORD((char *)(wndPtr->class + 1) + offset);
786             goto END;
787         }
788     }
789
790     switch(offset)
791     {
792         case GCL_HBRBACKGROUND:
793             retvalue = (LONG)wndPtr->class->hbrBackground;
794             goto END;
795         case GCL_HCURSOR:
796             retvalue = (LONG)wndPtr->class->hCursor;
797             goto END;
798         case GCL_HICON:
799             retvalue = (LONG)wndPtr->class->hIcon;
800             goto END;
801         case GCL_HICONSM:
802             retvalue = (LONG)wndPtr->class->hIconSm;
803             goto END;
804         case GCL_STYLE:
805             retvalue = (LONG)wndPtr->class->style;
806             goto END;
807         case GCL_CBWNDEXTRA:
808             retvalue = (LONG)wndPtr->class->cbWndExtra;
809             goto END;
810         case GCL_CBCLSEXTRA:
811             retvalue = (LONG)wndPtr->class->cbClsExtra;
812             goto END;
813         case GCL_HMODULE:
814             retvalue = (LONG)wndPtr->class->hInstance;
815             goto END;
816         case GCL_WNDPROC:
817             retvalue = (LONG)CLASS_GetProc( wndPtr->class, WIN_PROC_32A );
818             goto END;
819         case GCL_MENUNAME:
820             retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
821             goto END;
822         case GCW_ATOM:
823             retvalue = GetClassWord( hwnd, offset );
824             goto END;
825     }
826     WARN("Invalid offset %d\n", offset);
827     retvalue = 0;
828 END:
829     WIN_ReleaseWndPtr(wndPtr);
830     return retvalue;
831 }
832
833
834 /***********************************************************************
835  *              GetClassLongW (USER32.@)
836  */
837 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
838 {
839     WND * wndPtr;
840     LONG retvalue;
841
842     TRACE("%x %x\n",hwnd, offset);
843
844     switch(offset)
845     {
846     case GCL_WNDPROC:
847         if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
848         retvalue = (LONG)CLASS_GetProc( wndPtr->class, WIN_PROC_32W );
849         WIN_ReleaseWndPtr(wndPtr);
850         return retvalue;
851     case GCL_MENUNAME:
852         if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
853         retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
854         WIN_ReleaseWndPtr(wndPtr);
855         return retvalue;
856     default:
857         return GetClassLongA( hwnd, offset );
858     }
859 }
860
861
862 /***********************************************************************
863  *              SetClassWord (USER32.@)
864  */
865 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
866 {
867     WND * wndPtr;
868     WORD retval = 0;
869     void *ptr;
870     
871     TRACE("%x %x %x\n",hwnd, offset, newval);
872     
873     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
874     if (offset >= 0)
875     {
876         if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
877             ptr = (char *)(wndPtr->class + 1) + offset;
878         else
879         {
880             WARN("Invalid offset %d\n", offset );
881             WIN_ReleaseWndPtr(wndPtr);
882             return 0;
883         }
884     }
885     else switch(offset)
886     {
887         case GCL_HBRBACKGROUND:
888         case GCL_HCURSOR:
889         case GCL_HICON:
890         case GCL_HICONSM:
891         case GCL_STYLE:
892         case GCL_CBWNDEXTRA:
893         case GCL_CBCLSEXTRA:
894         case GCL_HMODULE:
895             WIN_ReleaseWndPtr(wndPtr);
896             return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
897         case GCW_ATOM:
898             ptr = &wndPtr->class->atomName;
899             break;
900         default:
901             WARN("Invalid offset %d\n", offset);
902             WIN_ReleaseWndPtr(wndPtr);
903             return 0;
904     }
905     retval = GET_WORD(ptr);
906     PUT_WORD( ptr, newval );
907     WIN_ReleaseWndPtr(wndPtr);
908     return retval;
909 }
910
911
912 /***********************************************************************
913  *              SetClassLong (USER.132)
914  */
915 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
916 {
917     WND *wndPtr;
918     LONG retval;
919
920     TRACE("%x %x %lx\n",hwnd, offset, newval);
921
922     switch(offset)
923     {
924     case GCL_WNDPROC:
925         if (!(wndPtr = WIN_FindWndPtr16(hwnd))) return 0;
926         retval = (LONG)CLASS_SetProc( wndPtr->class, (WNDPROC)newval, WIN_PROC_16 );
927         WIN_ReleaseWndPtr(wndPtr);
928         return retval;
929     case GCL_MENUNAME:
930         newval = (LONG)MapSL( newval );
931         /* fall through */
932     default:
933         return SetClassLongA( WIN_Handle32(hwnd), offset, newval );
934     }
935 }
936
937
938 /***********************************************************************
939  *              SetClassLongA (USER32.@)
940  */
941 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
942 {
943     WND * wndPtr;
944     LONG retval = 0;
945     void *ptr;
946     
947     TRACE("%x %x %lx\n",hwnd, offset, newval);
948         
949     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
950     if (offset >= 0)
951     {
952         if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
953             ptr = (char *)(wndPtr->class + 1) + offset;
954         else
955         {
956             WARN("Invalid offset %d\n", offset );
957             retval = 0;
958             goto END;
959         }
960     }
961     else switch(offset)
962     {
963         case GCL_MENUNAME:
964             CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
965             retval = 0;  /* Old value is now meaningless anyway */
966             goto END;
967         case GCL_WNDPROC:
968             retval = (LONG)CLASS_SetProc( wndPtr->class, (WNDPROC)newval, WIN_PROC_32A );
969             goto END;
970         case GCL_HBRBACKGROUND:
971             ptr = &wndPtr->class->hbrBackground;
972             break;
973         case GCL_HCURSOR:
974             ptr = &wndPtr->class->hCursor;
975             break;
976         case GCL_HICON:
977             ptr = &wndPtr->class->hIcon;
978             break;
979         case GCL_HICONSM:
980             ptr = &wndPtr->class->hIconSm;
981             break;
982         case GCL_STYLE:
983             ptr = &wndPtr->class->style;
984             break;
985         case GCL_CBWNDEXTRA:
986             ptr = &wndPtr->class->cbWndExtra;
987             break;
988         case GCL_CBCLSEXTRA:
989             ptr = &wndPtr->class->cbClsExtra;
990             break;
991         case GCL_HMODULE:
992             ptr = &wndPtr->class->hInstance;
993             break;
994         case GCW_ATOM:
995             WIN_ReleaseWndPtr(wndPtr);
996             return SetClassWord( hwnd, offset, newval );
997         default:
998             WARN("Invalid offset %d\n", offset );
999             retval = 0;
1000             goto END;
1001     }
1002     retval = GET_DWORD(ptr);
1003     PUT_DWORD( ptr, newval );
1004 END:
1005     WIN_ReleaseWndPtr(wndPtr);
1006     return retval;
1007 }
1008
1009
1010 /***********************************************************************
1011  *              SetClassLongW (USER32.@)
1012  */
1013 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
1014 {
1015     WND *wndPtr;
1016     LONG retval;
1017
1018     TRACE("%x %x %lx\n",hwnd, offset, newval);
1019     
1020     switch(offset)
1021     {
1022     case GCL_WNDPROC:
1023         if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1024         retval = (LONG)CLASS_SetProc( wndPtr->class, (WNDPROC)newval, WIN_PROC_32W );
1025         WIN_ReleaseWndPtr(wndPtr);
1026         return retval;
1027     case GCL_MENUNAME:
1028         if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1029         CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
1030         WIN_ReleaseWndPtr(wndPtr);
1031         return 0;  /* Old value is now meaningless anyway */
1032     default:
1033         return SetClassLongA( hwnd, offset, newval );
1034     }
1035 }
1036
1037
1038 /***********************************************************************
1039  *              GetClassNameA (USER32.@)
1040  */
1041 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1042 {   INT ret;
1043     WND *wndPtr;
1044             
1045     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1046     ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
1047
1048     WIN_ReleaseWndPtr(wndPtr);
1049     TRACE("%x %s %x\n",hwnd, buffer, count);
1050     return ret;
1051 }
1052
1053
1054 /***********************************************************************
1055  *              GetClassNameW (USER32.@)
1056  */
1057 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1058 {   INT ret;
1059     WND *wndPtr;
1060
1061     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1062     ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
1063     WIN_ReleaseWndPtr(wndPtr);
1064     TRACE("%x %s %x\n",hwnd, debugstr_w(buffer), count);
1065     
1066     return ret;
1067 }
1068
1069
1070 /***********************************************************************
1071  *              GetClassInfo (USER.404)
1072  */
1073 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name, WNDCLASS16 *wc )
1074 {
1075     ATOM atom;
1076     CLASS *classPtr;
1077
1078     TRACE("%x %s %p\n",hInstance, debugres_a(MapSL(name)), wc);
1079
1080     hInstance = GetExePtr( hInstance );
1081     if (!(atom = GlobalFindAtomA( MapSL(name) )) ||
1082         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1083         return FALSE;
1084     if ((hInstance != classPtr->hInstance) &&
1085         !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1086         return FALSE;
1087     wc->style         = (UINT16)classPtr->style;
1088     wc->lpfnWndProc   = CLASS_GetProc( classPtr, WIN_PROC_16 );
1089     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1090     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1091     wc->hInstance     = (HINSTANCE16)classPtr->hInstance;
1092     wc->hIcon         = classPtr->hIcon;
1093     wc->hCursor       = classPtr->hCursor;
1094     wc->hbrBackground = classPtr->hbrBackground;
1095     wc->lpszClassName = name;
1096     wc->lpszMenuName  = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1097     if (HIWORD(wc->lpszMenuName))  /* Make it a SEGPTR */
1098         wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1099     return TRUE;
1100 }
1101
1102
1103 /***********************************************************************
1104  *              GetClassInfoA (USER32.@)
1105  */
1106 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1107                                WNDCLASSA *wc )
1108 {
1109     ATOM atom;
1110     CLASS *classPtr;
1111
1112     TRACE("%x %p %p\n",hInstance, name, wc);
1113
1114     /* workaround: if hInstance=NULL you expect to get the system classes
1115     but this classes (as example from comctl32.dll SysListView) won't be
1116     registered with hInstance=NULL in WINE because of the late loading
1117     of this dll. fixes file dialogs in WinWord95 (jsch)*/
1118
1119     if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1120         return FALSE;
1121
1122     if (!(classPtr->style & CS_GLOBALCLASS) &&
1123         classPtr->hInstance &&
1124         (hInstance != classPtr->hInstance))
1125     {
1126         if (hInstance) return FALSE;
1127         WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1128     }
1129
1130     wc->style         = classPtr->style;
1131     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
1132     wc->cbClsExtra    = classPtr->cbClsExtra;
1133     wc->cbWndExtra    = classPtr->cbWndExtra;
1134     wc->hInstance     = hInstance;
1135     wc->hIcon         = (HICON)classPtr->hIcon;
1136     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1137     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1138     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1139     wc->lpszClassName = name;
1140     return TRUE;
1141 }
1142
1143
1144 /***********************************************************************
1145  *              GetClassInfoW (USER32.@)
1146  */
1147 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1148                                WNDCLASSW *wc )
1149 {
1150     ATOM atom;
1151     CLASS *classPtr;
1152
1153     TRACE("%x %p %p\n",hInstance, name, wc);
1154
1155     if (        !(atom=GlobalFindAtomW(name)) ||
1156                 !(classPtr=CLASS_FindClassByAtom(atom,hInstance))
1157     )
1158         return FALSE;
1159
1160     if (!(classPtr->style & CS_GLOBALCLASS) &&
1161         classPtr->hInstance &&
1162         (hInstance != classPtr->hInstance))
1163     {
1164         if (hInstance) return FALSE;
1165         WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name));
1166     }
1167     wc->style         = classPtr->style;
1168     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
1169     wc->cbClsExtra    = classPtr->cbClsExtra;
1170     wc->cbWndExtra    = classPtr->cbWndExtra;
1171     wc->hInstance     = hInstance;
1172     wc->hIcon         = (HICON)classPtr->hIcon;
1173     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1174     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1175     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1176     wc->lpszClassName = name;
1177     return TRUE;
1178 }
1179
1180
1181 /***********************************************************************
1182  *              GetClassInfoEx (USER.398)
1183  *
1184  * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1185  * same in Win16 as in Win32. --AJ
1186  */
1187 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name, WNDCLASSEX16 *wc )
1188 {
1189     ATOM atom;
1190     CLASS *classPtr;
1191
1192     TRACE("%x %s %p\n",hInstance,debugres_a( MapSL(name) ), wc);
1193
1194     hInstance = GetExePtr( hInstance );
1195     if (!(atom = GlobalFindAtomA( MapSL(name) )) ||
1196         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1197         (hInstance != classPtr->hInstance)) return FALSE;
1198     wc->style         = classPtr->style;
1199     wc->lpfnWndProc   = CLASS_GetProc( classPtr, WIN_PROC_16 );
1200     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1201     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1202     wc->hInstance     = (HINSTANCE16)classPtr->hInstance;
1203     wc->hIcon         = classPtr->hIcon;
1204     wc->hIconSm       = classPtr->hIconSm;
1205     wc->hCursor       = classPtr->hCursor;
1206     wc->hbrBackground = classPtr->hbrBackground;
1207     wc->lpszClassName = (SEGPTR)0;
1208     wc->lpszMenuName  = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1209     if (HIWORD(wc->lpszMenuName))  /* Make it a SEGPTR */
1210         wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1211     wc->lpszClassName  = name;
1212
1213     /* We must return the atom of the class here instead of just TRUE. */
1214     return atom;
1215 }
1216
1217
1218 /***********************************************************************
1219  *              GetClassInfoExA (USER32.@)
1220  */
1221 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1222                                  WNDCLASSEXA *wc )
1223 {
1224     ATOM atom;
1225     CLASS *classPtr;
1226
1227     TRACE("%x %p %p\n",hInstance, name, wc);
1228     
1229     if (!(atom = GlobalFindAtomA( name )) ||
1230         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) 
1231         /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1232     wc->style         = classPtr->style;
1233     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
1234     wc->cbClsExtra    = classPtr->cbClsExtra;
1235     wc->cbWndExtra    = classPtr->cbWndExtra;
1236     wc->hInstance     = classPtr->hInstance;
1237     wc->hIcon         = (HICON)classPtr->hIcon;
1238     wc->hIconSm       = (HICON)classPtr->hIconSm;
1239     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1240     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1241     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1242     wc->lpszClassName = name;
1243
1244     /* We must return the atom of the class here instead of just TRUE. */
1245     return atom;
1246 }
1247
1248
1249 /***********************************************************************
1250  *              GetClassInfoExW (USER32.@)
1251  */
1252 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1253                                  WNDCLASSEXW *wc )
1254 {
1255     ATOM atom;
1256     CLASS *classPtr;
1257
1258     TRACE("%x %p %p\n",hInstance, name, wc);
1259     
1260     if (!(atom = GlobalFindAtomW( name )) ||
1261         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1262         (hInstance != classPtr->hInstance)) return FALSE;
1263     wc->style         = classPtr->style;
1264     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
1265     wc->cbClsExtra    = classPtr->cbClsExtra;
1266     wc->cbWndExtra    = classPtr->cbWndExtra;
1267     wc->hInstance     = classPtr->hInstance;
1268     wc->hIcon         = (HICON)classPtr->hIcon;
1269     wc->hIconSm       = (HICON)classPtr->hIconSm;
1270     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1271     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1272     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1273     wc->lpszClassName = name;
1274
1275     /* We must return the atom of the class here instead of just TRUE. */
1276     return atom;
1277 }
1278
1279
1280 #if 0  /* toolhelp is in kernel, so this cannot work */
1281
1282 /***********************************************************************
1283  *              ClassFirst (TOOLHELP.69)
1284  */
1285 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1286 {
1287     TRACE("%p\n",pClassEntry);
1288     pClassEntry->wNext = 1;
1289     return ClassNext16( pClassEntry );
1290 }
1291
1292
1293 /***********************************************************************
1294  *              ClassNext (TOOLHELP.70)
1295  */
1296 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1297 {
1298     int i;
1299     CLASS *class = firstClass;
1300
1301     TRACE("%p\n",pClassEntry);
1302    
1303     if (!pClassEntry->wNext) return FALSE;
1304     for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1305     if (!class)
1306     {
1307         pClassEntry->wNext = 0;
1308         return FALSE;
1309     }
1310     pClassEntry->hInst = class->hInstance;
1311     pClassEntry->wNext++;
1312     GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1313                           sizeof(pClassEntry->szClassName) );
1314     return TRUE;
1315 }
1316 #endif