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"
29 DEFAULT_DEBUG_CHANNEL(class)
32 static CLASS *firstClass = NULL;
35 /***********************************************************************
38 * Dump the content of a class structure to stderr.
40 void CLASS_DumpClass( CLASS *ptr )
42 char className[MAX_CLASSNAME+1];
45 if (ptr->magic != CLASS_MAGIC)
47 DUMP("%p is not a class\n", ptr );
51 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
53 DUMP( "Class %p:\n", ptr );
54 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
55 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
56 "clsExtra=%d winExtra=%d #windows=%d\n",
57 ptr->next, ptr->atomName, className, ptr->style,
58 (UINT)ptr->winproc, ptr->hInstance, (UINT)ptr->dce,
59 ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
60 ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
63 DUMP( "extra bytes:" );
64 for (i = 0; i < ptr->cbClsExtra; i++)
65 DUMP( " %02x", *((BYTE *)ptr->wExtra+i) );
72 /***********************************************************************
75 * Walk the class list and print each class on stderr.
77 void CLASS_WalkClasses(void)
80 char className[MAX_CLASSNAME+1];
82 DUMP( " Class Name Style WndProc\n" );
83 for (ptr = firstClass; ptr; ptr = ptr->next)
85 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
86 DUMP( "%08x %-20.20s %08x %08x\n", (UINT)ptr, className,
87 ptr->style, (UINT)ptr->winproc );
93 /***********************************************************************
96 * Get the menu name as a ASCII string.
98 static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
100 if (!classPtr->menuNameA && classPtr->menuNameW)
102 /* We need to copy the Unicode string */
103 classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
105 return classPtr->menuNameA;
109 /***********************************************************************
112 * Get the menu name as a Unicode string.
114 static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
116 if (!classPtr->menuNameW && classPtr->menuNameA)
118 if (!HIWORD(classPtr->menuNameA))
119 return (LPWSTR)classPtr->menuNameA;
120 /* Now we need to copy the ASCII string */
121 classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
122 classPtr->menuNameA );
124 return classPtr->menuNameW;
128 /***********************************************************************
131 * Set the menu name in a class structure by copying the string.
133 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
135 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
136 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
137 classPtr->menuNameA = SEGPTR_STRDUP( name );
138 classPtr->menuNameW = 0;
142 /***********************************************************************
145 * Set the menu name in a class structure by copying the string.
147 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
151 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
154 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
155 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
156 if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
157 (lstrlenW(name)+1)*sizeof(WCHAR) )))
158 lstrcpyW( classPtr->menuNameW, name );
159 classPtr->menuNameA = 0;
163 /***********************************************************************
164 * CLASS_GetClassNameA
166 * Get the clas name as a ASCII string.
168 static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
170 if (!classPtr->classNameA && classPtr->classNameW)
172 /* We need to copy the Unicode string */
173 classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
175 return classPtr->classNameA;
179 /***********************************************************************
180 * CLASS_GetClassNameW
182 * Get the class name as a Unicode string.
184 static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
186 if (!classPtr->classNameW && classPtr->classNameA)
188 if (!HIWORD(classPtr->classNameA))
189 return (LPWSTR)classPtr->classNameA;
190 /* Now we need to copy the ASCII string */
191 classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
192 classPtr->classNameA );
194 return classPtr->classNameW;
197 /***********************************************************************
198 * CLASS_SetClassNameA
200 * Set the class name in a class structure by copying the string.
202 static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
204 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
205 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
206 classPtr->classNameA = SEGPTR_STRDUP( name );
207 classPtr->classNameW = 0;
211 /***********************************************************************
212 * CLASS_SetClassNameW
214 * Set the class name in a class structure by copying the string.
216 static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
220 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
223 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
224 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
225 if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
226 (lstrlenW(name)+1)*sizeof(WCHAR) )))
227 lstrcpyW( classPtr->classNameW, name );
228 classPtr->classNameA = 0;
232 /***********************************************************************
235 * Free a class structure.
237 static BOOL CLASS_FreeClass( CLASS *classPtr )
240 TRACE(class,"%p \n", classPtr);
242 /* Check if we can remove this class */
244 if (classPtr->cWindows > 0) return FALSE;
246 /* Remove the class from the linked list */
248 for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
249 if (*ppClass == classPtr) break;
252 ERR( class, "Class list corrupted\n" );
255 *ppClass = classPtr->next;
257 /* Delete the class */
259 if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
260 if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
261 GlobalDeleteAtom( classPtr->atomName );
262 CLASS_SetMenuNameA( classPtr, NULL );
263 CLASS_SetClassNameA( classPtr, NULL );
264 WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
265 HeapFree( SystemHeap, 0, classPtr );
270 /***********************************************************************
271 * CLASS_FreeModuleClasses
273 void CLASS_FreeModuleClasses( HMODULE16 hModule )
277 TRACE(class,"0x%08x \n", hModule);
279 for (ptr = firstClass; ptr; ptr = next)
282 if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
287 /***********************************************************************
288 * CLASS_FindClassByAtom
290 * Return a pointer to the class.
291 * hinstance has been normalized by the caller.
294 * 980805 a local class will be found now if registred with hInst=0
295 * and looed up with a hInst!=0. msmoney does it (jsch)
297 CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
298 { CLASS * class, *tclass=0;
300 TRACE(class,"0x%08x 0x%08x\n", atom, hinstance);
302 /* First search task-specific classes */
304 for (class = firstClass; (class); class = class->next)
306 if (class->style & CS_GLOBALCLASS) continue;
307 if (class->atomName == atom)
309 if (hinstance==class->hInstance || hinstance==0xffff )
311 TRACE(class,"-- found local %p\n", class);
314 if (class->hInstance==0) tclass = class;
318 /* Then search global classes */
320 for (class = firstClass; (class); class = class->next)
322 if (!(class->style & CS_GLOBALCLASS)) continue;
323 if (class->atomName == atom)
325 TRACE(class,"-- found global %p\n", class);
330 /* Then check if there was a local class with hInst=0*/
333 WARN(class,"-- found local Class registred with hInst=0\n");
337 TRACE(class,"-- not found\n");
342 /***********************************************************************
343 * CLASS_RegisterClass
345 * The real RegisterClass() functionality.
347 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
348 DWORD style, INT classExtra,
349 INT winExtra, WNDPROC16 wndProc,
350 WINDOWPROCTYPE wndProcType )
354 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
355 atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
357 /* Check if a class with this name already exists */
358 classPtr = CLASS_FindClassByAtom( atom, hInstance );
361 /* Class can be created only if it is local and */
362 /* if the class with the same name is global. */
364 if (style & CS_GLOBALCLASS) return NULL;
365 if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
368 /* Fix the extra bytes value */
370 if (classExtra < 0) classExtra = 0;
371 else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
372 WARN(class, "Class extra bytes %d is > 40\n", classExtra);
373 if (winExtra < 0) winExtra = 0;
374 else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
375 WARN(class, "Win extra bytes %d is > 40\n", winExtra );
377 /* Create the class */
379 classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
380 classExtra - sizeof(classPtr->wExtra) );
381 if (!classPtr) return NULL;
382 classPtr->next = firstClass;
383 classPtr->magic = CLASS_MAGIC;
384 classPtr->cWindows = 0;
385 classPtr->style = style;
386 classPtr->winproc = (HWINDOWPROC)0;
387 classPtr->cbWndExtra = winExtra;
388 classPtr->cbClsExtra = classExtra;
389 classPtr->hInstance = hInstance;
390 classPtr->atomName = atom;
391 classPtr->menuNameA = 0;
392 classPtr->menuNameW = 0;
393 classPtr->classNameA = 0;
394 classPtr->classNameW = 0;
395 classPtr->dce = (style & CS_CLASSDC) ?
396 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
398 WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
400 /* Other values must be set by caller */
402 if (classExtra) memset( classPtr->wExtra, 0, classExtra );
403 firstClass = classPtr;
408 /***********************************************************************
409 * RegisterClass16 (USER.57)
411 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
415 HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
417 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
418 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
419 wc->cbClsExtra, wc->cbWndExtra,
420 wc->lpfnWndProc, WIN_PROC_16 )))
422 GlobalDeleteAtom( atom );
426 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
427 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
428 atom, (DWORD)wc->lpfnWndProc, hInstance,
429 wc->hbrBackground, wc->style, wc->cbClsExtra,
430 wc->cbWndExtra, classPtr,
431 HIWORD(wc->lpszClassName) ?
432 (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
434 classPtr->hIcon = wc->hIcon;
435 classPtr->hIconSm = 0;
436 classPtr->hCursor = wc->hCursor;
437 classPtr->hbrBackground = wc->hbrBackground;
439 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
440 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
441 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
442 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
448 /***********************************************************************
449 * RegisterClass32A (USER32.427)
451 * >0: Unique identifier
454 ATOM WINAPI RegisterClassA(
455 const WNDCLASSA* wc /* Address of structure with class data */
460 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
462 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
465 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
466 wc->cbClsExtra, wc->cbWndExtra,
467 (WNDPROC16)wc->lpfnWndProc,
469 { GlobalDeleteAtom( atom );
470 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
474 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
475 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
476 wc->hbrBackground, wc->style, wc->cbClsExtra,
477 wc->cbWndExtra, classPtr,
478 HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
480 classPtr->hIcon = (HICON16)wc->hIcon;
481 classPtr->hIconSm = 0;
482 classPtr->hCursor = (HCURSOR16)wc->hCursor;
483 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
485 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
486 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
491 /***********************************************************************
492 * RegisterClass32W (USER32.430)
494 ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
499 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
501 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
504 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
505 wc->cbClsExtra, wc->cbWndExtra,
506 (WNDPROC16)wc->lpfnWndProc,
509 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
510 GlobalDeleteAtom( atom );
514 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
515 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
516 wc->hbrBackground, wc->style, wc->cbClsExtra,
517 wc->cbWndExtra, classPtr );
519 classPtr->hIcon = (HICON16)wc->hIcon;
520 classPtr->hIconSm = 0;
521 classPtr->hCursor = (HCURSOR16)wc->hCursor;
522 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
524 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
525 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
530 /***********************************************************************
531 * RegisterClassEx16 (USER.397)
533 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
537 HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
539 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
540 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
541 wc->cbClsExtra, wc->cbWndExtra,
542 wc->lpfnWndProc, WIN_PROC_16 )))
544 GlobalDeleteAtom( atom );
548 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
549 atom, (DWORD)wc->lpfnWndProc, hInstance,
550 wc->hbrBackground, wc->style, wc->cbClsExtra,
551 wc->cbWndExtra, classPtr );
553 classPtr->hIcon = wc->hIcon;
554 classPtr->hIconSm = wc->hIconSm;
555 classPtr->hCursor = wc->hCursor;
556 classPtr->hbrBackground = wc->hbrBackground;
558 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
559 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
560 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
561 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
566 /***********************************************************************
567 * RegisterClassEx32A (USER32.428)
569 ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
574 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
576 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
579 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
580 wc->cbClsExtra, wc->cbWndExtra,
581 (WNDPROC16)wc->lpfnWndProc,
584 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
585 GlobalDeleteAtom( atom );
589 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
590 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
591 wc->hbrBackground, wc->style, wc->cbClsExtra,
592 wc->cbWndExtra, classPtr );
594 classPtr->hIcon = (HICON16)wc->hIcon;
595 classPtr->hIconSm = (HICON16)wc->hIconSm;
596 classPtr->hCursor = (HCURSOR16)wc->hCursor;
597 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
598 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
599 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
604 /***********************************************************************
605 * RegisterClassEx32W (USER32.429)
607 ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
612 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
614 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
617 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
618 wc->cbClsExtra, wc->cbWndExtra,
619 (WNDPROC16)wc->lpfnWndProc,
622 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
623 GlobalDeleteAtom( atom );
627 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
628 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
629 wc->hbrBackground, wc->style, wc->cbClsExtra,
630 wc->cbWndExtra, classPtr );
632 classPtr->hIcon = (HICON16)wc->hIcon;
633 classPtr->hIconSm = (HICON16)wc->hIconSm;
634 classPtr->hCursor = (HCURSOR16)wc->hCursor;
635 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
636 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
637 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
642 /***********************************************************************
643 * UnregisterClass16 (USER.403)
645 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
650 hInstance = GetExePtr( hInstance );
651 if (!(atom = GlobalFindAtom16( className ))) return FALSE;
652 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
653 (classPtr->hInstance != hInstance)) return FALSE;
654 return CLASS_FreeClass( classPtr );
658 /***********************************************************************
659 * UnregisterClass32A (USER32.563)
662 BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
667 TRACE(class,"%s %x\n",className, hInstance);
669 if (!(atom = GlobalFindAtomA( className )))
671 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
674 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
675 (classPtr->hInstance != hInstance))
677 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
680 if (!(ret = CLASS_FreeClass( classPtr )))
681 SetLastError(ERROR_CLASS_HAS_WINDOWS);
685 /***********************************************************************
686 * UnregisterClass32W (USER32.564)
688 BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
693 TRACE(class,"%s %x\n",debugstr_w(className), hInstance);
695 if (!(atom = GlobalFindAtomW( className )))
697 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
700 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
701 (classPtr->hInstance != hInstance))
703 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
706 if (!(ret = CLASS_FreeClass( classPtr )))
707 SetLastError(ERROR_CLASS_HAS_WINDOWS);
711 /***********************************************************************
712 * GetClassWord16 (USER.129)
714 WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
716 return GetClassWord( hwnd, offset );
720 /***********************************************************************
721 * GetClassWord32 (USER32.219)
723 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
727 TRACE(class,"%x %x\n",hwnd, offset);
729 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
732 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
734 WORD retvalue = GET_WORD(((char *)wndPtr->class->wExtra) + offset);
735 WIN_ReleaseWndPtr(wndPtr);
741 case GCW_HBRBACKGROUND: return wndPtr->class->hbrBackground;
742 case GCW_HCURSOR: return wndPtr->class->hCursor;
743 case GCW_HICON: return wndPtr->class->hIcon;
744 case GCW_HICONSM: return wndPtr->class->hIconSm;
745 case GCW_ATOM: return wndPtr->class->atomName;
750 WIN_ReleaseWndPtr(wndPtr);
751 return (WORD)GetClassLongA( hwnd, offset );
754 WIN_ReleaseWndPtr(wndPtr);
755 WARN(class, "Invalid offset %d\n", offset);
760 /***********************************************************************
761 * GetClassLong16 (USER.131)
763 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
768 TRACE(class,"%x %x\n",hwnd, offset);
773 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
774 ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
775 WIN_ReleaseWndPtr(wndPtr);
778 ret = GetClassLongA( hwnd, offset );
779 return (LONG)SEGPTR_GET( (void *)ret );
781 return GetClassLongA( hwnd, offset );
786 /***********************************************************************
787 * GetClassLong32A (USER32.215)
789 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
794 TRACE(class,"%x %x\n",hwnd, offset);
796 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
799 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
801 retvalue = GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
808 case GCL_STYLE: retvalue = (LONG)wndPtr->class->style;
810 case GCL_CBWNDEXTRA: retvalue = (LONG)wndPtr->class->cbWndExtra;
812 case GCL_CBCLSEXTRA: retvalue = (LONG)wndPtr->class->cbClsExtra;
814 case GCL_HMODULE: retvalue = (LONG)wndPtr->class->hInstance;
817 retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
820 retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
823 case GCL_HBRBACKGROUND:
827 retvalue = GetClassWord( hwnd, offset );
830 WARN(class, "Invalid offset %d\n", offset);
833 WIN_ReleaseWndPtr(wndPtr);
838 /***********************************************************************
839 * GetClassLong32W (USER32.216)
841 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
846 TRACE(class,"%x %x\n",hwnd, offset);
851 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
852 retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
853 WIN_ReleaseWndPtr(wndPtr);
856 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
857 retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
858 WIN_ReleaseWndPtr(wndPtr);
861 return GetClassLongA( hwnd, offset );
866 /***********************************************************************
867 * SetClassWord16 (USER.130)
869 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
871 return SetClassWord( hwnd, offset, newval );
875 /***********************************************************************
876 * SetClassWord32 (USER32.469)
878 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
884 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
886 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
889 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
890 ptr = ((char *)wndPtr->class->wExtra) + offset;
893 WARN( class, "Invalid offset %d\n", offset );
894 WIN_ReleaseWndPtr(wndPtr);
904 WIN_ReleaseWndPtr(wndPtr);
905 return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
906 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
907 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
908 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
909 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
910 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
912 WARN( class, "Invalid offset %d\n", offset);
913 WIN_ReleaseWndPtr(wndPtr);
916 retval = GET_WORD(ptr);
917 PUT_WORD( ptr, newval );
919 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
920 need to be updated as well. Problem is that we can't tell whether the atom is
921 using wide or narrow characters. For now, we'll just NULL out the className
922 fields, and emit a FIXME. */
923 if (offset == GCW_ATOM)
925 CLASS_SetClassNameA( wndPtr->class, NULL );
926 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
928 WIN_ReleaseWndPtr(wndPtr);
933 /***********************************************************************
934 * SetClassLong16 (USER.132)
936 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
941 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
946 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
947 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
948 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
949 WIN_PROC_16, WIN_PROC_CLASS );
950 WIN_ReleaseWndPtr(wndPtr);
953 return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
955 return SetClassLongA( hwnd, offset, newval );
960 /***********************************************************************
961 * SetClassLong32A (USER32.467)
963 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
969 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
971 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
974 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
975 ptr = ((char *)wndPtr->class->wExtra) + offset;
978 WARN( class, "Invalid offset %d\n", offset );
986 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
987 retval = 0; /* Old value is now meaningless anyway */
990 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
992 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
993 WIN_PROC_32A, WIN_PROC_CLASS );
995 case GCL_HBRBACKGROUND:
999 retval = SetClassWord( hwnd, offset, (WORD)newval );
1001 case GCL_STYLE: ptr = &wndPtr->class->style; break;
1002 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
1003 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
1004 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
1006 WARN( class, "Invalid offset %d\n", offset );
1010 retval = GET_DWORD(ptr);
1011 PUT_DWORD( ptr, newval );
1013 WIN_ReleaseWndPtr(wndPtr);
1018 /***********************************************************************
1019 * SetClassLong32W (USER32.468)
1021 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
1026 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
1031 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1032 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
1033 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
1034 WIN_PROC_32W, WIN_PROC_CLASS );
1035 WIN_ReleaseWndPtr(wndPtr);
1038 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1039 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
1040 WIN_ReleaseWndPtr(wndPtr);
1041 return 0; /* Old value is now meaningless anyway */
1043 return SetClassLongA( hwnd, offset, newval );
1048 /***********************************************************************
1049 * GetClassName16 (USER.58)
1051 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1055 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1056 retvalue = GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1057 WIN_ReleaseWndPtr(wndPtr);
1062 /***********************************************************************
1063 * GetClassName32A (USER32.217)
1065 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1069 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1070 ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
1072 WIN_ReleaseWndPtr(wndPtr);
1073 TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1078 /***********************************************************************
1079 * GetClassName32W (USER32.218)
1081 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1085 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1086 ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
1087 WIN_ReleaseWndPtr(wndPtr);
1088 TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1094 /***********************************************************************
1095 * GetClassInfo16 (USER.404)
1097 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1103 TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1105 hInstance = GetExePtr( hInstance );
1106 if (!(atom = GlobalFindAtom16( name )) ||
1107 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1109 if ((hInstance != classPtr->hInstance) &&
1110 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1112 wc->style = (UINT16)classPtr->style;
1113 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1114 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1115 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1116 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1117 wc->hIcon = classPtr->hIcon;
1118 wc->hCursor = classPtr->hCursor;
1119 wc->hbrBackground = classPtr->hbrBackground;
1120 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1121 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1122 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1123 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1124 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1125 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1130 /***********************************************************************
1131 * GetClassInfo32A (USER32.211)
1133 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1139 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1141 /* workaround: if hInstance=NULL you expect to get the system classes
1142 but this classes (as example from comctl32.dll SysListView) won't be
1143 registred with hInstance=NULL in WINE because of the late loading
1144 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1146 if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1149 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1151 if (hInstance) return FALSE;
1153 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1156 wc->style = classPtr->style;
1157 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1159 wc->cbClsExtra = classPtr->cbClsExtra;
1160 wc->cbWndExtra = classPtr->cbWndExtra;
1161 wc->hInstance = classPtr->hInstance;
1162 wc->hIcon = (HICON)classPtr->hIcon;
1163 wc->hCursor = (HCURSOR)classPtr->hCursor;
1164 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1165 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1166 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1171 /***********************************************************************
1172 * GetClassInfo32W (USER32.214)
1174 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1180 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1182 if (!(atom = GlobalFindAtomW( name )) ||
1183 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1184 (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1187 wc->style = classPtr->style;
1188 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1190 wc->cbClsExtra = classPtr->cbClsExtra;
1191 wc->cbWndExtra = classPtr->cbWndExtra;
1192 wc->hInstance = classPtr->hInstance;
1193 wc->hIcon = (HICON)classPtr->hIcon;
1194 wc->hCursor = (HCURSOR)classPtr->hCursor;
1195 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1196 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1197 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1202 /***********************************************************************
1203 * GetClassInfoEx16 (USER.398)
1205 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1206 * same in Win16 as in Win32. --AJ
1208 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1214 TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1216 hInstance = GetExePtr( hInstance );
1217 if (!(atom = GlobalFindAtom16( name )) ||
1218 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1219 (hInstance != classPtr->hInstance)) return FALSE;
1220 wc->style = classPtr->style;
1221 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1222 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1223 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1224 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1225 wc->hIcon = classPtr->hIcon;
1226 wc->hIconSm = classPtr->hIconSm;
1227 wc->hCursor = classPtr->hCursor;
1228 wc->hbrBackground = classPtr->hbrBackground;
1229 wc->lpszClassName = (SEGPTR)0;
1230 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1231 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1232 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1233 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1234 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1235 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1240 /***********************************************************************
1241 * GetClassInfoEx32A (USER32.212)
1243 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1249 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1251 if (!(atom = GlobalFindAtomA( name )) ||
1252 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1253 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1254 wc->style = classPtr->style;
1255 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1257 wc->cbClsExtra = classPtr->cbClsExtra;
1258 wc->cbWndExtra = classPtr->cbWndExtra;
1259 wc->hInstance = classPtr->hInstance;
1260 wc->hIcon = (HICON)classPtr->hIcon;
1261 wc->hIconSm = (HICON)classPtr->hIconSm;
1262 wc->hCursor = (HCURSOR)classPtr->hCursor;
1263 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1264 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1265 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1270 /***********************************************************************
1271 * GetClassInfoEx32W (USER32.213)
1273 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1279 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1281 if (!(atom = GlobalFindAtomW( name )) ||
1282 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1283 (hInstance != classPtr->hInstance)) return FALSE;
1284 wc->style = classPtr->style;
1285 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1287 wc->cbClsExtra = classPtr->cbClsExtra;
1288 wc->cbWndExtra = classPtr->cbWndExtra;
1289 wc->hInstance = classPtr->hInstance;
1290 wc->hIcon = (HICON)classPtr->hIcon;
1291 wc->hIconSm = (HICON)classPtr->hIconSm;
1292 wc->hCursor = (HCURSOR)classPtr->hCursor;
1293 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1294 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1295 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1300 /***********************************************************************
1301 * ClassFirst (TOOLHELP.69)
1303 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1305 TRACE(class,"%p\n",pClassEntry);
1306 pClassEntry->wNext = 1;
1307 return ClassNext16( pClassEntry );
1311 /***********************************************************************
1312 * ClassNext (TOOLHELP.70)
1314 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1317 CLASS *class = firstClass;
1319 TRACE(class,"%p\n",pClassEntry);
1321 if (!pClassEntry->wNext) return FALSE;
1322 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1325 pClassEntry->wNext = 0;
1328 pClassEntry->hInst = class->hInstance;
1329 pClassEntry->wNext++;
1330 GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1331 sizeof(pClassEntry->szClassName) );