Tried another kludge for the Xmd.h problem.
[wine/multimedia.git] / windows / class.c
blob416e4eea45251aa9b333b91d7147daf696ad83d0
1 /*
2 * Window classes functions
4 * Copyright 1993, 1996 Alexandre Julliard
5 * 1998 Juergen Schmied (jsch)
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)
11 * FIXME: There seems to be a general problem with hInstance in WINE
12 * classes are getting registred with wrong hInstance.
15 #include <stdlib.h>
16 #include <string.h>
17 #include "class.h"
18 #include "heap.h"
19 #include "win.h"
20 #include "dce.h"
21 #include "ldt.h"
22 #include "toolhelp.h"
23 #include "winproc.h"
24 #include "debug.h"
25 #include "winerror.h"
28 static CLASS *firstClass = NULL;
31 /***********************************************************************
32 * CLASS_DumpClass
34 * Dump the content of a class structure to stderr.
36 void CLASS_DumpClass( CLASS *ptr )
38 char className[MAX_CLASSNAME+1];
39 int i;
41 if (ptr->magic != CLASS_MAGIC)
43 DUMP("%p is not a class\n", ptr );
44 return;
47 GlobalGetAtomName32A( ptr->atomName, className, sizeof(className) );
49 DUMP( "Class %p:\n", ptr );
50 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
51 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
52 "clsExtra=%d winExtra=%d #windows=%d\n",
53 ptr->next, ptr->atomName, className, ptr->style,
54 (UINT32)ptr->winproc, ptr->hInstance, (UINT32)ptr->dce,
55 ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
56 ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
57 if (ptr->cbClsExtra)
59 DUMP( "extra bytes:" );
60 for (i = 0; i < ptr->cbClsExtra; i++)
61 DUMP( " %02x", *((BYTE *)ptr->wExtra+i) );
62 DUMP( "\n" );
64 DUMP( "\n" );
68 /***********************************************************************
69 * CLASS_WalkClasses
71 * Walk the class list and print each class on stderr.
73 void CLASS_WalkClasses(void)
75 CLASS *ptr;
76 char className[MAX_CLASSNAME+1];
78 DUMP( " Class Name Style WndProc\n" );
79 for (ptr = firstClass; ptr; ptr = ptr->next)
81 GlobalGetAtomName32A( ptr->atomName, className, sizeof(className) );
82 DUMP( "%08x %-20.20s %08x %08x\n", (UINT32)ptr, className,
83 ptr->style, (UINT32)ptr->winproc );
85 DUMP( "\n" );
89 /***********************************************************************
90 * CLASS_GetMenuNameA
92 * Get the menu name as a ASCII string.
94 static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
96 if (!classPtr->menuNameA && classPtr->menuNameW)
98 /* We need to copy the Unicode string */
99 classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
101 return classPtr->menuNameA;
105 /***********************************************************************
106 * CLASS_GetMenuNameW
108 * Get the menu name as a Unicode string.
110 static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
112 if (!classPtr->menuNameW && classPtr->menuNameA)
114 if (!HIWORD(classPtr->menuNameA))
115 return (LPWSTR)classPtr->menuNameA;
116 /* Now we need to copy the ASCII string */
117 classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
118 classPtr->menuNameA );
120 return classPtr->menuNameW;
124 /***********************************************************************
125 * CLASS_SetMenuNameA
127 * Set the menu name in a class structure by copying the string.
129 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
131 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
132 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
133 classPtr->menuNameA = SEGPTR_STRDUP( name );
134 classPtr->menuNameW = 0;
138 /***********************************************************************
139 * CLASS_SetMenuNameW
141 * Set the menu name in a class structure by copying the string.
143 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
145 if (!HIWORD(name))
147 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
148 return;
150 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
151 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
152 if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
153 (lstrlen32W(name)+1)*sizeof(WCHAR) )))
154 lstrcpy32W( classPtr->menuNameW, name );
155 classPtr->menuNameA = 0;
159 /***********************************************************************
160 * CLASS_GetClassNameA
162 * Get the clas name as a ASCII string.
164 static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
166 if (!classPtr->classNameA && classPtr->classNameW)
168 /* We need to copy the Unicode string */
169 classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
171 return classPtr->classNameA;
175 /***********************************************************************
176 * CLASS_GetClassNameW
178 * Get the class name as a Unicode string.
180 static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
182 if (!classPtr->classNameW && classPtr->classNameA)
184 if (!HIWORD(classPtr->classNameA))
185 return (LPWSTR)classPtr->classNameA;
186 /* Now we need to copy the ASCII string */
187 classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
188 classPtr->classNameA );
190 return classPtr->classNameW;
193 /***********************************************************************
194 * CLASS_SetClassNameA
196 * Set the class name in a class structure by copying the string.
198 static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
200 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
201 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
202 classPtr->classNameA = SEGPTR_STRDUP( name );
203 classPtr->classNameW = 0;
207 /***********************************************************************
208 * CLASS_SetClassNameW
210 * Set the class name in a class structure by copying the string.
212 static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
214 if (!HIWORD(name))
216 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
217 return;
219 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
220 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
221 if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
222 (lstrlen32W(name)+1)*sizeof(WCHAR) )))
223 lstrcpy32W( classPtr->classNameW, name );
224 classPtr->classNameA = 0;
228 /***********************************************************************
229 * CLASS_FreeClass
231 * Free a class structure.
233 static BOOL32 CLASS_FreeClass( CLASS *classPtr )
235 CLASS **ppClass;
236 TRACE(class,"%p \n", classPtr);
238 /* Check if we can remove this class */
240 if (classPtr->cWindows > 0) return FALSE;
242 /* Remove the class from the linked list */
244 for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
245 if (*ppClass == classPtr) break;
246 if (!*ppClass)
248 ERR( class, "Class list corrupted\n" );
249 return FALSE;
251 *ppClass = classPtr->next;
253 /* Delete the class */
255 if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
256 if (classPtr->hbrBackground) DeleteObject32( classPtr->hbrBackground );
257 GlobalDeleteAtom( classPtr->atomName );
258 CLASS_SetMenuNameA( classPtr, NULL );
259 CLASS_SetClassNameA( classPtr, NULL );
260 WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
261 HeapFree( SystemHeap, 0, classPtr );
262 return TRUE;
266 /***********************************************************************
267 * CLASS_FreeModuleClasses
269 void CLASS_FreeModuleClasses( HMODULE16 hModule )
271 CLASS *ptr, *next;
273 TRACE(class,"0x%08x \n", hModule);
275 for (ptr = firstClass; ptr; ptr = next)
277 next = ptr->next;
278 if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
283 /***********************************************************************
284 * CLASS_FindClassByAtom
286 * Return a pointer to the class.
287 * hinstance has been normalized by the caller.
289 * NOTES
290 * 980805 a local class will be found now if registred with hInst=0
291 * and looed up with a hInst!=0. msmoney does it (jsch)
293 CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE32 hinstance )
294 { CLASS * class, *tclass=0;
296 TRACE(class,"0x%08x 0x%08x\n", atom, hinstance);
298 /* First search task-specific classes */
300 for (class = firstClass; (class); class = class->next)
302 if (class->style & CS_GLOBALCLASS) continue;
303 if (class->atomName == atom)
305 if (hinstance==class->hInstance || hinstance==0xffff )
307 TRACE(class,"-- found local %p\n", class);
308 return class;
310 if (class->hInstance==0) tclass = class;
314 /* Then search global classes */
316 for (class = firstClass; (class); class = class->next)
318 if (!(class->style & CS_GLOBALCLASS)) continue;
319 if (class->atomName == atom)
321 TRACE(class,"-- found global %p\n", class);
322 return class;
326 /* Then check if there was a local class with hInst=0*/
327 if ( tclass )
329 WARN(class,"-- found local Class registred with hInst=0\n");
330 return tclass;
333 TRACE(class,"-- not found\n");
334 return 0;
338 /***********************************************************************
339 * CLASS_RegisterClass
341 * The real RegisterClass() functionality.
343 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE32 hInstance,
344 DWORD style, INT32 classExtra,
345 INT32 winExtra, WNDPROC16 wndProc,
346 WINDOWPROCTYPE wndProcType )
348 CLASS *classPtr;
350 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
351 atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
353 /* Check if a class with this name already exists */
354 classPtr = CLASS_FindClassByAtom( atom, hInstance );
355 if (classPtr)
357 /* Class can be created only if it is local and */
358 /* if the class with the same name is global. */
360 if (style & CS_GLOBALCLASS) return NULL;
361 if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
364 /* Fix the extra bytes value */
366 if (classExtra < 0) classExtra = 0;
367 else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
368 WARN(class, "Class extra bytes %d is > 40\n", classExtra);
369 if (winExtra < 0) winExtra = 0;
370 else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
371 WARN(class, "Win extra bytes %d is > 40\n", winExtra );
373 /* Create the class */
375 classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
376 classExtra - sizeof(classPtr->wExtra) );
377 if (!classPtr) return NULL;
378 classPtr->next = firstClass;
379 classPtr->magic = CLASS_MAGIC;
380 classPtr->cWindows = 0;
381 classPtr->style = style;
382 classPtr->winproc = (HWINDOWPROC)0;
383 classPtr->cbWndExtra = winExtra;
384 classPtr->cbClsExtra = classExtra;
385 classPtr->hInstance = hInstance;
386 classPtr->atomName = atom;
387 classPtr->menuNameA = 0;
388 classPtr->menuNameW = 0;
389 classPtr->classNameA = 0;
390 classPtr->classNameW = 0;
391 classPtr->dce = (style & CS_CLASSDC) ?
392 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
394 WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
396 /* Other values must be set by caller */
398 if (classExtra) memset( classPtr->wExtra, 0, classExtra );
399 firstClass = classPtr;
400 return classPtr;
404 /***********************************************************************
405 * RegisterClass16 (USER.57)
407 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
409 ATOM atom;
410 CLASS *classPtr;
411 HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
413 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
414 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
415 wc->cbClsExtra, wc->cbWndExtra,
416 wc->lpfnWndProc, WIN_PROC_16 )))
418 GlobalDeleteAtom( atom );
419 return 0;
422 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
423 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
424 atom, (DWORD)wc->lpfnWndProc, hInstance,
425 wc->hbrBackground, wc->style, wc->cbClsExtra,
426 wc->cbWndExtra, classPtr,
427 HIWORD(wc->lpszClassName) ?
428 (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
430 classPtr->hIcon = wc->hIcon;
431 classPtr->hIconSm = 0;
432 classPtr->hCursor = wc->hCursor;
433 classPtr->hbrBackground = wc->hbrBackground;
435 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
436 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
437 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
438 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
440 return atom;
444 /***********************************************************************
445 * RegisterClass32A (USER32.427)
446 * RETURNS
447 * >0: Unique identifier
448 * 0: Failure
450 ATOM WINAPI RegisterClass32A(
451 const WNDCLASS32A* wc /* Address of structure with class data */
453 ATOM atom;
454 CLASS *classPtr;
456 if (!(atom = GlobalAddAtom32A( wc->lpszClassName )))
458 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
459 return FALSE;
461 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
462 wc->cbClsExtra, wc->cbWndExtra,
463 (WNDPROC16)wc->lpfnWndProc,
464 WIN_PROC_32A )))
465 { GlobalDeleteAtom( atom );
466 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
467 return FALSE;
470 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
471 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
472 wc->hbrBackground, wc->style, wc->cbClsExtra,
473 wc->cbWndExtra, classPtr,
474 HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
476 classPtr->hIcon = (HICON16)wc->hIcon;
477 classPtr->hIconSm = 0;
478 classPtr->hCursor = (HCURSOR16)wc->hCursor;
479 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
481 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
482 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
483 return atom;
487 /***********************************************************************
488 * RegisterClass32W (USER32.430)
490 ATOM WINAPI RegisterClass32W( const WNDCLASS32W* wc )
492 ATOM atom;
493 CLASS *classPtr;
495 if (!(atom = GlobalAddAtom32W( wc->lpszClassName )))
497 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
498 return FALSE;
500 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
501 wc->cbClsExtra, wc->cbWndExtra,
502 (WNDPROC16)wc->lpfnWndProc,
503 WIN_PROC_32W )))
505 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
506 GlobalDeleteAtom( atom );
507 return 0;
510 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
511 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
512 wc->hbrBackground, wc->style, wc->cbClsExtra,
513 wc->cbWndExtra, classPtr );
515 classPtr->hIcon = (HICON16)wc->hIcon;
516 classPtr->hIconSm = 0;
517 classPtr->hCursor = (HCURSOR16)wc->hCursor;
518 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
520 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
521 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
522 return atom;
526 /***********************************************************************
527 * RegisterClassEx16 (USER.397)
529 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
531 ATOM atom;
532 CLASS *classPtr;
533 HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
535 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
536 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
537 wc->cbClsExtra, wc->cbWndExtra,
538 wc->lpfnWndProc, WIN_PROC_16 )))
540 GlobalDeleteAtom( atom );
541 return 0;
544 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
545 atom, (DWORD)wc->lpfnWndProc, hInstance,
546 wc->hbrBackground, wc->style, wc->cbClsExtra,
547 wc->cbWndExtra, classPtr );
549 classPtr->hIcon = wc->hIcon;
550 classPtr->hIconSm = wc->hIconSm;
551 classPtr->hCursor = wc->hCursor;
552 classPtr->hbrBackground = wc->hbrBackground;
554 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
555 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
556 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
557 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
558 return atom;
562 /***********************************************************************
563 * RegisterClassEx32A (USER32.428)
565 ATOM WINAPI RegisterClassEx32A( const WNDCLASSEX32A* wc )
567 ATOM atom;
568 CLASS *classPtr;
570 if (!(atom = GlobalAddAtom32A( wc->lpszClassName )))
572 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
573 return FALSE;
575 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
576 wc->cbClsExtra, wc->cbWndExtra,
577 (WNDPROC16)wc->lpfnWndProc,
578 WIN_PROC_32A )))
580 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
581 GlobalDeleteAtom( atom );
582 return FALSE;
585 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
586 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
587 wc->hbrBackground, wc->style, wc->cbClsExtra,
588 wc->cbWndExtra, classPtr );
590 classPtr->hIcon = (HICON16)wc->hIcon;
591 classPtr->hIconSm = (HICON16)wc->hIconSm;
592 classPtr->hCursor = (HCURSOR16)wc->hCursor;
593 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
594 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
595 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
596 return atom;
600 /***********************************************************************
601 * RegisterClassEx32W (USER32.429)
603 ATOM WINAPI RegisterClassEx32W( const WNDCLASSEX32W* wc )
605 ATOM atom;
606 CLASS *classPtr;
608 if (!(atom = GlobalAddAtom32W( wc->lpszClassName )))
610 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
611 return 0;
613 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
614 wc->cbClsExtra, wc->cbWndExtra,
615 (WNDPROC16)wc->lpfnWndProc,
616 WIN_PROC_32W )))
618 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
619 GlobalDeleteAtom( atom );
620 return 0;
623 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
624 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
625 wc->hbrBackground, wc->style, wc->cbClsExtra,
626 wc->cbWndExtra, classPtr );
628 classPtr->hIcon = (HICON16)wc->hIcon;
629 classPtr->hIconSm = (HICON16)wc->hIconSm;
630 classPtr->hCursor = (HCURSOR16)wc->hCursor;
631 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
632 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
633 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
634 return atom;
638 /***********************************************************************
639 * UnregisterClass16 (USER.403)
641 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
643 CLASS *classPtr;
644 ATOM atom;
646 hInstance = GetExePtr( hInstance );
647 if (!(atom = GlobalFindAtom16( className ))) return FALSE;
648 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
649 (classPtr->hInstance != hInstance)) return FALSE;
650 return CLASS_FreeClass( classPtr );
654 /***********************************************************************
655 * UnregisterClass32A (USER32.563)
658 BOOL32 WINAPI UnregisterClass32A( LPCSTR className, HINSTANCE32 hInstance )
659 { CLASS *classPtr;
660 ATOM atom;
661 BOOL32 ret;
663 TRACE(class,"%s %x\n",className, hInstance);
665 if (!(atom = GlobalFindAtom32A( className )))
667 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
668 return FALSE;
670 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
671 (classPtr->hInstance != hInstance))
673 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
674 return FALSE;
676 if (!(ret = CLASS_FreeClass( classPtr )))
677 SetLastError(ERROR_CLASS_HAS_WINDOWS);
678 return ret;
681 /***********************************************************************
682 * UnregisterClass32W (USER32.564)
684 BOOL32 WINAPI UnregisterClass32W( LPCWSTR className, HINSTANCE32 hInstance )
685 { CLASS *classPtr;
686 ATOM atom;
687 BOOL32 ret;
689 TRACE(class,"%s %x\n",debugstr_w(className), hInstance);
691 if (!(atom = GlobalFindAtom32W( className )))
693 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
694 return FALSE;
696 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
697 (classPtr->hInstance != hInstance))
699 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
700 return FALSE;
702 if (!(ret = CLASS_FreeClass( classPtr )))
703 SetLastError(ERROR_CLASS_HAS_WINDOWS);
704 return ret;
707 /***********************************************************************
708 * GetClassWord16 (USER.129)
710 WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
712 return GetClassWord32( hwnd, offset );
716 /***********************************************************************
717 * GetClassWord32 (USER32.219)
719 WORD WINAPI GetClassWord32( HWND32 hwnd, INT32 offset )
721 WND * wndPtr;
723 TRACE(class,"%x %x\n",hwnd, offset);
725 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
726 if (offset >= 0)
728 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
729 return GET_WORD(((char *)wndPtr->class->wExtra) + offset);
731 else switch(offset)
733 case GCW_HBRBACKGROUND: return wndPtr->class->hbrBackground;
734 case GCW_HCURSOR: return wndPtr->class->hCursor;
735 case GCW_HICON: return wndPtr->class->hIcon;
736 case GCW_HICONSM: return wndPtr->class->hIconSm;
737 case GCW_ATOM: return wndPtr->class->atomName;
738 case GCW_STYLE:
739 case GCW_CBWNDEXTRA:
740 case GCW_CBCLSEXTRA:
741 case GCW_HMODULE:
742 return (WORD)GetClassLong32A( hwnd, offset );
745 WARN(class, "Invalid offset %d\n", offset);
746 return 0;
750 /***********************************************************************
751 * GetClassLong16 (USER.131)
753 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
755 WND *wndPtr;
756 LONG ret;
758 TRACE(class,"%x %x\n",hwnd, offset);
760 switch( offset )
762 case GCL_WNDPROC:
763 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
764 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
765 case GCL_MENUNAME:
766 ret = GetClassLong32A( hwnd, offset );
767 return (LONG)SEGPTR_GET( (void *)ret );
768 default:
769 return GetClassLong32A( hwnd, offset );
774 /***********************************************************************
775 * GetClassLong32A (USER32.215)
777 LONG WINAPI GetClassLong32A( HWND32 hwnd, INT32 offset )
779 WND * wndPtr;
781 TRACE(class,"%x %x\n",hwnd, offset);
783 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
784 if (offset >= 0)
786 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
787 return GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
789 switch(offset)
791 case GCL_STYLE: return (LONG)wndPtr->class->style;
792 case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
793 case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
794 case GCL_HMODULE: return (LONG)wndPtr->class->hInstance;
795 case GCL_WNDPROC:
796 return (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
797 case GCL_MENUNAME:
798 return (LONG)CLASS_GetMenuNameA( wndPtr->class );
799 case GCW_ATOM:
800 case GCL_HBRBACKGROUND:
801 case GCL_HCURSOR:
802 case GCL_HICON:
803 case GCL_HICONSM:
804 return GetClassWord32( hwnd, offset );
806 WARN(class, "Invalid offset %d\n", offset);
807 return 0;
811 /***********************************************************************
812 * GetClassLong32W (USER32.216)
814 LONG WINAPI GetClassLong32W( HWND32 hwnd, INT32 offset )
816 WND * wndPtr;
818 TRACE(class,"%x %x\n",hwnd, offset);
820 switch(offset)
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 );
834 /***********************************************************************
835 * SetClassWord16 (USER.130)
837 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
839 return SetClassWord32( hwnd, offset, newval );
843 /***********************************************************************
844 * SetClassWord32 (USER32.469)
846 WORD WINAPI SetClassWord32( HWND32 hwnd, INT32 offset, WORD newval )
848 WND * wndPtr;
849 WORD retval = 0;
850 void *ptr;
852 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
854 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
855 if (offset >= 0)
857 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
858 ptr = ((char *)wndPtr->class->wExtra) + offset;
859 else
861 WARN( class, "Invalid offset %d\n", offset );
862 return 0;
865 else switch(offset)
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;
881 retval = GET_WORD(ptr);
882 PUT_WORD( ptr, newval );
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)
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");
893 return retval;
897 /***********************************************************************
898 * SetClassLong16 (USER.132)
900 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
902 WND *wndPtr;
903 LONG retval;
905 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
907 switch(offset)
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 );
923 /***********************************************************************
924 * SetClassLong32A (USER32.467)
926 LONG WINAPI SetClassLong32A( HWND32 hwnd, INT32 offset, LONG newval )
928 WND * wndPtr;
929 LONG retval = 0;
930 void *ptr;
932 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
934 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
935 if (offset >= 0)
937 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
938 ptr = ((char *)wndPtr->class->wExtra) + offset;
939 else
941 WARN( class, "Invalid offset %d\n", offset );
942 return 0;
945 else switch(offset)
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;
969 retval = GET_DWORD(ptr);
970 PUT_DWORD( ptr, newval );
971 return retval;
975 /***********************************************************************
976 * SetClassLong32W (USER32.468)
978 LONG WINAPI SetClassLong32W( HWND32 hwnd, INT32 offset, LONG newval )
980 WND *wndPtr;
981 LONG retval;
983 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
985 switch(offset)
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 );
1003 /***********************************************************************
1004 * GetClassName16 (USER.58)
1006 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1008 WND *wndPtr;
1009 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1010 return GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1014 /***********************************************************************
1015 * GetClassName32A (USER32.217)
1017 INT32 WINAPI GetClassName32A( HWND32 hwnd, LPSTR buffer, INT32 count )
1018 { INT32 ret;
1019 WND *wndPtr;
1021 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1022 ret = GlobalGetAtomName32A( wndPtr->class->atomName, buffer, count );
1024 TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1025 return ret;
1029 /***********************************************************************
1030 * GetClassName32W (USER32.218)
1032 INT32 WINAPI GetClassName32W( HWND32 hwnd, LPWSTR buffer, INT32 count )
1033 { INT32 ret;
1034 WND *wndPtr;
1036 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1037 ret = GlobalGetAtomName32W( wndPtr->class->atomName, buffer, count );
1039 TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1041 return ret;
1045 /***********************************************************************
1046 * GetClassInfo16 (USER.404)
1048 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1049 WNDCLASS16 *wc )
1051 ATOM atom;
1052 CLASS *classPtr;
1054 TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1056 hInstance = GetExePtr( hInstance );
1057 if (!(atom = GlobalFindAtom16( name )) ||
1058 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1059 return FALSE;
1060 if ((hInstance != classPtr->hInstance) &&
1061 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1062 return FALSE;
1063 wc->style = (UINT16)classPtr->style;
1064 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1065 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1066 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1067 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1068 wc->hIcon = classPtr->hIcon;
1069 wc->hCursor = classPtr->hCursor;
1070 wc->hbrBackground = classPtr->hbrBackground;
1071 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1072 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1073 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1074 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1075 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1076 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1077 return TRUE;
1081 /***********************************************************************
1082 * GetClassInfo32A (USER32.211)
1084 BOOL32 WINAPI GetClassInfo32A( HINSTANCE32 hInstance, LPCSTR name,
1085 WNDCLASS32A *wc )
1087 ATOM atom;
1088 CLASS *classPtr;
1090 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1092 /* workaround: if hInstance=NULL you expect to get the system classes
1093 but this classes (as example from comctl32.dll SysListView) won't be
1094 registred with hInstance=NULL in WINE because of the late loading
1095 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1097 if (!(atom=GlobalFindAtom32A(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1098 return FALSE;
1100 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1102 if (hInstance) return FALSE;
1103 else
1104 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1107 wc->style = classPtr->style;
1108 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1109 WIN_PROC_32A );
1110 wc->cbClsExtra = classPtr->cbClsExtra;
1111 wc->cbWndExtra = classPtr->cbWndExtra;
1112 wc->hInstance = classPtr->hInstance;
1113 wc->hIcon = (HICON32)classPtr->hIcon;
1114 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1115 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1116 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1117 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1118 return TRUE;
1122 /***********************************************************************
1123 * GetClassInfo32W (USER32.214)
1125 BOOL32 WINAPI GetClassInfo32W( HINSTANCE32 hInstance, LPCWSTR name,
1126 WNDCLASS32W *wc )
1128 ATOM atom;
1129 CLASS *classPtr;
1131 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1133 if (!(atom = GlobalFindAtom32W( name )) ||
1134 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1135 (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1136 return FALSE;
1138 wc->style = classPtr->style;
1139 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1140 WIN_PROC_32W );
1141 wc->cbClsExtra = classPtr->cbClsExtra;
1142 wc->cbWndExtra = classPtr->cbWndExtra;
1143 wc->hInstance = classPtr->hInstance;
1144 wc->hIcon = (HICON32)classPtr->hIcon;
1145 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1146 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1147 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1148 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1149 return TRUE;
1153 /***********************************************************************
1154 * GetClassInfoEx16 (USER.398)
1156 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1157 * same in Win16 as in Win32. --AJ
1159 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1160 WNDCLASSEX16 *wc )
1162 ATOM atom;
1163 CLASS *classPtr;
1165 TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1167 hInstance = GetExePtr( hInstance );
1168 if (!(atom = GlobalFindAtom16( name )) ||
1169 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1170 (hInstance != classPtr->hInstance)) return FALSE;
1171 wc->style = classPtr->style;
1172 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1173 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1174 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1175 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1176 wc->hIcon = classPtr->hIcon;
1177 wc->hIconSm = classPtr->hIconSm;
1178 wc->hCursor = classPtr->hCursor;
1179 wc->hbrBackground = classPtr->hbrBackground;
1180 wc->lpszClassName = (SEGPTR)0;
1181 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1182 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1183 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1184 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1185 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1186 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1187 return TRUE;
1191 /***********************************************************************
1192 * GetClassInfoEx32A (USER32.212)
1194 BOOL32 WINAPI GetClassInfoEx32A( HINSTANCE32 hInstance, LPCSTR name,
1195 WNDCLASSEX32A *wc )
1197 ATOM atom;
1198 CLASS *classPtr;
1200 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1202 if (!(atom = GlobalFindAtom32A( name )) ||
1203 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1204 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1205 wc->style = classPtr->style;
1206 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1207 WIN_PROC_32A );
1208 wc->cbClsExtra = classPtr->cbClsExtra;
1209 wc->cbWndExtra = classPtr->cbWndExtra;
1210 wc->hInstance = classPtr->hInstance;
1211 wc->hIcon = (HICON32)classPtr->hIcon;
1212 wc->hIconSm = (HICON32)classPtr->hIconSm;
1213 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1214 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1215 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1216 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1217 return TRUE;
1221 /***********************************************************************
1222 * GetClassInfoEx32W (USER32.213)
1224 BOOL32 WINAPI GetClassInfoEx32W( HINSTANCE32 hInstance, LPCWSTR name,
1225 WNDCLASSEX32W *wc )
1227 ATOM atom;
1228 CLASS *classPtr;
1230 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1232 if (!(atom = GlobalFindAtom32W( name )) ||
1233 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1234 (hInstance != classPtr->hInstance)) return FALSE;
1235 wc->style = classPtr->style;
1236 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1237 WIN_PROC_32W );
1238 wc->cbClsExtra = classPtr->cbClsExtra;
1239 wc->cbWndExtra = classPtr->cbWndExtra;
1240 wc->hInstance = classPtr->hInstance;
1241 wc->hIcon = (HICON32)classPtr->hIcon;
1242 wc->hIconSm = (HICON32)classPtr->hIconSm;
1243 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1244 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1245 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1246 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1247 return TRUE;
1251 /***********************************************************************
1252 * ClassFirst (TOOLHELP.69)
1254 BOOL16 WINAPI ClassFirst( CLASSENTRY *pClassEntry )
1256 TRACE(class,"%p\n",pClassEntry);
1257 pClassEntry->wNext = 1;
1258 return ClassNext( pClassEntry );
1262 /***********************************************************************
1263 * ClassNext (TOOLHELP.70)
1265 BOOL16 WINAPI ClassNext( CLASSENTRY *pClassEntry )
1267 int i;
1268 CLASS *class = firstClass;
1270 TRACE(class,"%p\n",pClassEntry);
1272 if (!pClassEntry->wNext) return FALSE;
1273 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1274 if (!class)
1276 pClassEntry->wNext = 0;
1277 return FALSE;
1279 pClassEntry->hInst = class->hInstance;
1280 pClassEntry->wNext++;
1281 GlobalGetAtomName32A( class->atomName, pClassEntry->szClassName,
1282 sizeof(pClassEntry->szClassName) );
1283 return TRUE;