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 );
778 WARN("Invalid offset %d\n", offset);
780 WIN_ReleaseWndPtr(wndPtr);
785 /***********************************************************************
786 * GetClassLong16 (USER.131)
788 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
793 TRACE("%x %x\n",hwnd, offset);
798 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
799 ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
800 WIN_ReleaseWndPtr(wndPtr);
803 ret = GetClassLongA( hwnd, offset );
804 return (LONG)SEGPTR_GET( (void *)ret );
806 return GetClassLongA( hwnd, offset );
811 /***********************************************************************
812 * GetClassLong32A (USER32.215)
814 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
819 TRACE("%x %x\n",hwnd, offset);
821 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
824 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
826 retvalue = GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
833 case GCL_STYLE: retvalue = (LONG)wndPtr->class->style;
835 case GCL_CBWNDEXTRA: retvalue = (LONG)wndPtr->class->cbWndExtra;
837 case GCL_CBCLSEXTRA: retvalue = (LONG)wndPtr->class->cbClsExtra;
839 case GCL_HMODULE: retvalue = (LONG)wndPtr->class->hInstance;
842 retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
845 retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
848 case GCL_HBRBACKGROUND:
852 retvalue = GetClassWord( hwnd, offset );
855 WARN("Invalid offset %d\n", offset);
858 WIN_ReleaseWndPtr(wndPtr);
863 /***********************************************************************
864 * GetClassLong32W (USER32.216)
866 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
871 TRACE("%x %x\n",hwnd, offset);
876 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
877 retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
878 WIN_ReleaseWndPtr(wndPtr);
881 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
882 retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
883 WIN_ReleaseWndPtr(wndPtr);
886 return GetClassLongA( hwnd, offset );
891 /***********************************************************************
892 * SetClassWord16 (USER.130)
894 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
896 return SetClassWord( hwnd, offset, newval );
900 /***********************************************************************
901 * SetClassWord32 (USER32.469)
903 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
909 TRACE("%x %x %x\n",hwnd, offset, newval);
911 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
914 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
915 ptr = ((char *)wndPtr->class->wExtra) + offset;
918 WARN("Invalid offset %d\n", offset );
919 WIN_ReleaseWndPtr(wndPtr);
929 WIN_ReleaseWndPtr(wndPtr);
930 return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
931 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
932 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
933 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
934 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
935 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
937 WARN("Invalid offset %d\n", offset);
938 WIN_ReleaseWndPtr(wndPtr);
941 retval = GET_WORD(ptr);
942 PUT_WORD( ptr, newval );
944 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
945 need to be updated as well. Problem is that we can't tell whether the atom is
946 using wide or narrow characters. For now, we'll just NULL out the className
947 fields, and emit a FIXME. */
948 if (offset == GCW_ATOM)
950 CLASS_SetClassNameA( wndPtr->class, NULL );
951 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
953 WIN_ReleaseWndPtr(wndPtr);
958 /***********************************************************************
959 * SetClassLong16 (USER.132)
961 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
966 TRACE("%x %x %lx\n",hwnd, offset, newval);
971 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
972 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
973 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
974 WIN_PROC_16, WIN_PROC_CLASS );
975 WIN_ReleaseWndPtr(wndPtr);
978 return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
980 return SetClassLongA( hwnd, offset, newval );
985 /***********************************************************************
986 * SetClassLong32A (USER32.467)
988 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
994 TRACE("%x %x %lx\n",hwnd, offset, newval);
996 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
999 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
1000 ptr = ((char *)wndPtr->class->wExtra) + offset;
1003 WARN("Invalid offset %d\n", offset );
1011 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
1012 retval = 0; /* Old value is now meaningless anyway */
1015 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
1017 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
1018 WIN_PROC_32A, WIN_PROC_CLASS );
1020 case GCL_HBRBACKGROUND:
1024 retval = SetClassWord( hwnd, offset, (WORD)newval );
1026 case GCL_STYLE: ptr = &wndPtr->class->style; break;
1027 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
1028 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
1029 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
1031 WARN("Invalid offset %d\n", offset );
1035 retval = GET_DWORD(ptr);
1036 PUT_DWORD( ptr, newval );
1038 WIN_ReleaseWndPtr(wndPtr);
1043 /***********************************************************************
1044 * SetClassLong32W (USER32.468)
1046 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
1051 TRACE("%x %x %lx\n",hwnd, offset, newval);
1056 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1057 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
1058 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
1059 WIN_PROC_32W, WIN_PROC_CLASS );
1060 WIN_ReleaseWndPtr(wndPtr);
1063 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1064 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
1065 WIN_ReleaseWndPtr(wndPtr);
1066 return 0; /* Old value is now meaningless anyway */
1068 return SetClassLongA( hwnd, offset, newval );
1073 /***********************************************************************
1074 * GetClassName16 (USER.58)
1076 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1080 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1081 retvalue = GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1082 WIN_ReleaseWndPtr(wndPtr);
1087 /***********************************************************************
1088 * GetClassName32A (USER32.217)
1090 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1094 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1095 ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
1097 WIN_ReleaseWndPtr(wndPtr);
1098 TRACE("%x %s %x\n",hwnd, buffer, count);
1103 /***********************************************************************
1104 * GetClassName32W (USER32.218)
1106 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1110 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1111 ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
1112 WIN_ReleaseWndPtr(wndPtr);
1113 TRACE("%x %s %x\n",hwnd, debugstr_w(buffer), count);
1119 /***********************************************************************
1120 * GetClassInfo16 (USER.404)
1122 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1128 TRACE("%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1130 hInstance = GetExePtr( hInstance );
1131 if (!(atom = GlobalFindAtom16( name )) ||
1132 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1134 if ((hInstance != classPtr->hInstance) &&
1135 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1137 wc->style = (UINT16)classPtr->style;
1138 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1139 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1140 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1141 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1142 wc->hIcon = classPtr->hIcon;
1143 wc->hCursor = classPtr->hCursor;
1144 wc->hbrBackground = classPtr->hbrBackground;
1145 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1146 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1147 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1148 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1149 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1150 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1155 /***********************************************************************
1156 * GetClassInfo32A (USER32.211)
1158 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1164 TRACE("%x %p %p\n",hInstance, name, wc);
1166 /* workaround: if hInstance=NULL you expect to get the system classes
1167 but this classes (as example from comctl32.dll SysListView) won't be
1168 registred with hInstance=NULL in WINE because of the late loading
1169 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1171 if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1174 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1176 if (hInstance) return FALSE;
1178 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1181 wc->style = classPtr->style;
1182 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1184 wc->cbClsExtra = classPtr->cbClsExtra;
1185 wc->cbWndExtra = classPtr->cbWndExtra;
1186 wc->hInstance = classPtr->hInstance;
1187 wc->hIcon = (HICON)classPtr->hIcon;
1188 wc->hCursor = (HCURSOR)classPtr->hCursor;
1189 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1190 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1191 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1196 /***********************************************************************
1197 * GetClassInfo32W (USER32.214)
1199 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1205 TRACE("%x %p %p\n",hInstance, name, wc);
1207 if ( !(atom=GlobalFindAtomW(name)) ||
1208 !(classPtr=CLASS_FindClassByAtom(atom,hInstance))
1212 if (classPtr->hInstance && (hInstance != classPtr->hInstance)) {
1216 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name));
1218 wc->style = classPtr->style;
1219 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1221 wc->cbClsExtra = classPtr->cbClsExtra;
1222 wc->cbWndExtra = classPtr->cbWndExtra;
1223 wc->hInstance = classPtr->hInstance;
1224 wc->hIcon = (HICON)classPtr->hIcon;
1225 wc->hCursor = (HCURSOR)classPtr->hCursor;
1226 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1227 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1228 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1233 /***********************************************************************
1234 * GetClassInfoEx16 (USER.398)
1236 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1237 * same in Win16 as in Win32. --AJ
1239 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1245 TRACE("%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1247 hInstance = GetExePtr( hInstance );
1248 if (!(atom = GlobalFindAtom16( name )) ||
1249 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1250 (hInstance != classPtr->hInstance)) return FALSE;
1251 wc->style = classPtr->style;
1252 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1253 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1254 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1255 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1256 wc->hIcon = classPtr->hIcon;
1257 wc->hIconSm = classPtr->hIconSm;
1258 wc->hCursor = classPtr->hCursor;
1259 wc->hbrBackground = classPtr->hbrBackground;
1260 wc->lpszClassName = (SEGPTR)0;
1261 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1262 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1263 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1264 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1265 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1266 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1271 /***********************************************************************
1272 * GetClassInfoEx32A (USER32.212)
1274 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1280 TRACE("%x %p %p\n",hInstance, name, wc);
1282 if (!(atom = GlobalFindAtomA( name )) ||
1283 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1284 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1285 wc->style = classPtr->style;
1286 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1288 wc->cbClsExtra = classPtr->cbClsExtra;
1289 wc->cbWndExtra = classPtr->cbWndExtra;
1290 wc->hInstance = classPtr->hInstance;
1291 wc->hIcon = (HICON)classPtr->hIcon;
1292 wc->hIconSm = (HICON)classPtr->hIconSm;
1293 wc->hCursor = (HCURSOR)classPtr->hCursor;
1294 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1295 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1296 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1301 /***********************************************************************
1302 * GetClassInfoEx32W (USER32.213)
1304 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1310 TRACE("%x %p %p\n",hInstance, name, wc);
1312 if (!(atom = GlobalFindAtomW( name )) ||
1313 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1314 (hInstance != classPtr->hInstance)) return FALSE;
1315 wc->style = classPtr->style;
1316 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1318 wc->cbClsExtra = classPtr->cbClsExtra;
1319 wc->cbWndExtra = classPtr->cbWndExtra;
1320 wc->hInstance = classPtr->hInstance;
1321 wc->hIcon = (HICON)classPtr->hIcon;
1322 wc->hIconSm = (HICON)classPtr->hIconSm;
1323 wc->hCursor = (HCURSOR)classPtr->hCursor;
1324 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1325 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1326 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1331 /***********************************************************************
1332 * ClassFirst (TOOLHELP.69)
1334 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1336 TRACE("%p\n",pClassEntry);
1337 pClassEntry->wNext = 1;
1338 return ClassNext16( pClassEntry );
1342 /***********************************************************************
1343 * ClassNext (TOOLHELP.70)
1345 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1348 CLASS *class = firstClass;
1350 TRACE("%p\n",pClassEntry);
1352 if (!pClassEntry->wNext) return FALSE;
1353 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1356 pClassEntry->wNext = 0;
1359 pClassEntry->hInst = class->hInstance;
1360 pClassEntry->wNext++;
1361 GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1362 sizeof(pClassEntry->szClassName) );