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