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