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.
17 #include "wine/winbase16.h"
25 #include "debugtools.h"
29 #include "wine/winuser16.h"
31 DEFAULT_DEBUG_CHANNEL(class)
34 static CLASS *firstClass = NULL;
37 /***********************************************************************
40 * Dump the content of a class structure to stderr.
42 void CLASS_DumpClass( CLASS *ptr )
44 char className[MAX_CLASSNAME+1];
47 if (ptr->magic != CLASS_MAGIC)
49 DPRINTF("%p is not a class\n", ptr );
53 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
55 DPRINTF( "Class %p:\n", ptr );
56 DPRINTF( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
57 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
58 "clsExtra=%d winExtra=%d #windows=%d\n",
59 ptr->next, ptr->atomName, className, ptr->style,
60 (UINT)ptr->winproc, ptr->hInstance, (UINT)ptr->dce,
61 ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
62 ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
65 DPRINTF( "extra bytes:" );
66 for (i = 0; i < ptr->cbClsExtra; i++)
67 DPRINTF( " %02x", *((BYTE *)ptr->wExtra+i) );
74 /***********************************************************************
77 * Walk the class list and print each class on stderr.
79 void CLASS_WalkClasses(void)
82 char className[MAX_CLASSNAME+1];
84 DPRINTF( " Class Name Style WndProc\n" );
85 for (ptr = firstClass; ptr; ptr = ptr->next)
87 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
88 DPRINTF( "%08x %-20.20s %08x %08x\n", (UINT)ptr, className,
89 ptr->style, (UINT)ptr->winproc );
95 /***********************************************************************
98 * Get the menu name as a ASCII string.
100 static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
102 if (!classPtr->menuNameA && classPtr->menuNameW)
104 /* We need to copy the Unicode string */
105 classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
107 return classPtr->menuNameA;
111 /***********************************************************************
114 * Get the menu name as a Unicode string.
116 static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
118 if (!classPtr->menuNameW && classPtr->menuNameA)
120 if (!HIWORD(classPtr->menuNameA))
121 return (LPWSTR)classPtr->menuNameA;
122 /* Now we need to copy the ASCII string */
123 classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
124 classPtr->menuNameA );
126 return classPtr->menuNameW;
130 /***********************************************************************
133 * Set the menu name in a class structure by copying the string.
135 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
137 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
138 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
139 classPtr->menuNameA = SEGPTR_STRDUP( name );
140 classPtr->menuNameW = 0;
144 /***********************************************************************
147 * Set the menu name in a class structure by copying the string.
149 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
153 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
156 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
157 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
158 if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
159 (lstrlenW(name)+1)*sizeof(WCHAR) )))
160 lstrcpyW( classPtr->menuNameW, name );
161 classPtr->menuNameA = 0;
165 /***********************************************************************
166 * CLASS_GetClassNameA
168 * Get the clas name as a ASCII string.
170 static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
172 if (!classPtr->classNameA && classPtr->classNameW)
174 /* We need to copy the Unicode string */
175 classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
177 return classPtr->classNameA;
181 /***********************************************************************
182 * CLASS_GetClassNameW
184 * Get the class name as a Unicode string.
186 static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
188 if (!classPtr->classNameW && classPtr->classNameA)
190 if (!HIWORD(classPtr->classNameA))
191 return (LPWSTR)classPtr->classNameA;
192 /* Now we need to copy the ASCII string */
193 classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
194 classPtr->classNameA );
196 return classPtr->classNameW;
199 /***********************************************************************
200 * CLASS_SetClassNameA
202 * Set the class name in a class structure by copying the string.
204 static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
206 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
207 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
208 classPtr->classNameA = SEGPTR_STRDUP( name );
209 classPtr->classNameW = 0;
213 /***********************************************************************
214 * CLASS_SetClassNameW
216 * Set the class name in a class structure by copying the string.
218 static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
222 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
225 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
226 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
227 if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
228 (lstrlenW(name)+1)*sizeof(WCHAR) )))
229 lstrcpyW( classPtr->classNameW, name );
230 classPtr->classNameA = 0;
234 /***********************************************************************
237 * Free a class structure.
239 static BOOL CLASS_FreeClass( CLASS *classPtr )
242 TRACE("%p \n", classPtr);
244 /* Check if we can remove this class */
246 if (classPtr->cWindows > 0) return FALSE;
248 /* Remove the class from the linked list */
250 for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
251 if (*ppClass == classPtr) break;
254 ERR("Class list corrupted\n" );
257 *ppClass = classPtr->next;
259 /* Delete the class */
261 if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
262 if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
263 GlobalDeleteAtom( classPtr->atomName );
264 CLASS_SetMenuNameA( classPtr, NULL );
265 CLASS_SetClassNameA( classPtr, NULL );
266 WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
267 HeapFree( SystemHeap, 0, classPtr );
272 /***********************************************************************
273 * CLASS_FreeModuleClasses
275 void CLASS_FreeModuleClasses( HMODULE16 hModule )
279 TRACE("0x%08x \n", hModule);
281 for (ptr = firstClass; ptr; ptr = next)
284 if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
289 /***********************************************************************
290 * CLASS_FindClassByAtom
292 * Return a pointer to the class.
293 * hinstance has been normalized by the caller.
296 * 980805 a local class will be found now if registred with hInst=0
297 * and looed up with a hInst!=0. msmoney does it (jsch)
299 CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
300 { CLASS * class, *tclass=0;
302 TRACE("0x%08x 0x%08x\n", atom, hinstance);
304 /* First search task-specific classes */
306 for (class = firstClass; (class); class = class->next)
308 if (class->style & CS_GLOBALCLASS) continue;
309 if (class->atomName == atom)
311 if (hinstance==class->hInstance || hinstance==0xffff )
313 TRACE("-- found local %p\n", class);
316 if (class->hInstance==0) tclass = class;
320 /* Then search global classes */
322 for (class = firstClass; (class); class = class->next)
324 if (!(class->style & CS_GLOBALCLASS)) continue;
325 if (class->atomName == atom)
327 TRACE("-- found global %p\n", class);
332 /* Then check if there was a local class with hInst=0*/
335 WARN("-- found local Class registred with hInst=0\n");
339 TRACE("-- not found\n");
344 /***********************************************************************
345 * CLASS_RegisterClass
347 * The real RegisterClass() functionality.
349 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
350 DWORD style, INT classExtra,
351 INT winExtra, WNDPROC16 wndProc,
352 WINDOWPROCTYPE wndProcType )
356 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
357 atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
359 /* Check if a class with this name already exists */
360 classPtr = CLASS_FindClassByAtom( atom, hInstance );
363 /* Class can be created only if it is local and */
364 /* if the class with the same name is global. */
366 if (style & CS_GLOBALCLASS) return NULL;
367 if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
370 /* Fix the extra bytes value */
372 if (classExtra < 0) classExtra = 0;
373 else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
374 WARN("Class extra bytes %d is > 40\n", classExtra);
375 if (winExtra < 0) winExtra = 0;
376 else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
377 WARN("Win extra bytes %d is > 40\n", winExtra );
379 /* Create the class */
381 classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
382 classExtra - sizeof(classPtr->wExtra) );
383 if (!classPtr) return NULL;
384 classPtr->next = firstClass;
385 classPtr->magic = CLASS_MAGIC;
386 classPtr->cWindows = 0;
387 classPtr->style = style;
388 classPtr->winproc = (HWINDOWPROC)0;
389 classPtr->cbWndExtra = winExtra;
390 classPtr->cbClsExtra = classExtra;
391 classPtr->hInstance = hInstance;
392 classPtr->atomName = atom;
393 classPtr->menuNameA = 0;
394 classPtr->menuNameW = 0;
395 classPtr->classNameA = 0;
396 classPtr->classNameW = 0;
397 classPtr->dce = (style & CS_CLASSDC) ?
398 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
400 WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
402 /* Other values must be set by caller */
404 if (classExtra) memset( classPtr->wExtra, 0, classExtra );
405 firstClass = classPtr;
410 /***********************************************************************
411 * RegisterClass16 (USER.57)
413 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
417 int iSmIconWidth, iSmIconHeight;
418 HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
420 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
421 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
422 wc->cbClsExtra, wc->cbWndExtra,
423 wc->lpfnWndProc, WIN_PROC_16 )))
425 GlobalDeleteAtom( atom );
429 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
430 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
431 atom, (DWORD)wc->lpfnWndProc, hInstance,
432 wc->hbrBackground, wc->style, wc->cbClsExtra,
433 wc->cbWndExtra, classPtr,
434 HIWORD(wc->lpszClassName) ?
435 (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
437 iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
438 iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
440 classPtr->hIcon = wc->hIcon;
441 classPtr->hIconSm = CopyImage(wc->hIcon, IMAGE_ICON,
442 iSmIconWidth, iSmIconHeight,
443 LR_COPYFROMRESOURCE);
444 classPtr->hCursor = wc->hCursor;
445 classPtr->hbrBackground = wc->hbrBackground;
447 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
448 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
449 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
450 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
456 /***********************************************************************
457 * RegisterClass32A (USER32.427)
459 * >0: Unique identifier
462 ATOM WINAPI RegisterClassA(
463 const WNDCLASSA* wc /* Address of structure with class data */
466 int iSmIconWidth, iSmIconHeight;
469 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
471 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
474 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
475 wc->cbClsExtra, wc->cbWndExtra,
476 (WNDPROC16)wc->lpfnWndProc,
478 { GlobalDeleteAtom( atom );
479 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
483 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
484 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
485 wc->hbrBackground, wc->style, wc->cbClsExtra,
486 wc->cbWndExtra, classPtr,
487 HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
489 iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
490 iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
492 classPtr->hIcon = wc->hIcon;
493 classPtr->hIconSm = CopyImage(wc->hIcon, IMAGE_ICON,
494 iSmIconWidth, iSmIconHeight,
495 LR_COPYFROMRESOURCE);
496 classPtr->hCursor = (HCURSOR16)wc->hCursor;
497 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
499 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
500 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
505 /***********************************************************************
506 * RegisterClass32W (USER32.430)
508 ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
511 int iSmIconWidth, iSmIconHeight;
514 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
516 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
519 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
520 wc->cbClsExtra, wc->cbWndExtra,
521 (WNDPROC16)wc->lpfnWndProc,
524 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
525 GlobalDeleteAtom( atom );
529 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
530 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
531 wc->hbrBackground, wc->style, wc->cbClsExtra,
532 wc->cbWndExtra, classPtr );
534 iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
535 iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
537 classPtr->hIcon = wc->hIcon;
538 classPtr->hIconSm = CopyImage(wc->hIcon, IMAGE_ICON,
539 iSmIconWidth, iSmIconHeight,
540 LR_COPYFROMRESOURCE);
541 classPtr->hCursor = (HCURSOR16)wc->hCursor;
542 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
544 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
545 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
550 /***********************************************************************
551 * RegisterClassEx16 (USER.397)
553 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
557 HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
559 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
560 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
561 wc->cbClsExtra, wc->cbWndExtra,
562 wc->lpfnWndProc, WIN_PROC_16 )))
564 GlobalDeleteAtom( atom );
568 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
569 atom, (DWORD)wc->lpfnWndProc, hInstance,
570 wc->hbrBackground, wc->style, wc->cbClsExtra,
571 wc->cbWndExtra, classPtr );
573 classPtr->hIcon = wc->hIcon;
574 classPtr->hIconSm = wc->hIconSm;
575 classPtr->hCursor = wc->hCursor;
576 classPtr->hbrBackground = wc->hbrBackground;
578 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
579 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
580 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
581 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
586 /***********************************************************************
587 * RegisterClassEx32A (USER32.428)
589 ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
594 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
596 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
599 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
600 wc->cbClsExtra, wc->cbWndExtra,
601 (WNDPROC16)wc->lpfnWndProc,
604 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
605 GlobalDeleteAtom( atom );
609 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
610 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
611 wc->hbrBackground, wc->style, wc->cbClsExtra,
612 wc->cbWndExtra, classPtr );
614 classPtr->hIcon = (HICON16)wc->hIcon;
615 classPtr->hIconSm = (HICON16)wc->hIconSm;
616 classPtr->hCursor = (HCURSOR16)wc->hCursor;
617 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
618 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
619 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
624 /***********************************************************************
625 * RegisterClassEx32W (USER32.429)
627 ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
632 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
634 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
637 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
638 wc->cbClsExtra, wc->cbWndExtra,
639 (WNDPROC16)wc->lpfnWndProc,
642 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
643 GlobalDeleteAtom( atom );
647 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
648 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
649 wc->hbrBackground, wc->style, wc->cbClsExtra,
650 wc->cbWndExtra, classPtr );
652 classPtr->hIcon = (HICON16)wc->hIcon;
653 classPtr->hIconSm = (HICON16)wc->hIconSm;
654 classPtr->hCursor = (HCURSOR16)wc->hCursor;
655 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
656 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
657 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
662 /***********************************************************************
663 * UnregisterClass16 (USER.403)
665 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
670 hInstance = GetExePtr( hInstance );
671 if (!(atom = GlobalFindAtom16( className ))) return FALSE;
672 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
673 (classPtr->hInstance != hInstance)) return FALSE;
674 return CLASS_FreeClass( classPtr );
678 /***********************************************************************
679 * UnregisterClass32A (USER32.563)
682 BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
687 TRACE("%s %x\n",debugres_a(className), hInstance);
689 if (!(atom = GlobalFindAtomA( className )))
691 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
694 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
695 (classPtr->hInstance != hInstance))
697 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
700 if (!(ret = CLASS_FreeClass( classPtr )))
701 SetLastError(ERROR_CLASS_HAS_WINDOWS);
705 /***********************************************************************
706 * UnregisterClass32W (USER32.564)
708 BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
713 TRACE("%s %x\n",debugres_w(className), hInstance);
715 if (!(atom = GlobalFindAtomW( className )))
717 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
720 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
721 (classPtr->hInstance != hInstance))
723 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
726 if (!(ret = CLASS_FreeClass( classPtr )))
727 SetLastError(ERROR_CLASS_HAS_WINDOWS);
731 /***********************************************************************
732 * GetClassWord16 (USER.129)
734 WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
736 return GetClassWord( hwnd, offset );
740 /***********************************************************************
741 * GetClassWord32 (USER32.219)
743 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
748 TRACE("%x %x\n",hwnd, offset);
750 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
753 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
755 retvalue = GET_WORD(((char *)wndPtr->class->wExtra) + offset);
761 case GCW_HBRBACKGROUND: retvalue = wndPtr->class->hbrBackground;
763 case GCW_HCURSOR: retvalue = wndPtr->class->hCursor;
765 case GCW_HICON: retvalue = wndPtr->class->hIcon;
767 case GCW_HICONSM: retvalue = wndPtr->class->hIconSm;
769 case GCW_ATOM: retvalue = wndPtr->class->atomName;
775 retvalue = (WORD)GetClassLongA( hwnd, offset );
779 WARN("Invalid offset %d\n", offset);
781 WIN_ReleaseWndPtr(wndPtr);
786 /***********************************************************************
787 * GetClassLong16 (USER.131)
789 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
794 TRACE("%x %x\n",hwnd, offset);
799 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
800 ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
801 WIN_ReleaseWndPtr(wndPtr);
804 ret = GetClassLongA( hwnd, offset );
805 return (LONG)SEGPTR_GET( (void *)ret );
807 return GetClassLongA( hwnd, offset );
812 /***********************************************************************
813 * GetClassLong32A (USER32.215)
815 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
820 TRACE("%x %x\n",hwnd, offset);
822 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
825 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
827 retvalue = GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
834 case GCL_STYLE: retvalue = (LONG)wndPtr->class->style;
836 case GCL_CBWNDEXTRA: retvalue = (LONG)wndPtr->class->cbWndExtra;
838 case GCL_CBCLSEXTRA: retvalue = (LONG)wndPtr->class->cbClsExtra;
840 case GCL_HMODULE: retvalue = (LONG)wndPtr->class->hInstance;
843 retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
846 retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
849 case GCL_HBRBACKGROUND:
853 retvalue = GetClassWord( hwnd, offset );
856 WARN("Invalid offset %d\n", offset);
859 WIN_ReleaseWndPtr(wndPtr);
864 /***********************************************************************
865 * GetClassLong32W (USER32.216)
867 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
872 TRACE("%x %x\n",hwnd, offset);
877 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
878 retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
879 WIN_ReleaseWndPtr(wndPtr);
882 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
883 retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
884 WIN_ReleaseWndPtr(wndPtr);
887 return GetClassLongA( hwnd, offset );
892 /***********************************************************************
893 * SetClassWord16 (USER.130)
895 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
897 return SetClassWord( hwnd, offset, newval );
901 /***********************************************************************
902 * SetClassWord32 (USER32.469)
904 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
910 TRACE("%x %x %x\n",hwnd, offset, newval);
912 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
915 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
916 ptr = ((char *)wndPtr->class->wExtra) + offset;
919 WARN("Invalid offset %d\n", offset );
920 WIN_ReleaseWndPtr(wndPtr);
930 WIN_ReleaseWndPtr(wndPtr);
931 return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
932 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
933 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
934 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
935 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
936 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
938 WARN("Invalid offset %d\n", offset);
939 WIN_ReleaseWndPtr(wndPtr);
942 retval = GET_WORD(ptr);
943 PUT_WORD( ptr, newval );
945 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
946 need to be updated as well. Problem is that we can't tell whether the atom is
947 using wide or narrow characters. For now, we'll just NULL out the className
948 fields, and emit a FIXME. */
949 if (offset == GCW_ATOM)
951 CLASS_SetClassNameA( wndPtr->class, NULL );
952 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
954 WIN_ReleaseWndPtr(wndPtr);
959 /***********************************************************************
960 * SetClassLong16 (USER.132)
962 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
967 TRACE("%x %x %lx\n",hwnd, offset, newval);
972 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
973 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
974 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
975 WIN_PROC_16, WIN_PROC_CLASS );
976 WIN_ReleaseWndPtr(wndPtr);
979 return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
981 return SetClassLongA( hwnd, offset, newval );
986 /***********************************************************************
987 * SetClassLong32A (USER32.467)
989 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
995 TRACE("%x %x %lx\n",hwnd, offset, newval);
997 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
1000 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
1001 ptr = ((char *)wndPtr->class->wExtra) + offset;
1004 WARN("Invalid offset %d\n", offset );
1012 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
1013 retval = 0; /* Old value is now meaningless anyway */
1016 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
1018 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
1019 WIN_PROC_32A, WIN_PROC_CLASS );
1021 case GCL_HBRBACKGROUND:
1025 retval = SetClassWord( hwnd, offset, (WORD)newval );
1027 case GCL_STYLE: ptr = &wndPtr->class->style; break;
1028 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
1029 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
1030 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
1032 WARN("Invalid offset %d\n", offset );
1036 retval = GET_DWORD(ptr);
1037 PUT_DWORD( ptr, newval );
1039 WIN_ReleaseWndPtr(wndPtr);
1044 /***********************************************************************
1045 * SetClassLong32W (USER32.468)
1047 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
1052 TRACE("%x %x %lx\n",hwnd, offset, newval);
1057 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1058 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
1059 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
1060 WIN_PROC_32W, WIN_PROC_CLASS );
1061 WIN_ReleaseWndPtr(wndPtr);
1064 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1065 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
1066 WIN_ReleaseWndPtr(wndPtr);
1067 return 0; /* Old value is now meaningless anyway */
1069 return SetClassLongA( hwnd, offset, newval );
1074 /***********************************************************************
1075 * GetClassName16 (USER.58)
1077 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1081 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1082 retvalue = GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1083 WIN_ReleaseWndPtr(wndPtr);
1088 /***********************************************************************
1089 * GetClassName32A (USER32.217)
1091 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1095 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1096 ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
1098 WIN_ReleaseWndPtr(wndPtr);
1099 TRACE("%x %s %x\n",hwnd, buffer, count);
1104 /***********************************************************************
1105 * GetClassName32W (USER32.218)
1107 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1111 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1112 ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
1113 WIN_ReleaseWndPtr(wndPtr);
1114 TRACE("%x %s %x\n",hwnd, debugstr_w(buffer), count);
1120 /***********************************************************************
1121 * GetClassInfo16 (USER.404)
1123 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1129 TRACE("%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1131 hInstance = GetExePtr( hInstance );
1132 if (!(atom = GlobalFindAtom16( name )) ||
1133 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1135 if ((hInstance != classPtr->hInstance) &&
1136 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1138 wc->style = (UINT16)classPtr->style;
1139 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1140 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1141 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1142 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1143 wc->hIcon = classPtr->hIcon;
1144 wc->hCursor = classPtr->hCursor;
1145 wc->hbrBackground = classPtr->hbrBackground;
1146 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1147 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1148 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1149 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1150 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1151 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1156 /***********************************************************************
1157 * GetClassInfo32A (USER32.211)
1159 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1165 TRACE("%x %p %p\n",hInstance, name, wc);
1167 /* workaround: if hInstance=NULL you expect to get the system classes
1168 but this classes (as example from comctl32.dll SysListView) won't be
1169 registred with hInstance=NULL in WINE because of the late loading
1170 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1172 if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1175 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1177 if (hInstance) return FALSE;
1179 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1182 wc->style = classPtr->style;
1183 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1185 wc->cbClsExtra = classPtr->cbClsExtra;
1186 wc->cbWndExtra = classPtr->cbWndExtra;
1187 wc->hInstance = classPtr->hInstance;
1188 wc->hIcon = (HICON)classPtr->hIcon;
1189 wc->hCursor = (HCURSOR)classPtr->hCursor;
1190 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1191 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1192 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1197 /***********************************************************************
1198 * GetClassInfo32W (USER32.214)
1200 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1206 TRACE("%x %p %p\n",hInstance, name, wc);
1208 if ( !(atom=GlobalFindAtomW(name)) ||
1209 !(classPtr=CLASS_FindClassByAtom(atom,hInstance))
1213 if (classPtr->hInstance && (hInstance != classPtr->hInstance)) {
1217 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name));
1219 wc->style = classPtr->style;
1220 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1222 wc->cbClsExtra = classPtr->cbClsExtra;
1223 wc->cbWndExtra = classPtr->cbWndExtra;
1224 wc->hInstance = classPtr->hInstance;
1225 wc->hIcon = (HICON)classPtr->hIcon;
1226 wc->hCursor = (HCURSOR)classPtr->hCursor;
1227 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1228 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1229 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1234 /***********************************************************************
1235 * GetClassInfoEx16 (USER.398)
1237 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1238 * same in Win16 as in Win32. --AJ
1240 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1246 TRACE("%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1248 hInstance = GetExePtr( hInstance );
1249 if (!(atom = GlobalFindAtom16( name )) ||
1250 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1251 (hInstance != classPtr->hInstance)) return FALSE;
1252 wc->style = classPtr->style;
1253 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1254 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1255 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1256 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1257 wc->hIcon = classPtr->hIcon;
1258 wc->hIconSm = classPtr->hIconSm;
1259 wc->hCursor = classPtr->hCursor;
1260 wc->hbrBackground = classPtr->hbrBackground;
1261 wc->lpszClassName = (SEGPTR)0;
1262 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1263 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1264 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1265 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1266 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1267 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1272 /***********************************************************************
1273 * GetClassInfoEx32A (USER32.212)
1275 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1281 TRACE("%x %p %p\n",hInstance, name, wc);
1283 if (!(atom = GlobalFindAtomA( name )) ||
1284 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1285 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1286 wc->style = classPtr->style;
1287 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1289 wc->cbClsExtra = classPtr->cbClsExtra;
1290 wc->cbWndExtra = classPtr->cbWndExtra;
1291 wc->hInstance = classPtr->hInstance;
1292 wc->hIcon = (HICON)classPtr->hIcon;
1293 wc->hIconSm = (HICON)classPtr->hIconSm;
1294 wc->hCursor = (HCURSOR)classPtr->hCursor;
1295 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1296 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1297 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1302 /***********************************************************************
1303 * GetClassInfoEx32W (USER32.213)
1305 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1311 TRACE("%x %p %p\n",hInstance, name, wc);
1313 if (!(atom = GlobalFindAtomW( name )) ||
1314 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1315 (hInstance != classPtr->hInstance)) return FALSE;
1316 wc->style = classPtr->style;
1317 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1319 wc->cbClsExtra = classPtr->cbClsExtra;
1320 wc->cbWndExtra = classPtr->cbWndExtra;
1321 wc->hInstance = classPtr->hInstance;
1322 wc->hIcon = (HICON)classPtr->hIcon;
1323 wc->hIconSm = (HICON)classPtr->hIconSm;
1324 wc->hCursor = (HCURSOR)classPtr->hCursor;
1325 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1326 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1327 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1332 /***********************************************************************
1333 * ClassFirst (TOOLHELP.69)
1335 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1337 TRACE("%p\n",pClassEntry);
1338 pClassEntry->wNext = 1;
1339 return ClassNext16( pClassEntry );
1343 /***********************************************************************
1344 * ClassNext (TOOLHELP.70)
1346 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1349 CLASS *class = firstClass;
1351 TRACE("%p\n",pClassEntry);
1353 if (!pClassEntry->wNext) return FALSE;
1354 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1357 pClassEntry->wNext = 0;
1360 pClassEntry->hInst = class->hInstance;
1361 pClassEntry->wNext++;
1362 GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1363 sizeof(pClassEntry->szClassName) );