Made user compile with -DSTRICT.
[wine] / windows / class.c
1 /*
2  * Window classes functions
3  *
4  * Copyright 1993, 1996 Alexandre Julliard
5  *           1998 Juergen Schmied (jsch)
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  *
21  * FIXME: In win32 all classes are local. They are registered at
22  *        program start. Processes CANNOT share classes. (Source: some
23  *        win31->NT migration book)
24  *
25  * FIXME: There seems to be a general problem with hInstance in WINE
26  *   classes are getting registered with wrong hInstance.
27  */
28
29 #include "config.h"
30 #include "wine/port.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34
35 #include "wine/winbase16.h"
36 #include "winerror.h"
37 #include "windef.h"
38 #include "wingdi.h"
39 #include "wine/winuser16.h"
40 #include "wownt32.h"
41 #include "wine/unicode.h"
42 #include "win.h"
43 #include "user.h"
44 #include "controls.h"
45 #include "dce.h"
46 #include "winproc.h"
47 #include "wine/debug.h"
48
49 WINE_DEFAULT_DEBUG_CHANNEL(class);
50
51 typedef struct tagCLASS
52 {
53     struct tagCLASS *next;          /* Next class */
54     struct tagCLASS *prev;          /* Prev class */
55     UINT             cWindows;      /* Count of existing windows */
56     UINT             style;         /* Class style */
57     HWINDOWPROC      winprocA;      /* Window procedure (ASCII) */
58     HWINDOWPROC      winprocW;      /* Window procedure (Unicode) */
59     INT              cbClsExtra;    /* Class extra bytes */
60     INT              cbWndExtra;    /* Window extra bytes */
61     LPWSTR           menuName;      /* Default menu name (Unicode followed by ASCII) */
62     SEGPTR           segMenuName;   /* Default menu name as SEGPTR */
63     struct tagDCE   *dce;           /* Class DCE (if CS_CLASSDC) */
64     HINSTANCE        hInstance;     /* Module that created the task */
65     HICON            hIcon;         /* Default icon */
66     HICON            hIconSm;       /* Default small icon */
67     HCURSOR          hCursor;       /* Default cursor */
68     HBRUSH           hbrBackground; /* Default background */
69     ATOM             atomName;      /* Name of the class */
70 } CLASS;
71
72 static CLASS *firstClass;
73
74 /***********************************************************************
75  *           get_class_ptr
76  */
77 static CLASS *get_class_ptr( HWND hwnd, BOOL write_access )
78 {
79     WND *ptr = WIN_GetPtr( hwnd );
80
81     if (ptr)
82     {
83         if (ptr != WND_OTHER_PROCESS) return ptr->class;
84         if (IsWindow( hwnd )) /* check other processes */
85         {
86             if (write_access)
87             {
88                 /* modifying classes in other processes is not allowed */
89                 SetLastError( ERROR_ACCESS_DENIED );
90                 return NULL;
91             }
92             FIXME( "reading from class of other process window %p\n", hwnd );
93             /* DbgBreakPoint(); */
94         }
95     }
96     SetLastError( ERROR_INVALID_WINDOW_HANDLE );
97     return NULL;
98 }
99
100
101 /***********************************************************************
102  *           release_class_ptr
103  */
104 inline static void release_class_ptr( CLASS *ptr )
105 {
106     USER_Unlock();
107 }
108
109
110 /***********************************************************************
111  *           CLASS_GetProc
112  *
113  * Get the class winproc for a given proc type
114  */
115 static WNDPROC16 CLASS_GetProc( CLASS *classPtr, WINDOWPROCTYPE type )
116 {
117     HWINDOWPROC proc = classPtr->winprocA;
118
119     if (classPtr->winprocW)
120     {
121         /* if we have a Unicode proc, use it if we have no ASCII proc
122          * or if we have both and Unicode was requested
123          */
124         if (!proc || type == WIN_PROC_32W) proc = classPtr->winprocW;
125     }
126     return WINPROC_GetProc( proc, type );
127 }
128
129
130 /***********************************************************************
131  *           CLASS_SetProc
132  *
133  * Set the class winproc for a given proc type.
134  * Returns the previous window proc.
135  */
136 static WNDPROC16 CLASS_SetProc( CLASS *classPtr, WNDPROC newproc, WINDOWPROCTYPE type )
137 {
138     HWINDOWPROC *proc = &classPtr->winprocA;
139     WNDPROC16 ret;
140
141     if (classPtr->winprocW)
142     {
143         /* if we have a Unicode proc, use it if we have no ASCII proc
144          * or if we have both and Unicode was requested
145          */
146         if (!*proc || type == WIN_PROC_32W) proc = &classPtr->winprocW;
147     }
148     ret = WINPROC_GetProc( *proc, type );
149     WINPROC_SetProc( proc, (HWINDOWPROC)newproc, type, WIN_PROC_CLASS );
150     /* now free the one that we didn't set */
151     if (classPtr->winprocA && classPtr->winprocW)
152     {
153         if (proc == &classPtr->winprocA)
154         {
155             WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS );
156             classPtr->winprocW = 0;
157         }
158         else
159         {
160             WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS );
161             classPtr->winprocA = 0;
162         }
163     }
164     return ret;
165 }
166
167
168 /***********************************************************************
169  *           CLASS_GetMenuNameA
170  *
171  * Get the menu name as a ASCII string.
172  */
173 inline static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
174 {
175     if (!HIWORD(classPtr->menuName)) return (LPSTR)classPtr->menuName;
176     return (LPSTR)(classPtr->menuName + strlenW(classPtr->menuName) + 1);
177 }
178
179
180 /***********************************************************************
181  *           CLASS_GetMenuName16
182  *
183  * Get the menu name as a SEGPTR.
184  */
185 inline static SEGPTR CLASS_GetMenuName16( CLASS *classPtr )
186 {
187     if (!HIWORD(classPtr->menuName)) return (SEGPTR)classPtr->menuName;
188     if (!classPtr->segMenuName)
189         classPtr->segMenuName = MapLS( CLASS_GetMenuNameA(classPtr) );
190     return classPtr->segMenuName;
191 }
192
193
194 /***********************************************************************
195  *           CLASS_GetMenuNameW
196  *
197  * Get the menu name as a Unicode string.
198  */
199 inline static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
200 {
201     return classPtr->menuName;
202 }
203
204
205 /***********************************************************************
206  *           CLASS_SetMenuNameA
207  *
208  * Set the menu name in a class structure by copying the string.
209  */
210 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
211 {
212     UnMapLS( classPtr->segMenuName );
213     classPtr->segMenuName = 0;
214     if (HIWORD(classPtr->menuName)) HeapFree( GetProcessHeap(), 0, classPtr->menuName );
215     if (HIWORD(name))
216     {
217         DWORD lenA = strlen(name) + 1;
218         DWORD lenW = MultiByteToWideChar( CP_ACP, 0, name, lenA, NULL, 0 );
219         classPtr->menuName = HeapAlloc( GetProcessHeap(), 0, lenA + lenW*sizeof(WCHAR) );
220         MultiByteToWideChar( CP_ACP, 0, name, lenA, classPtr->menuName, lenW );
221         memcpy( classPtr->menuName + lenW, name, lenA );
222     }
223     else classPtr->menuName = (LPWSTR)name;
224 }
225
226
227 /***********************************************************************
228  *           CLASS_SetMenuNameW
229  *
230  * Set the menu name in a class structure by copying the string.
231  */
232 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
233 {
234     UnMapLS( classPtr->segMenuName );
235     classPtr->segMenuName = 0;
236     if (HIWORD(classPtr->menuName)) HeapFree( GetProcessHeap(), 0, classPtr->menuName );
237     if (HIWORD(name))
238     {
239         DWORD lenW = strlenW(name) + 1;
240         DWORD lenA = WideCharToMultiByte( CP_ACP, 0, name, lenW, NULL, 0, NULL, NULL );
241         classPtr->menuName = HeapAlloc( GetProcessHeap(), 0, lenA + lenW*sizeof(WCHAR) );
242         memcpy( classPtr->menuName, name, lenW*sizeof(WCHAR) );
243         WideCharToMultiByte( CP_ACP, 0, name, lenW,
244                              (char *)(classPtr->menuName + lenW), lenA, NULL, NULL );
245     }
246     else classPtr->menuName = (LPWSTR)name;
247 }
248
249
250 /***********************************************************************
251  *           CLASS_FreeClass
252  *
253  * Free a class structure.
254  */
255 static BOOL CLASS_FreeClass( CLASS *classPtr )
256 {
257     TRACE("%p\n", classPtr);
258
259     /* Check if we can remove this class */
260
261     if (classPtr->cWindows > 0)
262     {
263         SetLastError( ERROR_CLASS_HAS_WINDOWS );
264         return FALSE;
265     }
266
267     /* Remove the class from the linked list */
268
269     if (classPtr->next) classPtr->next->prev = classPtr->prev;
270     if (classPtr->prev) classPtr->prev->next = classPtr->next;
271     else firstClass = classPtr->next;
272
273     /* Delete the class */
274
275     if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
276     if (classPtr->hbrBackground > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1))
277         DeleteObject( classPtr->hbrBackground );
278     GlobalDeleteAtom( classPtr->atomName );
279     WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS );
280     WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS );
281     UnMapLS( classPtr->segMenuName );
282     HeapFree( GetProcessHeap(), 0, classPtr->menuName );
283     HeapFree( GetProcessHeap(), 0, classPtr );
284     return TRUE;
285 }
286
287
288 /***********************************************************************
289  *           CLASS_FreeModuleClasses
290  */
291 void CLASS_FreeModuleClasses( HMODULE16 hModule )
292 {
293     CLASS *ptr, *next;
294
295     TRACE("0x%08x\n", hModule);
296
297     USER_Lock();
298     for (ptr = firstClass; ptr; ptr = next)
299     {
300         next = ptr->next;
301         if (ptr->hInstance == HINSTANCE_32(hModule)) CLASS_FreeClass( ptr );
302     }
303     USER_Unlock();
304 }
305
306
307 /***********************************************************************
308  *           CLASS_FindClassByAtom
309  *
310  * Return a pointer to the class.
311  * hinstance has been normalized by the caller.
312  *
313  * NOTES
314  *  980805 a local class will be found now if registred with hInst=0
315  *  and looed up with a hInst!=0. msmoney does it (jsch)
316  *
317  *  Local class registered with a USER instance handle are found as if
318  *  they were global classes.
319  */
320 static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
321 {
322     CLASS * class, *tclass = 0, *user_class = 0;
323     HINSTANCE16 hUser = GetModuleHandle16("USER");
324
325     TRACE("0x%08x %p\n", atom, hinstance);
326
327     /* First search task-specific classes */
328
329     for (class = firstClass; (class); class = class->next)
330     {
331         if (class->style & CS_GLOBALCLASS) continue;
332         if (class->atomName == atom)
333         {
334             if (hinstance==class->hInstance || hinstance == (HINSTANCE)0xffff)
335             {
336                 TRACE("-- found local %p\n", class);
337                 return class;
338             }
339             if (class->hInstance == 0) tclass = class;
340             else if(class->hInstance == HINSTANCE_32(hUser))
341             {
342                 user_class = class;
343             }
344         }
345     }
346
347     /* Then search global classes */
348
349     for (class = firstClass; (class); class = class->next)
350     {
351         if (!(class->style & CS_GLOBALCLASS)) continue;
352         if (class->atomName == atom)
353         {
354             TRACE("-- found global %p\n", class);
355             return class;
356         }
357     }
358
359     /* Check if there was a local class registered with USER */
360     if( user_class )
361     {
362         TRACE("--found local USER class %p\n", user_class);
363         return user_class;
364     }
365
366     /* Then check if there was a local class with hInst=0*/
367     if ( tclass )
368     {
369         WARN("-- found local Class registred with hInst=0\n");
370         return tclass;
371     }
372
373     TRACE("-- not found\n");
374     return 0;
375 }
376
377
378 /***********************************************************************
379  *           CLASS_RegisterClass
380  *
381  * The real RegisterClass() functionality.
382  */
383 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
384                                    DWORD style, INT classExtra, INT winExtra )
385 {
386     CLASS *classPtr;
387
388     TRACE("atom=0x%x hinst=%p style=0x%lx clExtr=0x%x winExtr=0x%x\n",
389           atom, hInstance, style, classExtra, winExtra );
390
391    /* Check if a class with this name already exists */
392     classPtr = CLASS_FindClassByAtom( atom, hInstance );
393     if (classPtr)
394     {
395         /* Class can be created only if it is local and */
396         /* if the class with the same name is global.   */
397
398         if ((style & CS_GLOBALCLASS) || !(classPtr->style & CS_GLOBALCLASS))
399         {
400             SetLastError( ERROR_CLASS_ALREADY_EXISTS );
401             return NULL;
402         }
403     }
404
405     /* Fix the extra bytes value */
406
407     if (classExtra < 0) classExtra = 0;
408     else if (classExtra > 40)  /* Extra bytes are limited to 40 in Win32 */
409         WARN("Class extra bytes %d is > 40\n", classExtra);
410     if (winExtra < 0) winExtra = 0;
411     else if (winExtra > 40)    /* Extra bytes are limited to 40 in Win32 */
412         WARN("Win extra bytes %d is > 40\n", winExtra );
413
414     /* Create the class */
415
416     classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
417     if (!classPtr) return NULL;
418     classPtr->style       = style;
419     classPtr->cbWndExtra  = winExtra;
420     classPtr->cbClsExtra  = classExtra;
421     classPtr->hInstance   = hInstance;
422     classPtr->atomName    = atom;
423     classPtr->dce         = (style & CS_CLASSDC) ? DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
424
425     /* Other non-null values must be set by caller */
426
427     if ((classPtr->next = firstClass)) firstClass->prev = classPtr;
428     firstClass = classPtr;
429     return classPtr;
430 }
431
432
433 /***********************************************************************
434  *           CLASS_UnregisterClass
435  *
436  * The real UnregisterClass() functionality.
437  */
438 static BOOL CLASS_UnregisterClass( ATOM atom, HINSTANCE hInstance )
439 {
440     CLASS *classPtr;
441     BOOL ret = FALSE;
442
443     USER_Lock();
444     if (atom &&
445         (classPtr = CLASS_FindClassByAtom( atom, hInstance )) &&
446         (!hInstance || classPtr->hInstance == hInstance))
447     {
448         ret = CLASS_FreeClass( classPtr );
449     }
450     else SetLastError( ERROR_CLASS_DOES_NOT_EXIST );
451
452     USER_Unlock();
453     return ret;
454 }
455
456
457 /***********************************************************************
458  *           CLASS_RegisterBuiltinClass
459  *
460  * Register a builtin control class.
461  * This allows having both ASCII and Unicode winprocs for the same class.
462  */
463 ATOM CLASS_RegisterBuiltinClass( const struct builtin_class_descr *descr )
464 {
465     ATOM atom;
466     CLASS *classPtr;
467
468     if (!(atom = GlobalAddAtomA( descr->name ))) return 0;
469
470     if (!(classPtr = CLASS_RegisterClass( atom, 0, descr->style, 0, descr->extra )))
471     {
472         GlobalDeleteAtom( atom );
473         return 0;
474     }
475
476     classPtr->hCursor       = LoadCursorA( 0, descr->cursor );
477     classPtr->hbrBackground = descr->brush;
478
479     if (descr->procA) WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)descr->procA,
480                                        WIN_PROC_32A, WIN_PROC_CLASS );
481     if (descr->procW) WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)descr->procW,
482                                        WIN_PROC_32W, WIN_PROC_CLASS );
483     return atom;
484 }
485
486
487 /***********************************************************************
488  *           CLASS_AddWindow
489  *
490  * Add a new window using this class, and return the necessary
491  * information for creating the window.
492  */
493 CLASS *CLASS_AddWindow( ATOM atom, HINSTANCE inst, WINDOWPROCTYPE type,
494                         INT *winExtra, WNDPROC *winproc, DWORD *style, struct tagDCE **dce )
495 {
496     CLASS *class;
497     if (type == WIN_PROC_16) inst = HINSTANCE_32(GetExePtr(HINSTANCE_16(inst)));
498
499     if (!(class = CLASS_FindClassByAtom( atom, inst ))) return NULL;
500     class->cWindows++;
501
502     if (type == WIN_PROC_32W)
503     {
504         if (!(*winproc = class->winprocW)) *winproc = class->winprocA;
505     }
506     else
507     {
508         if (!(*winproc = class->winprocA)) *winproc = class->winprocW;
509     }
510     *winExtra = class->cbWndExtra;
511     *style = class->style;
512     *dce = class->dce;
513     return class;
514 }
515
516
517 /***********************************************************************
518  *           CLASS_RemoveWindow
519  *
520  * Remove a window from the class window count.
521  */
522 void CLASS_RemoveWindow( CLASS *cls )
523 {
524     if (cls && cls->cWindows) cls->cWindows--;
525 }
526
527
528 /***********************************************************************
529  *              RegisterClass (USER.57)
530  */
531 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
532 {
533     ATOM atom;
534     CLASS *classPtr;
535     int iSmIconWidth, iSmIconHeight;
536     HINSTANCE hInstance = HINSTANCE_32(GetExePtr(wc->hInstance));
537
538     if (!(atom = GlobalAddAtomA( MapSL(wc->lpszClassName) ))) return 0;
539     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
540                                           wc->cbClsExtra, wc->cbWndExtra )))
541     {
542         GlobalDeleteAtom( atom );
543         return 0;
544     }
545
546     TRACE("atom=%04x wndproc=%08lx hinst=%p bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
547           atom, (DWORD)wc->lpfnWndProc, hInstance,
548           wc->hbrBackground, wc->style, wc->cbClsExtra,
549           wc->cbWndExtra, classPtr,
550           HIWORD(wc->lpszClassName) ? (char *)MapSL(wc->lpszClassName) : "" );
551
552     iSmIconWidth  = GetSystemMetrics(SM_CXSMICON);
553     iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
554
555     classPtr->hIcon         = HICON_32(wc->hIcon);
556     classPtr->hIconSm       = CopyImage(classPtr->hIcon, IMAGE_ICON,
557                                         iSmIconWidth, iSmIconHeight,
558                                         LR_COPYFROMRESOURCE);
559     classPtr->hCursor       = HCURSOR_32(wc->hCursor);
560     classPtr->hbrBackground = HBRUSH_32(wc->hbrBackground);
561
562     WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
563                      WIN_PROC_16, WIN_PROC_CLASS );
564     CLASS_SetMenuNameA( classPtr, MapSL(wc->lpszMenuName) );
565
566     return atom;
567 }
568
569
570 /***********************************************************************
571  *              RegisterClassA (USER32.@)
572  * RETURNS
573  *      >0: Unique identifier
574  *      0: Failure
575  */
576 ATOM WINAPI RegisterClassA( const WNDCLASSA* wc ) /* [in] Address of structure with class data */
577 {
578     ATOM atom;
579     int iSmIconWidth, iSmIconHeight;
580     CLASS *classPtr;
581
582     if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
583
584     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
585                                           wc->cbClsExtra, wc->cbWndExtra )))
586     {
587         GlobalDeleteAtom( atom );
588         return 0;
589     }
590
591     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
592           atom, wc->lpfnWndProc, wc->hInstance,
593           wc->hbrBackground, wc->style, wc->cbClsExtra,
594           wc->cbWndExtra, classPtr,
595           HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
596
597     iSmIconWidth  = GetSystemMetrics(SM_CXSMICON);
598     iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
599
600     classPtr->hIcon         = wc->hIcon;
601     classPtr->hIconSm       = CopyImage(wc->hIcon, IMAGE_ICON,
602                                         iSmIconWidth, iSmIconHeight,
603                                         LR_COPYFROMRESOURCE);
604     classPtr->hCursor       = wc->hCursor;
605     classPtr->hbrBackground = wc->hbrBackground;
606
607     WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
608                      WIN_PROC_32A, WIN_PROC_CLASS );
609     CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
610     return atom;
611 }
612
613
614 /***********************************************************************
615  *              RegisterClassW (USER32.@)
616  */
617 ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
618 {
619     ATOM atom;
620     int iSmIconWidth, iSmIconHeight;
621     CLASS *classPtr;
622
623     if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
624
625     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
626                                           wc->cbClsExtra, wc->cbWndExtra )))
627     {
628         GlobalDeleteAtom( atom );
629         return 0;
630     }
631
632     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
633           atom, wc->lpfnWndProc, wc->hInstance,
634           wc->hbrBackground, wc->style, wc->cbClsExtra,
635           wc->cbWndExtra, classPtr );
636
637     iSmIconWidth  = GetSystemMetrics(SM_CXSMICON);
638     iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
639
640     classPtr->hIcon         = wc->hIcon;
641     classPtr->hIconSm       = CopyImage(wc->hIcon, IMAGE_ICON,
642                                         iSmIconWidth, iSmIconHeight,
643                                         LR_COPYFROMRESOURCE);
644     classPtr->hCursor       = wc->hCursor;
645     classPtr->hbrBackground = wc->hbrBackground;
646
647     WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)wc->lpfnWndProc,
648                      WIN_PROC_32W, WIN_PROC_CLASS );
649     CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
650     return atom;
651 }
652
653
654 /***********************************************************************
655  *              RegisterClassEx (USER.397)
656  */
657 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
658 {
659     ATOM atom;
660     CLASS *classPtr;
661     HINSTANCE hInstance = HINSTANCE_32(GetExePtr( wc->hInstance ));
662
663     if (!(atom = GlobalAddAtomA( MapSL(wc->lpszClassName) ))) return 0;
664     if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
665                                           wc->cbClsExtra, wc->cbWndExtra )))
666     {
667         GlobalDeleteAtom( atom );
668         return 0;
669     }
670
671     TRACE("atom=%04x wndproc=%p hinst=%p bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
672           atom, wc->lpfnWndProc, hInstance,
673           wc->hbrBackground, wc->style, wc->cbClsExtra,
674           wc->cbWndExtra, classPtr );
675
676     classPtr->hIcon         = HICON_32(wc->hIcon);
677     classPtr->hIconSm       = HICON_32(wc->hIconSm);
678     classPtr->hCursor       = HCURSOR_32(wc->hCursor);
679     classPtr->hbrBackground = HBRUSH_32(wc->hbrBackground);
680
681     WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
682                      WIN_PROC_16, WIN_PROC_CLASS );
683     CLASS_SetMenuNameA( classPtr, MapSL(wc->lpszMenuName) );
684     return atom;
685 }
686
687
688 /***********************************************************************
689  *              RegisterClassExA (USER32.@)
690  */
691 ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
692 {
693     ATOM atom;
694     CLASS *classPtr;
695
696     if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
697
698     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
699                                           wc->cbClsExtra, wc->cbWndExtra )))
700     {
701         GlobalDeleteAtom( atom );
702         return 0;
703     }
704
705     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
706           atom, wc->lpfnWndProc, wc->hInstance,
707           wc->hbrBackground, wc->style, wc->cbClsExtra,
708           wc->cbWndExtra, classPtr );
709
710     classPtr->hIcon         = wc->hIcon;
711     classPtr->hIconSm       = wc->hIconSm;
712     classPtr->hCursor       = wc->hCursor;
713     classPtr->hbrBackground = wc->hbrBackground;
714     WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
715                      WIN_PROC_32A, WIN_PROC_CLASS );
716     CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
717     return atom;
718 }
719
720
721 /***********************************************************************
722  *              RegisterClassExW (USER32.@)
723  */
724 ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
725 {
726     ATOM atom;
727     CLASS *classPtr;
728
729     if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
730
731     if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
732                                           wc->cbClsExtra, wc->cbWndExtra )))
733     {
734         GlobalDeleteAtom( atom );
735         return 0;
736     }
737
738     TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
739           atom, wc->lpfnWndProc, wc->hInstance,
740           wc->hbrBackground, wc->style, wc->cbClsExtra,
741           wc->cbWndExtra, classPtr );
742
743     classPtr->hIcon         = wc->hIcon;
744     classPtr->hIconSm       = wc->hIconSm;
745     classPtr->hCursor       = wc->hCursor;
746     classPtr->hbrBackground = wc->hbrBackground;
747     WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)wc->lpfnWndProc,
748                      WIN_PROC_32W, WIN_PROC_CLASS );
749     CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
750     return atom;
751 }
752
753
754 /***********************************************************************
755  *              UnregisterClass (USER.403)
756  */
757 BOOL16 WINAPI UnregisterClass16( LPCSTR className, HINSTANCE16 hInstance )
758 {
759     return UnregisterClassA( className, HINSTANCE_32(GetExePtr( hInstance )) );
760 }
761
762 /***********************************************************************
763  *              UnregisterClassA (USER32.@)
764  *
765  */
766 BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
767 {
768     TRACE("%s %p\n",debugstr_a(className), hInstance);
769     return CLASS_UnregisterClass( GlobalFindAtomA( className ), hInstance );
770 }
771
772 /***********************************************************************
773  *              UnregisterClassW (USER32.@)
774  */
775 BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
776 {
777     TRACE("%s %p\n",debugstr_w(className), hInstance);
778     return CLASS_UnregisterClass( GlobalFindAtomW( className ), hInstance );
779 }
780
781
782 /***********************************************************************
783  *              GetClassWord (USER32.@)
784  */
785 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
786 {
787     CLASS *class;
788     WORD retvalue = 0;
789
790     if (offset < 0) return GetClassLongA( hwnd, offset );
791
792     TRACE("%p %x\n",hwnd, offset);
793
794     if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
795
796     if (offset <= class->cbClsExtra - sizeof(WORD))
797         memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) );
798     else
799         SetLastError( ERROR_INVALID_INDEX );
800     release_class_ptr( class );
801     return retvalue;
802 }
803
804
805 /***********************************************************************
806  *              GetClassLong (USER.131)
807  */
808 LONG WINAPI GetClassLong16( HWND16 hwnd16, INT16 offset )
809 {
810     CLASS *class;
811     LONG ret;
812     HWND hwnd = (HWND)(ULONG_PTR)hwnd16;  /* no need for full handle */
813
814     TRACE("%p %d\n",hwnd, offset);
815
816     switch( offset )
817     {
818     case GCL_WNDPROC:
819         if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
820         ret = (LONG)CLASS_GetProc( class, WIN_PROC_16 );
821         release_class_ptr( class );
822         return ret;
823     case GCL_MENUNAME:
824         if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
825         ret = (LONG)CLASS_GetMenuName16( class );
826         release_class_ptr( class );
827         return ret;
828     default:
829         return GetClassLongA( hwnd, offset );
830     }
831 }
832
833
834 /***********************************************************************
835  *              GetClassLongW (USER32.@)
836  */
837 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
838 {
839     CLASS *class;
840     LONG retvalue = 0;
841
842     TRACE("%p %d\n", hwnd, offset);
843
844     if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
845
846     if (offset >= 0)
847     {
848         if (offset <= class->cbClsExtra - sizeof(LONG))
849             memcpy( &retvalue, (char *)(class + 1) + offset, sizeof(retvalue) );
850         else
851             SetLastError( ERROR_INVALID_INDEX );
852         release_class_ptr( class );
853         return retvalue;
854     }
855
856     switch(offset)
857     {
858     case GCL_HBRBACKGROUND:
859         retvalue = (LONG)class->hbrBackground;
860         break;
861     case GCL_HCURSOR:
862         retvalue = (LONG)class->hCursor;
863         break;
864     case GCL_HICON:
865         retvalue = (LONG)class->hIcon;
866         break;
867     case GCL_HICONSM:
868         retvalue = (LONG)class->hIconSm;
869         break;
870     case GCL_STYLE:
871         retvalue = (LONG)class->style;
872         break;
873     case GCL_CBWNDEXTRA:
874         retvalue = (LONG)class->cbWndExtra;
875         break;
876     case GCL_CBCLSEXTRA:
877         retvalue = (LONG)class->cbClsExtra;
878         break;
879     case GCL_HMODULE:
880         retvalue = (LONG)class->hInstance;
881         break;
882     case GCL_WNDPROC:
883         retvalue = (LONG)CLASS_GetProc( class, WIN_PROC_32W );
884         break;
885     case GCL_MENUNAME:
886         retvalue = (LONG)CLASS_GetMenuNameW( class );
887         break;
888     case GCW_ATOM:
889         retvalue = (DWORD)class->atomName;
890         break;
891     default:
892         SetLastError( ERROR_INVALID_INDEX );
893         break;
894     }
895     release_class_ptr( class );
896     return retvalue;
897 }
898
899
900 /***********************************************************************
901  *              GetClassLongA (USER32.@)
902  */
903 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
904 {
905     CLASS *class;
906     LONG retvalue;
907
908     if (offset != GCL_WNDPROC && offset != GCL_MENUNAME)
909         return GetClassLongW( hwnd, offset );
910
911     TRACE("%p %d\n", hwnd, offset);
912
913     if (!(class = get_class_ptr( hwnd, FALSE ))) return 0;
914
915     if (offset == GCL_WNDPROC)
916         retvalue = (LONG)CLASS_GetProc( class, WIN_PROC_32A );
917     else  /* GCL_MENUNAME */
918         retvalue = (LONG)CLASS_GetMenuNameA( class );
919
920     release_class_ptr( class );
921     return retvalue;
922 }
923
924
925 /***********************************************************************
926  *              SetClassWord (USER32.@)
927  */
928 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
929 {
930     CLASS *class;
931     WORD retval = 0;
932
933     if (offset < 0) return SetClassLongA( hwnd, offset, (DWORD)newval );
934
935     TRACE("%p %d %x\n", hwnd, offset, newval);
936
937     if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
938
939     if (offset <= class->cbClsExtra - sizeof(WORD))
940     {
941         void *ptr = (char *)(class + 1) + offset;
942         memcpy( &retval, ptr, sizeof(retval) );
943         memcpy( ptr, &newval, sizeof(newval) );
944     }
945     else SetLastError( ERROR_INVALID_INDEX );
946
947     release_class_ptr( class );
948     return retval;
949 }
950
951
952 /***********************************************************************
953  *              SetClassLong (USER.132)
954  */
955 LONG WINAPI SetClassLong16( HWND16 hwnd16, INT16 offset, LONG newval )
956 {
957     CLASS *class;
958     LONG retval;
959     HWND hwnd = (HWND)(ULONG_PTR)hwnd16;  /* no need for full handle */
960
961     TRACE("%p %d %lx\n", hwnd, offset, newval);
962
963     switch(offset)
964     {
965     case GCL_WNDPROC:
966         if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
967         retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_16 );
968         release_class_ptr( class );
969         return retval;
970     case GCL_MENUNAME:
971         newval = (LONG)MapSL( newval );
972         /* fall through */
973     default:
974         return SetClassLongA( hwnd, offset, newval );
975     }
976 }
977
978
979 /***********************************************************************
980  *              SetClassLongW (USER32.@)
981  */
982 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
983 {
984     CLASS *class;
985     LONG retval = 0;
986
987     TRACE("%p %d %lx\n", hwnd, offset, newval);
988
989     if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
990
991     if (offset >= 0)
992     {
993         if (offset <= class->cbClsExtra - sizeof(LONG))
994         {
995             void *ptr = (char *)(class + 1) + offset;
996             memcpy( &retval, ptr, sizeof(retval) );
997             memcpy( ptr, &newval, sizeof(newval) );
998         }
999         else SetLastError( ERROR_INVALID_INDEX );
1000     }
1001     else switch(offset)
1002     {
1003     case GCL_MENUNAME:
1004         CLASS_SetMenuNameW( class, (LPCWSTR)newval );
1005         retval = 0;  /* Old value is now meaningless anyway */
1006         break;
1007     case GCL_WNDPROC:
1008         retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_32W );
1009         break;
1010     case GCL_HBRBACKGROUND:
1011         retval = (LONG)class->hbrBackground;
1012         class->hbrBackground = (HBRUSH)newval;
1013         break;
1014     case GCL_HCURSOR:
1015         retval = (LONG)class->hCursor;
1016         class->hCursor = (HCURSOR)newval;
1017         break;
1018     case GCL_HICON:
1019         retval = (LONG)class->hIcon;
1020         class->hIcon = (HICON)newval;
1021         break;
1022     case GCL_HICONSM:
1023         retval = (LONG)class->hIconSm;
1024         class->hIconSm = (HICON)newval;
1025         break;
1026     case GCL_STYLE:
1027         retval = (LONG)class->style;
1028         class->style = newval;
1029         break;
1030     case GCL_CBWNDEXTRA:
1031         retval = (LONG)class->cbWndExtra;
1032         class->cbWndExtra = newval;
1033         break;
1034     case GCL_HMODULE:
1035         retval = (LONG)class->hInstance;
1036         class->hInstance = (HINSTANCE)newval;
1037         break;
1038     case GCW_ATOM:
1039         retval = (DWORD)class->atomName;
1040         class->atomName = newval;
1041         break;
1042     case GCL_CBCLSEXTRA:  /* cannot change this one */
1043         SetLastError( ERROR_INVALID_PARAMETER );
1044         break;
1045     default:
1046         SetLastError( ERROR_INVALID_INDEX );
1047         break;
1048     }
1049     release_class_ptr( class );
1050     return retval;
1051 }
1052
1053
1054 /***********************************************************************
1055  *              SetClassLongA (USER32.@)
1056  */
1057 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
1058 {
1059     CLASS *class;
1060     LONG retval;
1061
1062     if (offset != GCL_WNDPROC && offset != GCL_MENUNAME)
1063         return SetClassLongW( hwnd, offset, newval );
1064
1065     TRACE("%p %d %lx\n", hwnd, offset, newval);
1066
1067     if (!(class = get_class_ptr( hwnd, TRUE ))) return 0;
1068
1069     if (offset == GCL_WNDPROC)
1070         retval = (LONG)CLASS_SetProc( class, (WNDPROC)newval, WIN_PROC_32A );
1071     else  /* GCL_MENUNAME */
1072     {
1073         CLASS_SetMenuNameA( class, (LPCSTR)newval );
1074         retval = 0;  /* Old value is now meaningless anyway */
1075     }
1076     release_class_ptr( class );
1077     return retval;
1078 }
1079
1080
1081 /***********************************************************************
1082  *              GetClassNameA (USER32.@)
1083  */
1084 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1085 {
1086     INT ret = GlobalGetAtomNameA( GetClassLongA( hwnd, GCW_ATOM ), buffer, count );
1087
1088     TRACE("%p %s %x\n",hwnd, debugstr_a(buffer), count);
1089     return ret;
1090 }
1091
1092
1093 /***********************************************************************
1094  *              GetClassNameW (USER32.@)
1095  */
1096 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1097 {
1098     INT ret = GlobalGetAtomNameW( GetClassLongW( hwnd, GCW_ATOM ), buffer, count );
1099
1100     TRACE("%p %s %x\n",hwnd, debugstr_w(buffer), count);
1101     return ret;
1102 }
1103
1104
1105 /***********************************************************************
1106  *              GetClassInfo (USER.404)
1107  */
1108 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInst16, SEGPTR name, WNDCLASS16 *wc )
1109 {
1110     ATOM atom;
1111     CLASS *classPtr;
1112     HINSTANCE hInstance = HINSTANCE_32(GetExePtr( hInst16 ));
1113
1114     TRACE("%p %s %p\n",hInstance, debugstr_a(MapSL(name)), wc);
1115
1116     if (!(atom = GlobalFindAtomA( MapSL(name) )) ||
1117         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1118         return FALSE;
1119     if ((hInstance != classPtr->hInstance) &&
1120         !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1121         return FALSE;
1122     wc->style         = (UINT16)classPtr->style;
1123     wc->lpfnWndProc   = CLASS_GetProc( classPtr, WIN_PROC_16 );
1124     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1125     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1126     wc->hInstance     = classPtr->style & CS_GLOBALCLASS ? GetModuleHandle16("USER") : HINSTANCE_16(classPtr->hInstance);
1127     wc->hIcon         = HICON_16(classPtr->hIcon);
1128     wc->hCursor       = HCURSOR_16(classPtr->hCursor);
1129     wc->hbrBackground = HBRUSH_16(classPtr->hbrBackground);
1130     wc->lpszClassName = name;
1131     wc->lpszMenuName  = CLASS_GetMenuName16( classPtr );
1132     return TRUE;
1133 }
1134
1135
1136 /***********************************************************************
1137  *              GetClassInfoA (USER32.@)
1138  */
1139 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1140                                WNDCLASSA *wc )
1141 {
1142     ATOM atom;
1143     CLASS *classPtr;
1144
1145     TRACE("%p %p %p\n",hInstance, name, wc);
1146
1147     /* workaround: if hInstance=NULL you expect to get the system classes
1148     but this classes (as example from comctl32.dll SysListView) won't be
1149     registered with hInstance=NULL in WINE because of the late loading
1150     of this dll. fixes file dialogs in WinWord95 (jsch)*/
1151
1152     if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1153         return FALSE;
1154
1155     if (!(classPtr->style & CS_GLOBALCLASS) &&
1156         classPtr->hInstance &&
1157         (hInstance != classPtr->hInstance))
1158     {
1159         if (hInstance) return FALSE;
1160         WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1161     }
1162
1163     wc->style         = classPtr->style;
1164     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
1165     wc->cbClsExtra    = classPtr->cbClsExtra;
1166     wc->cbWndExtra    = classPtr->cbWndExtra;
1167     wc->hInstance     = hInstance;
1168     wc->hIcon         = (HICON)classPtr->hIcon;
1169     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1170     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1171     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1172     wc->lpszClassName = name;
1173     return TRUE;
1174 }
1175
1176
1177 /***********************************************************************
1178  *              GetClassInfoW (USER32.@)
1179  */
1180 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1181                                WNDCLASSW *wc )
1182 {
1183     ATOM atom;
1184     CLASS *classPtr;
1185
1186     TRACE("%p %p %p\n",hInstance, name, wc);
1187
1188     if (        !(atom=GlobalFindAtomW(name)) ||
1189                 !(classPtr=CLASS_FindClassByAtom(atom,hInstance))
1190     )
1191         return FALSE;
1192
1193     if (!(classPtr->style & CS_GLOBALCLASS) &&
1194         classPtr->hInstance &&
1195         (hInstance != classPtr->hInstance))
1196     {
1197         if (hInstance) return FALSE;
1198         WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name));
1199     }
1200     wc->style         = classPtr->style;
1201     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
1202     wc->cbClsExtra    = classPtr->cbClsExtra;
1203     wc->cbWndExtra    = classPtr->cbWndExtra;
1204     wc->hInstance     = hInstance;
1205     wc->hIcon         = (HICON)classPtr->hIcon;
1206     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1207     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1208     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1209     wc->lpszClassName = name;
1210     return TRUE;
1211 }
1212
1213
1214 /***********************************************************************
1215  *              GetClassInfoEx (USER.398)
1216  *
1217  * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1218  * same in Win16 as in Win32. --AJ
1219  */
1220 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInst16, SEGPTR name, WNDCLASSEX16 *wc )
1221 {
1222     ATOM atom;
1223     CLASS *classPtr;
1224     HINSTANCE hInstance = HINSTANCE_32(GetExePtr( hInst16 ));
1225
1226     TRACE("%p %s %p\n",hInstance,debugstr_a( MapSL(name) ), wc);
1227
1228     if (!(atom = GlobalFindAtomA( MapSL(name) )) ||
1229         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1230         (hInstance != classPtr->hInstance)) return FALSE;
1231     wc->style         = classPtr->style;
1232     wc->lpfnWndProc   = CLASS_GetProc( classPtr, WIN_PROC_16 );
1233     wc->cbClsExtra    = (INT16)classPtr->cbClsExtra;
1234     wc->cbWndExtra    = (INT16)classPtr->cbWndExtra;
1235     wc->hInstance     = HINSTANCE_16(classPtr->hInstance);
1236     wc->hIcon         = HICON_16(classPtr->hIcon);
1237     wc->hIconSm       = HICON_16(classPtr->hIconSm);
1238     wc->hCursor       = HCURSOR_16(classPtr->hCursor);
1239     wc->hbrBackground = HBRUSH_16(classPtr->hbrBackground);
1240     wc->lpszClassName = (SEGPTR)0;
1241     wc->lpszMenuName  = CLASS_GetMenuName16( classPtr );
1242     wc->lpszClassName = name;
1243
1244     /* We must return the atom of the class here instead of just TRUE. */
1245     return atom;
1246 }
1247
1248
1249 /***********************************************************************
1250  *              GetClassInfoExA (USER32.@)
1251  */
1252 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1253                                  WNDCLASSEXA *wc )
1254 {
1255     ATOM atom;
1256     CLASS *classPtr;
1257
1258     TRACE("%p %p %p\n",hInstance, name, wc);
1259
1260     if (!(atom = GlobalFindAtomA( name )) ||
1261         !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1262         /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1263     wc->style         = classPtr->style;
1264     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
1265     wc->cbClsExtra    = classPtr->cbClsExtra;
1266     wc->cbWndExtra    = classPtr->cbWndExtra;
1267     wc->hInstance     = classPtr->hInstance;
1268     wc->hIcon         = (HICON)classPtr->hIcon;
1269     wc->hIconSm       = (HICON)classPtr->hIconSm;
1270     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1271     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1272     wc->lpszMenuName  = CLASS_GetMenuNameA( classPtr );
1273     wc->lpszClassName = name;
1274
1275     /* We must return the atom of the class here instead of just TRUE. */
1276     return atom;
1277 }
1278
1279
1280 /***********************************************************************
1281  *              GetClassInfoExW (USER32.@)
1282  */
1283 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1284                                  WNDCLASSEXW *wc )
1285 {
1286     ATOM atom;
1287     CLASS *classPtr;
1288
1289     TRACE("%p %p %p\n",hInstance, name, wc);
1290
1291     if (!(atom = GlobalFindAtomW( name )) ||
1292         !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1293         (hInstance != classPtr->hInstance)) return FALSE;
1294     wc->style         = classPtr->style;
1295     wc->lpfnWndProc   = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
1296     wc->cbClsExtra    = classPtr->cbClsExtra;
1297     wc->cbWndExtra    = classPtr->cbWndExtra;
1298     wc->hInstance     = classPtr->hInstance;
1299     wc->hIcon         = (HICON)classPtr->hIcon;
1300     wc->hIconSm       = (HICON)classPtr->hIconSm;
1301     wc->hCursor       = (HCURSOR)classPtr->hCursor;
1302     wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1303     wc->lpszMenuName  = CLASS_GetMenuNameW( classPtr );
1304     wc->lpszClassName = name;
1305
1306     /* We must return the atom of the class here instead of just TRUE. */
1307     return atom;
1308 }
1309
1310
1311 #if 0  /* toolhelp is in kernel, so this cannot work */
1312
1313 /***********************************************************************
1314  *              ClassFirst (TOOLHELP.69)
1315  */
1316 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1317 {
1318     TRACE("%p\n",pClassEntry);
1319     pClassEntry->wNext = 1;
1320     return ClassNext16( pClassEntry );
1321 }
1322
1323
1324 /***********************************************************************
1325  *              ClassNext (TOOLHELP.70)
1326  */
1327 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1328 {
1329     int i;
1330     CLASS *class = firstClass;
1331
1332     TRACE("%p\n",pClassEntry);
1333
1334     if (!pClassEntry->wNext) return FALSE;
1335     for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1336     if (!class)
1337     {
1338         pClassEntry->wNext = 0;
1339         return FALSE;
1340     }
1341     pClassEntry->hInst = class->hInstance;
1342     pClassEntry->wNext++;
1343     GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1344                           sizeof(pClassEntry->szClassName) );
1345     return TRUE;
1346 }
1347 #endif