Fixed typo.
[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 GCL_HBRBACKGROUND:
800         case GCL_HCURSOR:
801         case GCL_HICON:
802         case GCL_HICONSM:
803             return GetClassWord32( hwnd, offset );
804     }
805     WARN(class, "Invalid offset %d\n", offset);
806     return 0;
807 }
808
809
810 /***********************************************************************
811  *           GetClassLong32W    (USER32.216)
812  */
813 LONG WINAPI GetClassLong32W( HWND32 hwnd, INT32 offset )
814 {
815     WND * wndPtr;
816
817     TRACE(class,"%x %x\n",hwnd, offset);
818
819     switch(offset)
820     {
821     case GCL_WNDPROC:
822         if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
823         return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
824     case GCL_MENUNAME:
825         if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
826         return (LONG)CLASS_GetMenuNameW( wndPtr->class );
827     default:
828         return GetClassLong32A( hwnd, offset );
829     }
830 }
831
832
833 /***********************************************************************
834  *           SetClassWord16    (USER.130)
835  */
836 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
837 {
838     return SetClassWord32( hwnd, offset, newval );
839 }
840
841
842 /***********************************************************************
843  *           SetClassWord32    (USER32.469)
844  */
845 WORD WINAPI SetClassWord32( HWND32 hwnd, INT32 offset, WORD newval )
846 {
847     WND * wndPtr;
848     WORD retval = 0;
849     void *ptr;
850     
851     TRACE(class,"%x %x %x\n",hwnd, offset, newval);
852     
853     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
854     if (offset >= 0)
855     {
856         if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
857             ptr = ((char *)wndPtr->class->wExtra) + offset;
858         else
859         {
860             WARN( class, "Invalid offset %d\n", offset );
861             return 0;
862         }
863     }
864     else switch(offset)
865     {
866         case GCW_STYLE:
867         case GCW_CBWNDEXTRA:
868         case GCW_CBCLSEXTRA:
869         case GCW_HMODULE:
870             return (WORD)SetClassLong32A( hwnd, offset, (LONG)newval );
871         case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
872         case GCW_HCURSOR:       ptr = &wndPtr->class->hCursor; break;
873         case GCW_HICON:         ptr = &wndPtr->class->hIcon; break;
874         case GCW_HICONSM:       ptr = &wndPtr->class->hIconSm; break;
875         case GCW_ATOM:          ptr = &wndPtr->class->atomName; break;
876         default:
877             WARN( class, "Invalid offset %d\n", offset);
878             return 0;
879     }
880     retval = GET_WORD(ptr);
881     PUT_WORD( ptr, newval );
882     
883     /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
884     need to be updated as well.  Problem is that we can't tell whether the atom is 
885     using wide or narrow characters.  For now, we'll just NULL out the className 
886     fields, and emit a FIXME. */
887     if (offset == GCW_ATOM)
888     {
889         CLASS_SetClassNameA( wndPtr->class, NULL );
890         FIXME(class,"GCW_ATOM changed for a class.  Not updating className, so GetClassInfoEx may not return correct className!\n");
891     }
892     return retval;
893 }
894
895
896 /***********************************************************************
897  *           SetClassLong16    (USER.132)
898  */
899 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
900 {
901     WND *wndPtr;
902     LONG retval;
903
904     TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
905
906     switch(offset)
907     {
908     case GCL_WNDPROC:
909         if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
910         retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
911         WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
912                          WIN_PROC_16, WIN_PROC_CLASS );
913         return retval;
914     case GCL_MENUNAME:
915         return SetClassLong32A( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
916     default:
917         return SetClassLong32A( hwnd, offset, newval );
918     }
919 }
920
921
922 /***********************************************************************
923  *           SetClassLong32A    (USER32.467)
924  */
925 LONG WINAPI SetClassLong32A( HWND32 hwnd, INT32 offset, LONG newval )
926 {
927     WND * wndPtr;
928     LONG retval = 0;
929     void *ptr;
930     
931     TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
932         
933     if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
934     if (offset >= 0)
935     {
936         if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
937             ptr = ((char *)wndPtr->class->wExtra) + offset;
938         else
939         {
940             WARN( class, "Invalid offset %d\n", offset );
941             return 0;
942         }
943     }
944     else switch(offset)
945     {
946         case GCL_MENUNAME:
947             CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
948             return 0;  /* Old value is now meaningless anyway */
949         case GCL_WNDPROC:
950             retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
951                                             WIN_PROC_32A );
952             WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
953                              WIN_PROC_32A, WIN_PROC_CLASS );
954             return retval;
955         case GCL_HBRBACKGROUND:
956         case GCL_HCURSOR:
957         case GCL_HICON:
958         case GCL_HICONSM:
959             return SetClassWord32( hwnd, offset, (WORD)newval );
960         case GCL_STYLE:      ptr = &wndPtr->class->style; break;
961         case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
962         case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
963         case GCL_HMODULE:    ptr = &wndPtr->class->hInstance; break;
964         default:
965             WARN( class, "Invalid offset %d\n", offset );
966             return 0;
967     }
968     retval = GET_DWORD(ptr);
969     PUT_DWORD( ptr, newval );
970     return retval;
971 }
972
973
974 /***********************************************************************
975  *           SetClassLong32W    (USER32.468)
976  */
977 LONG WINAPI SetClassLong32W( HWND32 hwnd, INT32 offset, LONG newval )
978 {
979     WND *wndPtr;
980     LONG retval;
981
982     TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
983     
984     switch(offset)
985     {
986     case GCL_WNDPROC:
987         if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
988         retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
989         WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
990                          WIN_PROC_32W, WIN_PROC_CLASS );
991         return retval;
992     case GCL_MENUNAME:
993         if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
994         CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
995         return 0;  /* Old value is now meaningless anyway */
996     default:
997         return SetClassLong32A( hwnd, offset, newval );
998     }
999 }
1000
1001
1002 /***********************************************************************
1003  *           GetClassName16      (USER.58)
1004  */
1005 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1006 {
1007     WND *wndPtr;
1008     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1009     return GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1010 }
1011
1012
1013 /***********************************************************************
1014  *           GetClassName32A      (USER32.217)
1015  */
1016 INT32 WINAPI GetClassName32A( HWND32 hwnd, LPSTR buffer, INT32 count )
1017 {   INT32 ret;
1018     WND *wndPtr;
1019             
1020     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1021     ret = GlobalGetAtomName32A( wndPtr->class->atomName, buffer, count );
1022
1023     TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1024     return ret;
1025 }
1026
1027
1028 /***********************************************************************
1029  *           GetClassName32W      (USER32.218)
1030  */
1031 INT32 WINAPI GetClassName32W( HWND32 hwnd, LPWSTR buffer, INT32 count )
1032 {   INT32 ret;
1033     WND *wndPtr;
1034
1035     if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1036     ret = GlobalGetAtomName32W( wndPtr->class->atomName, buffer, count );
1037
1038     TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1039     
1040     return ret;
1041 }
1042
1043
1044 /***********************************************************************
1045  *           GetClassInfo16      (USER.404)
1046  */
1047 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1048                               WNDCLASS16 *wc )
1049 {
1050     ATOM atom;
1051     CLASS *classPtr;
1052
1053     TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1054     
1055     hInstance = GetExePtr( hInstance );
1056     if (!(atom = GlobalFindAtom16( name )) ||
1057         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1058         return FALSE;
1059     if ((hInstance != classPtr->hInstance) &&
1060         !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1061         return FALSE;
1062     wc->style         = (UINT16)classPtr->style;
1063     wc->lpfnWndProc   = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1064     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1065     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1066     wc->hInstance     = (HINSTANCE16)classPtr->hInstance;
1067     wc->hIcon         = classPtr->hIcon;
1068     wc->hCursor       = classPtr->hCursor;
1069     wc->hbrBackground = classPtr->hbrBackground;
1070     wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1071     wc->lpszMenuName  = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1072     if (HIWORD(wc->lpszMenuName))  /* Make it a SEGPTR */
1073         wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1074     return TRUE;
1075 }
1076
1077
1078 /***********************************************************************
1079  *           GetClassInfo32A      (USER32.211)
1080  */
1081 BOOL32 WINAPI GetClassInfo32A( HINSTANCE32 hInstance, LPCSTR name,
1082                                WNDCLASS32A *wc )
1083 {
1084     ATOM atom;
1085     CLASS *classPtr;
1086
1087     TRACE(class,"%x %p %p\n",hInstance, name, wc);
1088
1089     /* workaround: if hInstance=NULL you expect to get the system classes
1090     but this classes (as example from comctl32.dll SysListView) won't be
1091     registred with hInstance=NULL in WINE because of the late loading
1092     of this dll. fixes file dialogs in WinWord95 (jsch)*/
1093
1094     if (!(atom=GlobalFindAtom32A(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1095         return FALSE;
1096
1097     if  (classPtr->hInstance && (hInstance != classPtr->hInstance))
1098     {
1099         if (hInstance) return FALSE;
1100         else    
1101             WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1102     }
1103
1104     wc->style         = classPtr->style;
1105     wc->lpfnWndProc   = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1106                                                     WIN_PROC_32A );
1107     wc->cbClsExtra    = classPtr->cbClsExtra;
1108     wc->cbWndExtra    = classPtr->cbWndExtra;
1109     wc->hInstance     = classPtr->hInstance;
1110     wc->hIcon         = (HICON32)classPtr->hIcon;
1111     wc->hCursor       = (HCURSOR32)classPtr->hCursor;
1112     wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1113     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1114     wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1115     return TRUE;
1116 }
1117
1118
1119 /***********************************************************************
1120  *           GetClassInfo32W      (USER32.214)
1121  */
1122 BOOL32 WINAPI GetClassInfo32W( HINSTANCE32 hInstance, LPCWSTR name,
1123                                WNDCLASS32W *wc )
1124 {
1125     ATOM atom;
1126     CLASS *classPtr;
1127
1128     TRACE(class,"%x %p %p\n",hInstance, name, wc);
1129
1130     if (!(atom = GlobalFindAtom32W( name )) ||
1131         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1132         (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1133         return FALSE;
1134
1135     wc->style         = classPtr->style;
1136     wc->lpfnWndProc   = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1137                                                     WIN_PROC_32W );
1138     wc->cbClsExtra    = classPtr->cbClsExtra;
1139     wc->cbWndExtra    = classPtr->cbWndExtra;
1140     wc->hInstance     = classPtr->hInstance;
1141     wc->hIcon         = (HICON32)classPtr->hIcon;
1142     wc->hCursor       = (HCURSOR32)classPtr->hCursor;
1143     wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1144     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1145     wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1146     return TRUE;
1147 }
1148
1149
1150 /***********************************************************************
1151  *           GetClassInfoEx16      (USER.398)
1152  *
1153  * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1154  * same in Win16 as in Win32. --AJ
1155  */
1156 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1157                                 WNDCLASSEX16 *wc )
1158 {
1159     ATOM atom;
1160     CLASS *classPtr;
1161
1162     TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1163     
1164     hInstance = GetExePtr( hInstance );
1165     if (!(atom = GlobalFindAtom16( name )) ||
1166         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1167         (hInstance != classPtr->hInstance)) return FALSE;
1168     wc->style         = classPtr->style;
1169     wc->lpfnWndProc   = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1170     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1171     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1172     wc->hInstance     = (HINSTANCE16)classPtr->hInstance;
1173     wc->hIcon         = classPtr->hIcon;
1174     wc->hIconSm       = classPtr->hIconSm;
1175     wc->hCursor       = classPtr->hCursor;
1176     wc->hbrBackground = classPtr->hbrBackground;
1177     wc->lpszClassName = (SEGPTR)0;
1178     wc->lpszMenuName  = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1179     if (HIWORD(wc->lpszMenuName))  /* Make it a SEGPTR */
1180         wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1181     wc->lpszClassName  = (SEGPTR)CLASS_GetClassNameA( classPtr );
1182     if (HIWORD(wc->lpszClassName))  /* Make it a SEGPTR */
1183         wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1184     return TRUE;
1185 }
1186
1187
1188 /***********************************************************************
1189  *           GetClassInfoEx32A      (USER32.212)
1190  */
1191 BOOL32 WINAPI GetClassInfoEx32A( HINSTANCE32 hInstance, LPCSTR name,
1192                                  WNDCLASSEX32A *wc )
1193 {
1194     ATOM atom;
1195     CLASS *classPtr;
1196
1197     TRACE(class,"%x %p %p\n",hInstance, name, wc);
1198     
1199     if (!(atom = GlobalFindAtom32A( name )) ||
1200         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) 
1201         /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1202     wc->style         = classPtr->style;
1203     wc->lpfnWndProc   = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1204                                                     WIN_PROC_32A );
1205     wc->cbClsExtra    = classPtr->cbClsExtra;
1206     wc->cbWndExtra    = classPtr->cbWndExtra;
1207     wc->hInstance     = classPtr->hInstance;
1208     wc->hIcon         = (HICON32)classPtr->hIcon;
1209     wc->hIconSm       = (HICON32)classPtr->hIconSm;
1210     wc->hCursor       = (HCURSOR32)classPtr->hCursor;
1211     wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1212     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1213     wc->lpszClassName  = CLASS_GetClassNameA( classPtr );
1214     return TRUE;
1215 }
1216
1217
1218 /***********************************************************************
1219  *           GetClassInfoEx32W      (USER32.213)
1220  */
1221 BOOL32 WINAPI GetClassInfoEx32W( HINSTANCE32 hInstance, LPCWSTR name,
1222                                  WNDCLASSEX32W *wc )
1223 {
1224     ATOM atom;
1225     CLASS *classPtr;
1226
1227     TRACE(class,"%x %p %p\n",hInstance, name, wc);
1228     
1229     if (!(atom = GlobalFindAtom32W( name )) ||
1230         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1231         (hInstance != classPtr->hInstance)) return FALSE;
1232     wc->style         = classPtr->style;
1233     wc->lpfnWndProc   = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1234                                                     WIN_PROC_32W );
1235     wc->cbClsExtra    = classPtr->cbClsExtra;
1236     wc->cbWndExtra    = classPtr->cbWndExtra;
1237     wc->hInstance     = classPtr->hInstance;
1238     wc->hIcon         = (HICON32)classPtr->hIcon;
1239     wc->hIconSm       = (HICON32)classPtr->hIconSm;
1240     wc->hCursor       = (HCURSOR32)classPtr->hCursor;
1241     wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1242     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1243     wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1244     return TRUE;
1245 }
1246
1247
1248 /***********************************************************************
1249  *           ClassFirst      (TOOLHELP.69)
1250  */
1251 BOOL16 WINAPI ClassFirst( CLASSENTRY *pClassEntry )
1252 {
1253     TRACE(class,"%p\n",pClassEntry);
1254     pClassEntry->wNext = 1;
1255     return ClassNext( pClassEntry );
1256 }
1257
1258
1259 /***********************************************************************
1260  *           ClassNext      (TOOLHELP.70)
1261  */
1262 BOOL16 WINAPI ClassNext( CLASSENTRY *pClassEntry )
1263 {
1264     int i;
1265     CLASS *class = firstClass;
1266
1267     TRACE(class,"%p\n",pClassEntry);
1268    
1269     if (!pClassEntry->wNext) return FALSE;
1270     for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1271     if (!class)
1272     {
1273         pClassEntry->wNext = 0;
1274         return FALSE;
1275     }
1276     pClassEntry->hInst = class->hInstance;
1277     pClassEntry->wNext++;
1278     GlobalGetAtomName32A( class->atomName, pClassEntry->szClassName,
1279                           sizeof(pClassEntry->szClassName) );
1280     return TRUE;
1281 }