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