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"
21 #include "wine/winuser16.h"
22 #include "wine/unicode.h"
30 #include "debugtools.h"
32 DEFAULT_DEBUG_CHANNEL(class);
35 static CLASS
*firstClass
= NULL
;
38 /***********************************************************************
41 * Dump the content of a class structure to stderr.
43 void CLASS_DumpClass( CLASS
*ptr
)
45 char className
[MAX_CLASSNAME
+1];
48 if (ptr
->magic
!= CLASS_MAGIC
)
50 DPRINTF("%p is not a class\n", ptr
);
54 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
56 DPRINTF( "Class %p:\n", ptr
);
57 DPRINTF( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
58 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
59 "clsExtra=%d winExtra=%d #windows=%d\n",
60 ptr
->next
, ptr
->atomName
, className
, ptr
->style
,
61 (UINT
)ptr
->winproc
, ptr
->hInstance
, (UINT
)ptr
->dce
,
62 ptr
->hIcon
, ptr
->hCursor
, ptr
->hbrBackground
,
63 ptr
->cbClsExtra
, ptr
->cbWndExtra
, ptr
->cWindows
);
66 DPRINTF( "extra bytes:" );
67 for (i
= 0; i
< ptr
->cbClsExtra
; i
++)
68 DPRINTF( " %02x", *((BYTE
*)ptr
->wExtra
+i
) );
75 /***********************************************************************
78 * Walk the class list and print each class on stderr.
80 void CLASS_WalkClasses(void)
83 char className
[MAX_CLASSNAME
+1];
85 DPRINTF( " Class Name Style WndProc\n" );
86 for (ptr
= firstClass
; ptr
; ptr
= ptr
->next
)
88 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
89 DPRINTF( "%08x %-20.20s %08x %08x\n", (UINT
)ptr
, className
,
90 ptr
->style
, (UINT
)ptr
->winproc
);
96 /***********************************************************************
99 * Get the menu name as a ASCII string.
101 static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
103 if (!classPtr
->menuNameA
&& classPtr
->menuNameW
)
105 /* We need to copy the Unicode string */
106 classPtr
->menuNameA
= SEGPTR_STRDUP_WtoA( classPtr
->menuNameW
);
108 return classPtr
->menuNameA
;
112 /***********************************************************************
115 * Get the menu name as a Unicode string.
117 static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
119 if (!classPtr
->menuNameW
&& classPtr
->menuNameA
)
121 if (!HIWORD(classPtr
->menuNameA
))
122 return (LPWSTR
)classPtr
->menuNameA
;
123 /* Now we need to copy the ASCII string */
124 classPtr
->menuNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
125 classPtr
->menuNameA
);
127 return classPtr
->menuNameW
;
131 /***********************************************************************
134 * Set the menu name in a class structure by copying the string.
136 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
138 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
139 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
140 classPtr
->menuNameA
= SEGPTR_STRDUP( name
);
141 classPtr
->menuNameW
= 0;
145 /***********************************************************************
148 * Set the menu name in a class structure by copying the string.
150 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
154 CLASS_SetMenuNameA( classPtr
, (LPCSTR
)name
);
157 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
158 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
159 if ((classPtr
->menuNameW
= HeapAlloc( SystemHeap
, 0,
160 (strlenW(name
)+1)*sizeof(WCHAR
) )))
161 strcpyW( classPtr
->menuNameW
, name
);
162 classPtr
->menuNameA
= 0;
166 /***********************************************************************
167 * CLASS_GetClassNameA
169 * Get the clas name as a ASCII string.
171 static LPSTR
CLASS_GetClassNameA( CLASS
*classPtr
)
173 if (!classPtr
->classNameA
&& classPtr
->classNameW
)
175 /* We need to copy the Unicode string */
176 classPtr
->classNameA
= SEGPTR_STRDUP_WtoA( classPtr
->classNameW
);
178 return classPtr
->classNameA
;
182 /***********************************************************************
183 * CLASS_GetClassNameW
185 * Get the class name as a Unicode string.
187 static LPWSTR
CLASS_GetClassNameW( CLASS
*classPtr
)
189 if (!classPtr
->classNameW
&& classPtr
->classNameA
)
191 if (!HIWORD(classPtr
->classNameA
))
192 return (LPWSTR
)classPtr
->classNameA
;
193 /* Now we need to copy the ASCII string */
194 classPtr
->classNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
195 classPtr
->classNameA
);
197 return classPtr
->classNameW
;
200 /***********************************************************************
201 * CLASS_SetClassNameA
203 * Set the class name in a class structure by copying the string.
205 static void CLASS_SetClassNameA( CLASS
*classPtr
, LPCSTR name
)
207 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
208 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
209 classPtr
->classNameA
= SEGPTR_STRDUP( name
);
210 classPtr
->classNameW
= 0;
214 /***********************************************************************
215 * CLASS_SetClassNameW
217 * Set the class name in a class structure by copying the string.
219 static void CLASS_SetClassNameW( CLASS
*classPtr
, LPCWSTR name
)
223 CLASS_SetClassNameA( classPtr
, (LPCSTR
)name
);
226 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
227 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
228 if ((classPtr
->classNameW
= HeapAlloc( SystemHeap
, 0,
229 (strlenW(name
)+1)*sizeof(WCHAR
) )))
230 strcpyW( classPtr
->classNameW
, name
);
231 classPtr
->classNameA
= 0;
235 /***********************************************************************
238 * Free a class structure.
240 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
243 TRACE("%p \n", classPtr
);
245 /* Check if we can remove this class */
247 if (classPtr
->cWindows
> 0) return FALSE
;
249 /* Remove the class from the linked list */
251 for (ppClass
= &firstClass
; *ppClass
; ppClass
= &(*ppClass
)->next
)
252 if (*ppClass
== classPtr
) break;
255 ERR("Class list corrupted\n" );
258 *ppClass
= classPtr
->next
;
260 /* Delete the class */
262 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
263 if (classPtr
->hbrBackground
) DeleteObject( classPtr
->hbrBackground
);
264 GlobalDeleteAtom( classPtr
->atomName
);
265 CLASS_SetMenuNameA( classPtr
, NULL
);
266 CLASS_SetClassNameA( classPtr
, NULL
);
267 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
268 HeapFree( SystemHeap
, 0, classPtr
);
273 /***********************************************************************
274 * CLASS_FreeModuleClasses
276 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
280 TRACE("0x%08x \n", hModule
);
282 for (ptr
= firstClass
; ptr
; ptr
= next
)
285 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
290 /***********************************************************************
291 * CLASS_FindClassByAtom
293 * Return a pointer to the class.
294 * hinstance has been normalized by the caller.
297 * 980805 a local class will be found now if registred with hInst=0
298 * and looed up with a hInst!=0. msmoney does it (jsch)
300 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
301 { CLASS
* class, *tclass
=0;
303 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
305 /* First search task-specific classes */
307 for (class = firstClass
; (class); class = class->next
)
309 if (class->style
& CS_GLOBALCLASS
) continue;
310 if (class->atomName
== atom
)
312 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
314 TRACE("-- found local %p\n", class);
317 if (class->hInstance
==0) tclass
= class;
321 /* Then search global classes */
323 for (class = firstClass
; (class); class = class->next
)
325 if (!(class->style
& CS_GLOBALCLASS
)) continue;
326 if (class->atomName
== atom
)
328 TRACE("-- found global %p\n", class);
333 /* Then check if there was a local class with hInst=0*/
336 WARN("-- found local Class registred with hInst=0\n");
340 TRACE("-- not found\n");
345 /***********************************************************************
346 * CLASS_RegisterClass
348 * The real RegisterClass() functionality.
350 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
351 DWORD style
, INT classExtra
,
352 INT winExtra
, WNDPROC16 wndProc
,
353 WINDOWPROCTYPE wndProcType
)
357 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
358 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
360 /* Check if a class with this name already exists */
361 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
364 /* Class can be created only if it is local and */
365 /* if the class with the same name is global. */
367 if (style
& CS_GLOBALCLASS
) return NULL
;
368 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
371 /* Fix the extra bytes value */
373 if (classExtra
< 0) classExtra
= 0;
374 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
375 WARN("Class extra bytes %d is > 40\n", classExtra
);
376 if (winExtra
< 0) winExtra
= 0;
377 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
378 WARN("Win extra bytes %d is > 40\n", winExtra
);
380 /* Create the class */
382 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
383 classExtra
- sizeof(classPtr
->wExtra
) );
384 if (!classPtr
) return NULL
;
385 classPtr
->next
= firstClass
;
386 classPtr
->magic
= CLASS_MAGIC
;
387 classPtr
->cWindows
= 0;
388 classPtr
->style
= style
;
389 classPtr
->winproc
= (HWINDOWPROC
)0;
390 classPtr
->cbWndExtra
= winExtra
;
391 classPtr
->cbClsExtra
= classExtra
;
392 classPtr
->hInstance
= hInstance
;
393 classPtr
->atomName
= atom
;
394 classPtr
->menuNameA
= 0;
395 classPtr
->menuNameW
= 0;
396 classPtr
->classNameA
= 0;
397 classPtr
->classNameW
= 0;
398 classPtr
->dce
= (style
& CS_CLASSDC
) ?
399 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
401 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
403 /* Other values must be set by caller */
405 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
406 firstClass
= classPtr
;
411 /***********************************************************************
412 * RegisterClass16 (USER.57)
414 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
418 int iSmIconWidth
, iSmIconHeight
;
419 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
421 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
422 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
423 wc
->cbClsExtra
, wc
->cbWndExtra
,
424 wc
->lpfnWndProc
, WIN_PROC_16
)))
426 GlobalDeleteAtom( atom
);
430 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
431 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
432 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
433 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
434 wc
->cbWndExtra
, classPtr
,
435 HIWORD(wc
->lpszClassName
) ?
436 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
438 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
439 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
441 classPtr
->hIcon
= wc
->hIcon
;
442 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
443 iSmIconWidth
, iSmIconHeight
,
444 LR_COPYFROMRESOURCE
);
445 classPtr
->hCursor
= wc
->hCursor
;
446 classPtr
->hbrBackground
= wc
->hbrBackground
;
448 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
449 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
450 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
451 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
457 /***********************************************************************
458 * RegisterClassA (USER32.427)
460 * >0: Unique identifier
463 ATOM WINAPI
RegisterClassA(
464 const WNDCLASSA
* wc
/* Address of structure with class data */
467 int iSmIconWidth
, iSmIconHeight
;
470 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
472 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
475 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
476 wc
->cbClsExtra
, wc
->cbWndExtra
,
477 (WNDPROC16
)wc
->lpfnWndProc
,
479 { GlobalDeleteAtom( atom
);
480 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
484 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
485 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
486 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
487 wc
->cbWndExtra
, classPtr
,
488 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
490 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
491 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
493 classPtr
->hIcon
= wc
->hIcon
;
494 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
495 iSmIconWidth
, iSmIconHeight
,
496 LR_COPYFROMRESOURCE
);
497 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
498 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
500 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
501 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
506 /***********************************************************************
507 * RegisterClassW (USER32.430)
509 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
512 int iSmIconWidth
, iSmIconHeight
;
515 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
517 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
520 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
521 wc
->cbClsExtra
, wc
->cbWndExtra
,
522 (WNDPROC16
)wc
->lpfnWndProc
,
525 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
526 GlobalDeleteAtom( atom
);
530 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
531 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
532 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
533 wc
->cbWndExtra
, classPtr
);
535 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
536 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
538 classPtr
->hIcon
= wc
->hIcon
;
539 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
540 iSmIconWidth
, iSmIconHeight
,
541 LR_COPYFROMRESOURCE
);
542 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
543 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
545 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
546 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
551 /***********************************************************************
552 * RegisterClassEx16 (USER.397)
554 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
558 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
560 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
561 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
562 wc
->cbClsExtra
, wc
->cbWndExtra
,
563 wc
->lpfnWndProc
, WIN_PROC_16
)))
565 GlobalDeleteAtom( atom
);
569 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
570 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
571 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
572 wc
->cbWndExtra
, classPtr
);
574 classPtr
->hIcon
= wc
->hIcon
;
575 classPtr
->hIconSm
= wc
->hIconSm
;
576 classPtr
->hCursor
= wc
->hCursor
;
577 classPtr
->hbrBackground
= wc
->hbrBackground
;
579 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
580 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
581 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
582 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
587 /***********************************************************************
588 * RegisterClassExA (USER32.428)
590 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
595 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
597 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
600 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
601 wc
->cbClsExtra
, wc
->cbWndExtra
,
602 (WNDPROC16
)wc
->lpfnWndProc
,
605 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
606 GlobalDeleteAtom( atom
);
610 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
611 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
612 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
613 wc
->cbWndExtra
, classPtr
);
615 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
616 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
617 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
618 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
619 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
620 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
625 /***********************************************************************
626 * RegisterClassExW (USER32.429)
628 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
633 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
635 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
638 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
639 wc
->cbClsExtra
, wc
->cbWndExtra
,
640 (WNDPROC16
)wc
->lpfnWndProc
,
643 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
644 GlobalDeleteAtom( atom
);
648 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
649 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
650 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
651 wc
->cbWndExtra
, classPtr
);
653 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
654 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
655 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
656 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
657 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
658 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
663 /***********************************************************************
664 * UnregisterClass16 (USER.403)
666 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
668 return UnregisterClassA( className
, GetExePtr( hInstance
) );
672 /***********************************************************************
673 * UnregisterClassA (USER32.563)
676 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
681 TRACE("%s %x\n",debugres_a(className
), hInstance
);
683 if (!(atom
= GlobalFindAtomA( className
)))
685 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
688 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
689 (classPtr
->hInstance
!= hInstance
))
691 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
694 if (!(ret
= CLASS_FreeClass( classPtr
)))
695 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
699 /***********************************************************************
700 * UnregisterClassW (USER32.564)
702 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
707 TRACE("%s %x\n",debugres_w(className
), hInstance
);
709 if (!(atom
= GlobalFindAtomW( className
)))
711 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
714 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
715 (classPtr
->hInstance
!= hInstance
))
717 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
720 if (!(ret
= CLASS_FreeClass( classPtr
)))
721 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
725 /***********************************************************************
726 * GetClassWord16 (USER.129)
728 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
730 return GetClassWord( hwnd
, offset
);
734 /***********************************************************************
735 * GetClassWord (USER32.219)
737 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
742 TRACE("%x %x\n",hwnd
, offset
);
744 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
747 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
749 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
755 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
757 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
759 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
761 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
763 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
769 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
773 WARN("Invalid offset %d\n", offset
);
775 WIN_ReleaseWndPtr(wndPtr
);
780 /***********************************************************************
781 * GetClassLong16 (USER.131)
783 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
788 TRACE("%x %x\n",hwnd
, offset
);
793 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
794 ret
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
795 WIN_ReleaseWndPtr(wndPtr
);
798 ret
= GetClassLongA( hwnd
, offset
);
799 return (LONG
)SEGPTR_GET( (void *)ret
);
801 return GetClassLongA( hwnd
, offset
);
806 /***********************************************************************
807 * GetClassLongA (USER32.215)
809 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
814 TRACE("%x %x\n",hwnd
, offset
);
816 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
819 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
821 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
828 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
830 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
832 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
834 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
837 retvalue
= (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
840 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
843 case GCL_HBRBACKGROUND
:
847 retvalue
= GetClassWord( hwnd
, offset
);
850 WARN("Invalid offset %d\n", offset
);
853 WIN_ReleaseWndPtr(wndPtr
);
858 /***********************************************************************
859 * GetClassLongW (USER32.216)
861 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
866 TRACE("%x %x\n",hwnd
, offset
);
871 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
872 retvalue
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
873 WIN_ReleaseWndPtr(wndPtr
);
876 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
877 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
878 WIN_ReleaseWndPtr(wndPtr
);
881 return GetClassLongA( hwnd
, offset
);
886 /***********************************************************************
887 * SetClassWord16 (USER.130)
889 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
891 return SetClassWord( hwnd
, offset
, newval
);
895 /***********************************************************************
896 * SetClassWord (USER32.469)
898 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
904 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
906 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
909 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
910 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
913 WARN("Invalid offset %d\n", offset
);
914 WIN_ReleaseWndPtr(wndPtr
);
924 WIN_ReleaseWndPtr(wndPtr
);
925 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
926 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
927 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
928 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
929 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
930 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
932 WARN("Invalid offset %d\n", offset
);
933 WIN_ReleaseWndPtr(wndPtr
);
936 retval
= GET_WORD(ptr
);
937 PUT_WORD( ptr
, newval
);
939 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
940 need to be updated as well. Problem is that we can't tell whether the atom is
941 using wide or narrow characters. For now, we'll just NULL out the className
942 fields, and emit a FIXME. */
943 if (offset
== GCW_ATOM
)
945 CLASS_SetClassNameA( wndPtr
->class, NULL
);
946 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
948 WIN_ReleaseWndPtr(wndPtr
);
953 /***********************************************************************
954 * SetClassLong16 (USER.132)
956 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
961 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
966 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
967 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
968 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
969 WIN_PROC_16
, WIN_PROC_CLASS
);
970 WIN_ReleaseWndPtr(wndPtr
);
973 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
975 return SetClassLongA( hwnd
, offset
, newval
);
980 /***********************************************************************
981 * SetClassLongA (USER32.467)
983 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
989 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
991 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
994 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
995 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
998 WARN("Invalid offset %d\n", offset
);
1006 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
1007 retval
= 0; /* Old value is now meaningless anyway */
1010 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
1012 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1013 WIN_PROC_32A
, WIN_PROC_CLASS
);
1015 case GCL_HBRBACKGROUND
:
1019 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
1021 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
1022 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
1023 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
1024 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
1026 WARN("Invalid offset %d\n", offset
);
1030 retval
= GET_DWORD(ptr
);
1031 PUT_DWORD( ptr
, newval
);
1033 WIN_ReleaseWndPtr(wndPtr
);
1038 /***********************************************************************
1039 * SetClassLongW (USER32.468)
1041 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1046 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1051 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1052 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
1053 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1054 WIN_PROC_32W
, WIN_PROC_CLASS
);
1055 WIN_ReleaseWndPtr(wndPtr
);
1058 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1059 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1060 WIN_ReleaseWndPtr(wndPtr
);
1061 return 0; /* Old value is now meaningless anyway */
1063 return SetClassLongA( hwnd
, offset
, newval
);
1068 /***********************************************************************
1069 * GetClassName16 (USER.58)
1071 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1073 return GetClassNameA( hwnd
, buffer
, count
);
1077 /***********************************************************************
1078 * GetClassNameA (USER32.217)
1080 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1084 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1085 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1087 WIN_ReleaseWndPtr(wndPtr
);
1088 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1093 /***********************************************************************
1094 * GetClassNameW (USER32.218)
1096 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1100 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1101 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1102 WIN_ReleaseWndPtr(wndPtr
);
1103 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1109 /***********************************************************************
1110 * GetClassInfo16 (USER.404)
1112 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASS16
*wc
)
1117 TRACE("%x %s %p\n",hInstance
, debugres_a(name
), wc
);
1119 hInstance
= GetExePtr( hInstance
);
1120 if (!(atom
= GlobalFindAtomA( name
)) ||
1121 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1123 if ((hInstance
!= classPtr
->hInstance
) &&
1124 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1126 wc
->style
= (UINT16
)classPtr
->style
;
1127 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1128 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1129 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1130 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1131 wc
->hIcon
= classPtr
->hIcon
;
1132 wc
->hCursor
= classPtr
->hCursor
;
1133 wc
->hbrBackground
= classPtr
->hbrBackground
;
1134 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1135 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1136 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1137 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1138 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1139 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1144 /***********************************************************************
1145 * GetClassInfoA (USER32.211)
1147 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1153 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1155 /* workaround: if hInstance=NULL you expect to get the system classes
1156 but this classes (as example from comctl32.dll SysListView) won't be
1157 registered with hInstance=NULL in WINE because of the late loading
1158 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1160 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1163 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1164 classPtr
->hInstance
&&
1165 (hInstance
!= classPtr
->hInstance
))
1167 if (hInstance
) return FALSE
;
1168 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1171 wc
->style
= classPtr
->style
;
1172 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1174 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1175 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1176 wc
->hInstance
= hInstance
;
1177 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1178 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1179 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1180 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1181 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1186 /***********************************************************************
1187 * GetClassInfoW (USER32.214)
1189 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1195 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1197 if ( !(atom
=GlobalFindAtomW(name
)) ||
1198 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1202 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1203 classPtr
->hInstance
&&
1204 (hInstance
!= classPtr
->hInstance
))
1206 if (hInstance
) return FALSE
;
1207 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1209 wc
->style
= classPtr
->style
;
1210 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1212 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1213 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1214 wc
->hInstance
= hInstance
;
1215 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1216 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1217 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1218 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1219 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1224 /***********************************************************************
1225 * GetClassInfoEx16 (USER.398)
1227 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1228 * same in Win16 as in Win32. --AJ
1230 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASSEX16
*wc
)
1235 TRACE("%x %s %p\n",hInstance
,debugres_a( name
), wc
);
1237 hInstance
= GetExePtr( hInstance
);
1238 if (!(atom
= GlobalFindAtomA( name
)) ||
1239 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1240 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1241 wc
->style
= classPtr
->style
;
1242 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1243 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1244 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1245 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1246 wc
->hIcon
= classPtr
->hIcon
;
1247 wc
->hIconSm
= classPtr
->hIconSm
;
1248 wc
->hCursor
= classPtr
->hCursor
;
1249 wc
->hbrBackground
= classPtr
->hbrBackground
;
1250 wc
->lpszClassName
= (SEGPTR
)0;
1251 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1252 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1253 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1254 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1255 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1256 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1258 /* We must return the atom of the class here instead of just TRUE. */
1263 /***********************************************************************
1264 * GetClassInfoExA (USER32.212)
1266 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1272 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1274 if (!(atom
= GlobalFindAtomA( name
)) ||
1275 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1276 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1277 wc
->style
= classPtr
->style
;
1278 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1280 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1281 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1282 wc
->hInstance
= classPtr
->hInstance
;
1283 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1284 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1285 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1286 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1287 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1288 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1290 /* We must return the atom of the class here instead of just TRUE. */
1295 /***********************************************************************
1296 * GetClassInfoExW (USER32.213)
1298 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1304 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1306 if (!(atom
= GlobalFindAtomW( name
)) ||
1307 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1308 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1309 wc
->style
= classPtr
->style
;
1310 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1312 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1313 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1314 wc
->hInstance
= classPtr
->hInstance
;
1315 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1316 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1317 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1318 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1319 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1320 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1322 /* We must return the atom of the class here instead of just TRUE. */
1327 /***********************************************************************
1328 * ClassFirst (TOOLHELP.69)
1330 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1332 TRACE("%p\n",pClassEntry
);
1333 pClassEntry
->wNext
= 1;
1334 return ClassNext16( pClassEntry
);
1338 /***********************************************************************
1339 * ClassNext (TOOLHELP.70)
1341 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1344 CLASS
*class = firstClass
;
1346 TRACE("%p\n",pClassEntry
);
1348 if (!pClassEntry
->wNext
) return FALSE
;
1349 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1352 pClassEntry
->wNext
= 0;
1355 pClassEntry
->hInst
= class->hInstance
;
1356 pClassEntry
->wNext
++;
1357 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1358 sizeof(pClassEntry
->szClassName
) );