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"
27 #include "wine/winuser16.h"
30 static CLASS *firstClass = NULL;
33 /***********************************************************************
36 * Dump the content of a class structure to stderr.
38 void CLASS_DumpClass( CLASS *ptr )
40 char className[MAX_CLASSNAME+1];
43 if (ptr->magic != CLASS_MAGIC)
45 DUMP("%p is not a class\n", ptr );
49 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
51 DUMP( "Class %p:\n", ptr );
52 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
53 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
54 "clsExtra=%d winExtra=%d #windows=%d\n",
55 ptr->next, ptr->atomName, className, ptr->style,
56 (UINT)ptr->winproc, ptr->hInstance, (UINT)ptr->dce,
57 ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
58 ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
61 DUMP( "extra bytes:" );
62 for (i = 0; i < ptr->cbClsExtra; i++)
63 DUMP( " %02x", *((BYTE *)ptr->wExtra+i) );
70 /***********************************************************************
73 * Walk the class list and print each class on stderr.
75 void CLASS_WalkClasses(void)
78 char className[MAX_CLASSNAME+1];
80 DUMP( " Class Name Style WndProc\n" );
81 for (ptr = firstClass; ptr; ptr = ptr->next)
83 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
84 DUMP( "%08x %-20.20s %08x %08x\n", (UINT)ptr, className,
85 ptr->style, (UINT)ptr->winproc );
91 /***********************************************************************
94 * Get the menu name as a ASCII string.
96 static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
98 if (!classPtr->menuNameA && classPtr->menuNameW)
100 /* We need to copy the Unicode string */
101 classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
103 return classPtr->menuNameA;
107 /***********************************************************************
110 * Get the menu name as a Unicode string.
112 static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
114 if (!classPtr->menuNameW && classPtr->menuNameA)
116 if (!HIWORD(classPtr->menuNameA))
117 return (LPWSTR)classPtr->menuNameA;
118 /* Now we need to copy the ASCII string */
119 classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
120 classPtr->menuNameA );
122 return classPtr->menuNameW;
126 /***********************************************************************
129 * Set the menu name in a class structure by copying the string.
131 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
133 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
134 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
135 classPtr->menuNameA = SEGPTR_STRDUP( name );
136 classPtr->menuNameW = 0;
140 /***********************************************************************
143 * Set the menu name in a class structure by copying the string.
145 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
149 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
152 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
153 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
154 if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
155 (lstrlenW(name)+1)*sizeof(WCHAR) )))
156 lstrcpyW( classPtr->menuNameW, name );
157 classPtr->menuNameA = 0;
161 /***********************************************************************
162 * CLASS_GetClassNameA
164 * Get the clas name as a ASCII string.
166 static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
168 if (!classPtr->classNameA && classPtr->classNameW)
170 /* We need to copy the Unicode string */
171 classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
173 return classPtr->classNameA;
177 /***********************************************************************
178 * CLASS_GetClassNameW
180 * Get the class name as a Unicode string.
182 static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
184 if (!classPtr->classNameW && classPtr->classNameA)
186 if (!HIWORD(classPtr->classNameA))
187 return (LPWSTR)classPtr->classNameA;
188 /* Now we need to copy the ASCII string */
189 classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
190 classPtr->classNameA );
192 return classPtr->classNameW;
195 /***********************************************************************
196 * CLASS_SetClassNameA
198 * Set the class name in a class structure by copying the string.
200 static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
202 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
203 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
204 classPtr->classNameA = SEGPTR_STRDUP( name );
205 classPtr->classNameW = 0;
209 /***********************************************************************
210 * CLASS_SetClassNameW
212 * Set the class name in a class structure by copying the string.
214 static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
218 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
221 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
222 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
223 if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
224 (lstrlenW(name)+1)*sizeof(WCHAR) )))
225 lstrcpyW( classPtr->classNameW, name );
226 classPtr->classNameA = 0;
230 /***********************************************************************
233 * Free a class structure.
235 static BOOL CLASS_FreeClass( CLASS *classPtr )
238 TRACE(class,"%p \n", classPtr);
240 /* Check if we can remove this class */
242 if (classPtr->cWindows > 0) return FALSE;
244 /* Remove the class from the linked list */
246 for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
247 if (*ppClass == classPtr) break;
250 ERR( class, "Class list corrupted\n" );
253 *ppClass = classPtr->next;
255 /* Delete the class */
257 if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
258 if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
259 GlobalDeleteAtom( classPtr->atomName );
260 CLASS_SetMenuNameA( classPtr, NULL );
261 CLASS_SetClassNameA( classPtr, NULL );
262 WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
263 HeapFree( SystemHeap, 0, classPtr );
268 /***********************************************************************
269 * CLASS_FreeModuleClasses
271 void CLASS_FreeModuleClasses( HMODULE16 hModule )
275 TRACE(class,"0x%08x \n", hModule);
277 for (ptr = firstClass; ptr; ptr = next)
280 if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
285 /***********************************************************************
286 * CLASS_FindClassByAtom
288 * Return a pointer to the class.
289 * hinstance has been normalized by the caller.
292 * 980805 a local class will be found now if registred with hInst=0
293 * and looed up with a hInst!=0. msmoney does it (jsch)
295 CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
296 { CLASS * class, *tclass=0;
298 TRACE(class,"0x%08x 0x%08x\n", atom, hinstance);
300 /* First search task-specific classes */
302 for (class = firstClass; (class); class = class->next)
304 if (class->style & CS_GLOBALCLASS) continue;
305 if (class->atomName == atom)
307 if (hinstance==class->hInstance || hinstance==0xffff )
309 TRACE(class,"-- found local %p\n", class);
312 if (class->hInstance==0) tclass = class;
316 /* Then search global classes */
318 for (class = firstClass; (class); class = class->next)
320 if (!(class->style & CS_GLOBALCLASS)) continue;
321 if (class->atomName == atom)
323 TRACE(class,"-- found global %p\n", class);
328 /* Then check if there was a local class with hInst=0*/
331 WARN(class,"-- found local Class registred with hInst=0\n");
335 TRACE(class,"-- not found\n");
340 /***********************************************************************
341 * CLASS_RegisterClass
343 * The real RegisterClass() functionality.
345 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
346 DWORD style, INT classExtra,
347 INT winExtra, WNDPROC16 wndProc,
348 WINDOWPROCTYPE wndProcType )
352 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
353 atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
355 /* Check if a class with this name already exists */
356 classPtr = CLASS_FindClassByAtom( atom, hInstance );
359 /* Class can be created only if it is local and */
360 /* if the class with the same name is global. */
362 if (style & CS_GLOBALCLASS) return NULL;
363 if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
366 /* Fix the extra bytes value */
368 if (classExtra < 0) classExtra = 0;
369 else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
370 WARN(class, "Class extra bytes %d is > 40\n", classExtra);
371 if (winExtra < 0) winExtra = 0;
372 else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
373 WARN(class, "Win extra bytes %d is > 40\n", winExtra );
375 /* Create the class */
377 classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
378 classExtra - sizeof(classPtr->wExtra) );
379 if (!classPtr) return NULL;
380 classPtr->next = firstClass;
381 classPtr->magic = CLASS_MAGIC;
382 classPtr->cWindows = 0;
383 classPtr->style = style;
384 classPtr->winproc = (HWINDOWPROC)0;
385 classPtr->cbWndExtra = winExtra;
386 classPtr->cbClsExtra = classExtra;
387 classPtr->hInstance = hInstance;
388 classPtr->atomName = atom;
389 classPtr->menuNameA = 0;
390 classPtr->menuNameW = 0;
391 classPtr->classNameA = 0;
392 classPtr->classNameW = 0;
393 classPtr->dce = (style & CS_CLASSDC) ?
394 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
396 WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
398 /* Other values must be set by caller */
400 if (classExtra) memset( classPtr->wExtra, 0, classExtra );
401 firstClass = classPtr;
406 /***********************************************************************
407 * RegisterClass16 (USER.57)
409 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
413 HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
415 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
416 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
417 wc->cbClsExtra, wc->cbWndExtra,
418 wc->lpfnWndProc, WIN_PROC_16 )))
420 GlobalDeleteAtom( atom );
424 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
425 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
426 atom, (DWORD)wc->lpfnWndProc, hInstance,
427 wc->hbrBackground, wc->style, wc->cbClsExtra,
428 wc->cbWndExtra, classPtr,
429 HIWORD(wc->lpszClassName) ?
430 (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
432 classPtr->hIcon = wc->hIcon;
433 classPtr->hIconSm = 0;
434 classPtr->hCursor = wc->hCursor;
435 classPtr->hbrBackground = wc->hbrBackground;
437 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
438 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
439 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
440 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
446 /***********************************************************************
447 * RegisterClass32A (USER32.427)
449 * >0: Unique identifier
452 ATOM WINAPI RegisterClassA(
453 const WNDCLASSA* wc /* Address of structure with class data */
458 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
460 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
463 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
464 wc->cbClsExtra, wc->cbWndExtra,
465 (WNDPROC16)wc->lpfnWndProc,
467 { GlobalDeleteAtom( atom );
468 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
472 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
473 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
474 wc->hbrBackground, wc->style, wc->cbClsExtra,
475 wc->cbWndExtra, classPtr,
476 HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
478 classPtr->hIcon = (HICON16)wc->hIcon;
479 classPtr->hIconSm = 0;
480 classPtr->hCursor = (HCURSOR16)wc->hCursor;
481 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
483 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
484 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
489 /***********************************************************************
490 * RegisterClass32W (USER32.430)
492 ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
497 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
499 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
502 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
503 wc->cbClsExtra, wc->cbWndExtra,
504 (WNDPROC16)wc->lpfnWndProc,
507 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
508 GlobalDeleteAtom( atom );
512 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
513 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
514 wc->hbrBackground, wc->style, wc->cbClsExtra,
515 wc->cbWndExtra, classPtr );
517 classPtr->hIcon = (HICON16)wc->hIcon;
518 classPtr->hIconSm = 0;
519 classPtr->hCursor = (HCURSOR16)wc->hCursor;
520 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
522 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
523 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
528 /***********************************************************************
529 * RegisterClassEx16 (USER.397)
531 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
535 HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
537 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
538 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
539 wc->cbClsExtra, wc->cbWndExtra,
540 wc->lpfnWndProc, WIN_PROC_16 )))
542 GlobalDeleteAtom( atom );
546 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
547 atom, (DWORD)wc->lpfnWndProc, hInstance,
548 wc->hbrBackground, wc->style, wc->cbClsExtra,
549 wc->cbWndExtra, classPtr );
551 classPtr->hIcon = wc->hIcon;
552 classPtr->hIconSm = wc->hIconSm;
553 classPtr->hCursor = wc->hCursor;
554 classPtr->hbrBackground = wc->hbrBackground;
556 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
557 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
558 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
559 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
564 /***********************************************************************
565 * RegisterClassEx32A (USER32.428)
567 ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
572 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
574 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
577 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
578 wc->cbClsExtra, wc->cbWndExtra,
579 (WNDPROC16)wc->lpfnWndProc,
582 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
583 GlobalDeleteAtom( atom );
587 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
588 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
589 wc->hbrBackground, wc->style, wc->cbClsExtra,
590 wc->cbWndExtra, classPtr );
592 classPtr->hIcon = (HICON16)wc->hIcon;
593 classPtr->hIconSm = (HICON16)wc->hIconSm;
594 classPtr->hCursor = (HCURSOR16)wc->hCursor;
595 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
596 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
597 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
602 /***********************************************************************
603 * RegisterClassEx32W (USER32.429)
605 ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
610 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
612 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
615 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
616 wc->cbClsExtra, wc->cbWndExtra,
617 (WNDPROC16)wc->lpfnWndProc,
620 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
621 GlobalDeleteAtom( atom );
625 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
626 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
627 wc->hbrBackground, wc->style, wc->cbClsExtra,
628 wc->cbWndExtra, classPtr );
630 classPtr->hIcon = (HICON16)wc->hIcon;
631 classPtr->hIconSm = (HICON16)wc->hIconSm;
632 classPtr->hCursor = (HCURSOR16)wc->hCursor;
633 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
634 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
635 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
640 /***********************************************************************
641 * UnregisterClass16 (USER.403)
643 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
648 hInstance = GetExePtr( hInstance );
649 if (!(atom = GlobalFindAtom16( className ))) return FALSE;
650 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
651 (classPtr->hInstance != hInstance)) return FALSE;
652 return CLASS_FreeClass( classPtr );
656 /***********************************************************************
657 * UnregisterClass32A (USER32.563)
660 BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
665 TRACE(class,"%s %x\n",className, hInstance);
667 if (!(atom = GlobalFindAtomA( className )))
669 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
672 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
673 (classPtr->hInstance != hInstance))
675 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
678 if (!(ret = CLASS_FreeClass( classPtr )))
679 SetLastError(ERROR_CLASS_HAS_WINDOWS);
683 /***********************************************************************
684 * UnregisterClass32W (USER32.564)
686 BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
691 TRACE(class,"%s %x\n",debugstr_w(className), hInstance);
693 if (!(atom = GlobalFindAtomW( className )))
695 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
698 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
699 (classPtr->hInstance != hInstance))
701 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
704 if (!(ret = CLASS_FreeClass( classPtr )))
705 SetLastError(ERROR_CLASS_HAS_WINDOWS);
709 /***********************************************************************
710 * GetClassWord16 (USER.129)
712 WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
714 return GetClassWord( hwnd, offset );
718 /***********************************************************************
719 * GetClassWord32 (USER32.219)
721 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
725 TRACE(class,"%x %x\n",hwnd, offset);
727 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
730 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
732 WORD retvalue = GET_WORD(((char *)wndPtr->class->wExtra) + offset);
733 WIN_ReleaseWndPtr(wndPtr);
739 case GCW_HBRBACKGROUND: return wndPtr->class->hbrBackground;
740 case GCW_HCURSOR: return wndPtr->class->hCursor;
741 case GCW_HICON: return wndPtr->class->hIcon;
742 case GCW_HICONSM: return wndPtr->class->hIconSm;
743 case GCW_ATOM: return wndPtr->class->atomName;
748 WIN_ReleaseWndPtr(wndPtr);
749 return (WORD)GetClassLongA( hwnd, offset );
752 WIN_ReleaseWndPtr(wndPtr);
753 WARN(class, "Invalid offset %d\n", offset);
758 /***********************************************************************
759 * GetClassLong16 (USER.131)
761 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
766 TRACE(class,"%x %x\n",hwnd, offset);
771 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
772 ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
773 WIN_ReleaseWndPtr(wndPtr);
776 ret = GetClassLongA( hwnd, offset );
777 return (LONG)SEGPTR_GET( (void *)ret );
779 return GetClassLongA( hwnd, offset );
784 /***********************************************************************
785 * GetClassLong32A (USER32.215)
787 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
792 TRACE(class,"%x %x\n",hwnd, offset);
794 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
797 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
799 retvalue = GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
806 case GCL_STYLE: retvalue = (LONG)wndPtr->class->style;
808 case GCL_CBWNDEXTRA: retvalue = (LONG)wndPtr->class->cbWndExtra;
810 case GCL_CBCLSEXTRA: retvalue = (LONG)wndPtr->class->cbClsExtra;
812 case GCL_HMODULE: retvalue = (LONG)wndPtr->class->hInstance;
815 retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
818 retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
821 case GCL_HBRBACKGROUND:
825 retvalue = GetClassWord( hwnd, offset );
828 WARN(class, "Invalid offset %d\n", offset);
831 WIN_ReleaseWndPtr(wndPtr);
836 /***********************************************************************
837 * GetClassLong32W (USER32.216)
839 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
844 TRACE(class,"%x %x\n",hwnd, offset);
849 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
850 retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
851 WIN_ReleaseWndPtr(wndPtr);
854 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
855 retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
856 WIN_ReleaseWndPtr(wndPtr);
859 return GetClassLongA( hwnd, offset );
864 /***********************************************************************
865 * SetClassWord16 (USER.130)
867 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
869 return SetClassWord( hwnd, offset, newval );
873 /***********************************************************************
874 * SetClassWord32 (USER32.469)
876 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
882 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
884 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
887 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
888 ptr = ((char *)wndPtr->class->wExtra) + offset;
891 WARN( class, "Invalid offset %d\n", offset );
892 WIN_ReleaseWndPtr(wndPtr);
902 WIN_ReleaseWndPtr(wndPtr);
903 return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
904 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
905 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
906 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
907 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
908 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
910 WARN( class, "Invalid offset %d\n", offset);
911 WIN_ReleaseWndPtr(wndPtr);
914 retval = GET_WORD(ptr);
915 PUT_WORD( ptr, newval );
917 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
918 need to be updated as well. Problem is that we can't tell whether the atom is
919 using wide or narrow characters. For now, we'll just NULL out the className
920 fields, and emit a FIXME. */
921 if (offset == GCW_ATOM)
923 CLASS_SetClassNameA( wndPtr->class, NULL );
924 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
926 WIN_ReleaseWndPtr(wndPtr);
931 /***********************************************************************
932 * SetClassLong16 (USER.132)
934 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
939 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
944 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
945 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
946 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
947 WIN_PROC_16, WIN_PROC_CLASS );
948 WIN_ReleaseWndPtr(wndPtr);
951 return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
953 return SetClassLongA( hwnd, offset, newval );
958 /***********************************************************************
959 * SetClassLong32A (USER32.467)
961 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
967 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
969 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
972 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
973 ptr = ((char *)wndPtr->class->wExtra) + offset;
976 WARN( class, "Invalid offset %d\n", offset );
984 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
985 retval = 0; /* Old value is now meaningless anyway */
988 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
990 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
991 WIN_PROC_32A, WIN_PROC_CLASS );
993 case GCL_HBRBACKGROUND:
997 retval = SetClassWord( hwnd, offset, (WORD)newval );
999 case GCL_STYLE: ptr = &wndPtr->class->style; break;
1000 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
1001 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
1002 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
1004 WARN( class, "Invalid offset %d\n", offset );
1008 retval = GET_DWORD(ptr);
1009 PUT_DWORD( ptr, newval );
1011 WIN_ReleaseWndPtr(wndPtr);
1016 /***********************************************************************
1017 * SetClassLong32W (USER32.468)
1019 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
1024 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
1029 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1030 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
1031 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
1032 WIN_PROC_32W, WIN_PROC_CLASS );
1033 WIN_ReleaseWndPtr(wndPtr);
1036 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1037 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
1038 WIN_ReleaseWndPtr(wndPtr);
1039 return 0; /* Old value is now meaningless anyway */
1041 return SetClassLongA( hwnd, offset, newval );
1046 /***********************************************************************
1047 * GetClassName16 (USER.58)
1049 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1053 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1054 retvalue = GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1055 WIN_ReleaseWndPtr(wndPtr);
1060 /***********************************************************************
1061 * GetClassName32A (USER32.217)
1063 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1067 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1068 ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
1070 WIN_ReleaseWndPtr(wndPtr);
1071 TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1076 /***********************************************************************
1077 * GetClassName32W (USER32.218)
1079 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1083 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1084 ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
1085 WIN_ReleaseWndPtr(wndPtr);
1086 TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1092 /***********************************************************************
1093 * GetClassInfo16 (USER.404)
1095 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1101 TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1103 hInstance = GetExePtr( hInstance );
1104 if (!(atom = GlobalFindAtom16( name )) ||
1105 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1107 if ((hInstance != classPtr->hInstance) &&
1108 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1110 wc->style = (UINT16)classPtr->style;
1111 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1112 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1113 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1114 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1115 wc->hIcon = classPtr->hIcon;
1116 wc->hCursor = classPtr->hCursor;
1117 wc->hbrBackground = classPtr->hbrBackground;
1118 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1119 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1120 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1121 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1122 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1123 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1128 /***********************************************************************
1129 * GetClassInfo32A (USER32.211)
1131 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1137 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1139 /* workaround: if hInstance=NULL you expect to get the system classes
1140 but this classes (as example from comctl32.dll SysListView) won't be
1141 registred with hInstance=NULL in WINE because of the late loading
1142 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1144 if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1147 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1149 if (hInstance) return FALSE;
1151 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1154 wc->style = classPtr->style;
1155 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1157 wc->cbClsExtra = classPtr->cbClsExtra;
1158 wc->cbWndExtra = classPtr->cbWndExtra;
1159 wc->hInstance = classPtr->hInstance;
1160 wc->hIcon = (HICON)classPtr->hIcon;
1161 wc->hCursor = (HCURSOR)classPtr->hCursor;
1162 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1163 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1164 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1169 /***********************************************************************
1170 * GetClassInfo32W (USER32.214)
1172 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1178 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1180 if (!(atom = GlobalFindAtomW( name )) ||
1181 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1182 (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1185 wc->style = classPtr->style;
1186 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1188 wc->cbClsExtra = classPtr->cbClsExtra;
1189 wc->cbWndExtra = classPtr->cbWndExtra;
1190 wc->hInstance = classPtr->hInstance;
1191 wc->hIcon = (HICON)classPtr->hIcon;
1192 wc->hCursor = (HCURSOR)classPtr->hCursor;
1193 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1194 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1195 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1200 /***********************************************************************
1201 * GetClassInfoEx16 (USER.398)
1203 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1204 * same in Win16 as in Win32. --AJ
1206 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1212 TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1214 hInstance = GetExePtr( hInstance );
1215 if (!(atom = GlobalFindAtom16( name )) ||
1216 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1217 (hInstance != classPtr->hInstance)) return FALSE;
1218 wc->style = classPtr->style;
1219 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1220 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1221 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1222 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1223 wc->hIcon = classPtr->hIcon;
1224 wc->hIconSm = classPtr->hIconSm;
1225 wc->hCursor = classPtr->hCursor;
1226 wc->hbrBackground = classPtr->hbrBackground;
1227 wc->lpszClassName = (SEGPTR)0;
1228 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1229 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1230 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1231 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1232 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1233 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1238 /***********************************************************************
1239 * GetClassInfoEx32A (USER32.212)
1241 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1247 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1249 if (!(atom = GlobalFindAtomA( name )) ||
1250 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1251 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1252 wc->style = classPtr->style;
1253 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1255 wc->cbClsExtra = classPtr->cbClsExtra;
1256 wc->cbWndExtra = classPtr->cbWndExtra;
1257 wc->hInstance = classPtr->hInstance;
1258 wc->hIcon = (HICON)classPtr->hIcon;
1259 wc->hIconSm = (HICON)classPtr->hIconSm;
1260 wc->hCursor = (HCURSOR)classPtr->hCursor;
1261 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1262 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1263 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1268 /***********************************************************************
1269 * GetClassInfoEx32W (USER32.213)
1271 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1277 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1279 if (!(atom = GlobalFindAtomW( name )) ||
1280 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1281 (hInstance != classPtr->hInstance)) return FALSE;
1282 wc->style = classPtr->style;
1283 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1285 wc->cbClsExtra = classPtr->cbClsExtra;
1286 wc->cbWndExtra = classPtr->cbWndExtra;
1287 wc->hInstance = classPtr->hInstance;
1288 wc->hIcon = (HICON)classPtr->hIcon;
1289 wc->hIconSm = (HICON)classPtr->hIconSm;
1290 wc->hCursor = (HCURSOR)classPtr->hCursor;
1291 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1292 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1293 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1298 /***********************************************************************
1299 * ClassFirst (TOOLHELP.69)
1301 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1303 TRACE(class,"%p\n",pClassEntry);
1304 pClassEntry->wNext = 1;
1305 return ClassNext16( pClassEntry );
1309 /***********************************************************************
1310 * ClassNext (TOOLHELP.70)
1312 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1315 CLASS *class = firstClass;
1317 TRACE(class,"%p\n",pClassEntry);
1319 if (!pClassEntry->wNext) return FALSE;
1320 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1323 pClassEntry->wNext = 0;
1326 pClassEntry->hInst = class->hInstance;
1327 pClassEntry->wNext++;
1328 GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1329 sizeof(pClassEntry->szClassName) );