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
> (HBRUSH
)(COLOR_GRADIENTINACTIVECAPTION
+ 1))
264 DeleteObject( classPtr
->hbrBackground
);
265 GlobalDeleteAtom( classPtr
->atomName
);
266 CLASS_SetMenuNameA( classPtr
, NULL
);
267 CLASS_SetClassNameA( classPtr
, NULL
);
268 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
269 HeapFree( SystemHeap
, 0, classPtr
);
274 /***********************************************************************
275 * CLASS_FreeModuleClasses
277 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
281 TRACE("0x%08x\n", hModule
);
283 for (ptr
= firstClass
; ptr
; ptr
= next
)
286 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
291 /***********************************************************************
292 * CLASS_FindClassByAtom
294 * Return a pointer to the class.
295 * hinstance has been normalized by the caller.
298 * 980805 a local class will be found now if registred with hInst=0
299 * and looed up with a hInst!=0. msmoney does it (jsch)
301 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
302 { CLASS
* class, *tclass
=0;
304 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
306 /* First search task-specific classes */
308 for (class = firstClass
; (class); class = class->next
)
310 if (class->style
& CS_GLOBALCLASS
) continue;
311 if (class->atomName
== atom
)
313 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
315 TRACE("-- found local %p\n", class);
318 if (class->hInstance
==0) tclass
= class;
322 /* Then search global classes */
324 for (class = firstClass
; (class); class = class->next
)
326 if (!(class->style
& CS_GLOBALCLASS
)) continue;
327 if (class->atomName
== atom
)
329 TRACE("-- found global %p\n", class);
334 /* Then check if there was a local class with hInst=0*/
337 WARN("-- found local Class registred with hInst=0\n");
341 TRACE("-- not found\n");
346 /***********************************************************************
347 * CLASS_RegisterClass
349 * The real RegisterClass() functionality.
351 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
352 DWORD style
, INT classExtra
,
353 INT winExtra
, WNDPROC16 wndProc
,
354 WINDOWPROCTYPE wndProcType
)
358 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
359 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
361 /* Check if a class with this name already exists */
362 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
365 /* Class can be created only if it is local and */
366 /* if the class with the same name is global. */
368 if (style
& CS_GLOBALCLASS
) return NULL
;
369 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
372 /* Fix the extra bytes value */
374 if (classExtra
< 0) classExtra
= 0;
375 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
376 WARN("Class extra bytes %d is > 40\n", classExtra
);
377 if (winExtra
< 0) winExtra
= 0;
378 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
379 WARN("Win extra bytes %d is > 40\n", winExtra
);
381 /* Create the class */
383 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
384 classExtra
- sizeof(classPtr
->wExtra
) );
385 if (!classPtr
) return NULL
;
386 classPtr
->next
= firstClass
;
387 classPtr
->magic
= CLASS_MAGIC
;
388 classPtr
->cWindows
= 0;
389 classPtr
->style
= style
;
390 classPtr
->winproc
= (HWINDOWPROC
)0;
391 classPtr
->cbWndExtra
= winExtra
;
392 classPtr
->cbClsExtra
= classExtra
;
393 classPtr
->hInstance
= hInstance
;
394 classPtr
->atomName
= atom
;
395 classPtr
->menuNameA
= 0;
396 classPtr
->menuNameW
= 0;
397 classPtr
->classNameA
= 0;
398 classPtr
->classNameW
= 0;
399 classPtr
->dce
= (style
& CS_CLASSDC
) ?
400 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
402 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
404 /* Other values must be set by caller */
406 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
407 firstClass
= classPtr
;
412 /***********************************************************************
413 * RegisterClass16 (USER.57)
415 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
419 int iSmIconWidth
, iSmIconHeight
;
420 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
422 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
423 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
424 wc
->cbClsExtra
, wc
->cbWndExtra
,
425 wc
->lpfnWndProc
, WIN_PROC_16
)))
427 GlobalDeleteAtom( atom
);
431 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
432 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
433 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
434 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
435 wc
->cbWndExtra
, classPtr
,
436 HIWORD(wc
->lpszClassName
) ?
437 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
439 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
440 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
442 classPtr
->hIcon
= wc
->hIcon
;
443 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
444 iSmIconWidth
, iSmIconHeight
,
445 LR_COPYFROMRESOURCE
);
446 classPtr
->hCursor
= wc
->hCursor
;
447 classPtr
->hbrBackground
= wc
->hbrBackground
;
449 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
450 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
451 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
452 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
458 /***********************************************************************
459 * RegisterClassA (USER32.427)
461 * >0: Unique identifier
464 ATOM WINAPI
RegisterClassA( const WNDCLASSA
* wc
) /* Address of structure with class data */
467 int iSmIconWidth
, iSmIconHeight
;
470 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
472 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
473 wc
->cbClsExtra
, wc
->cbWndExtra
,
474 (WNDPROC16
)wc
->lpfnWndProc
,
476 { GlobalDeleteAtom( atom
);
477 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
481 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
482 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
483 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
484 wc
->cbWndExtra
, classPtr
,
485 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
487 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
488 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
490 classPtr
->hIcon
= wc
->hIcon
;
491 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
492 iSmIconWidth
, iSmIconHeight
,
493 LR_COPYFROMRESOURCE
);
494 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
495 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
497 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
498 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
503 /***********************************************************************
504 * RegisterClassW (USER32.430)
506 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
509 int iSmIconWidth
, iSmIconHeight
;
512 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
514 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
515 wc
->cbClsExtra
, wc
->cbWndExtra
,
516 (WNDPROC16
)wc
->lpfnWndProc
,
519 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
520 GlobalDeleteAtom( atom
);
524 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
525 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
526 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
527 wc
->cbWndExtra
, classPtr
);
529 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
530 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
532 classPtr
->hIcon
= wc
->hIcon
;
533 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
534 iSmIconWidth
, iSmIconHeight
,
535 LR_COPYFROMRESOURCE
);
536 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
537 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
539 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
540 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
545 /***********************************************************************
546 * RegisterClassEx16 (USER.397)
548 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
552 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
554 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
555 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
556 wc
->cbClsExtra
, wc
->cbWndExtra
,
557 wc
->lpfnWndProc
, WIN_PROC_16
)))
559 GlobalDeleteAtom( atom
);
563 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
564 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
565 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
566 wc
->cbWndExtra
, classPtr
);
568 classPtr
->hIcon
= wc
->hIcon
;
569 classPtr
->hIconSm
= wc
->hIconSm
;
570 classPtr
->hCursor
= wc
->hCursor
;
571 classPtr
->hbrBackground
= wc
->hbrBackground
;
573 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
574 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
575 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
576 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
581 /***********************************************************************
582 * RegisterClassExA (USER32.428)
584 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
589 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
591 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
592 wc
->cbClsExtra
, wc
->cbWndExtra
,
593 (WNDPROC16
)wc
->lpfnWndProc
,
596 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
597 GlobalDeleteAtom( atom
);
601 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
602 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
603 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
604 wc
->cbWndExtra
, classPtr
);
606 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
607 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
608 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
609 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
610 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
611 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
616 /***********************************************************************
617 * RegisterClassExW (USER32.429)
619 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
624 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
626 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
627 wc
->cbClsExtra
, wc
->cbWndExtra
,
628 (WNDPROC16
)wc
->lpfnWndProc
,
631 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
632 GlobalDeleteAtom( atom
);
636 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
637 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
638 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
639 wc
->cbWndExtra
, classPtr
);
641 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
642 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
643 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
644 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
645 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
646 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
651 /***********************************************************************
652 * UnregisterClass16 (USER.403)
654 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
656 return UnregisterClassA( className
, GetExePtr( hInstance
) );
660 /***********************************************************************
661 * UnregisterClassA (USER32.563)
664 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
669 TRACE("%s %x\n",debugres_a(className
), hInstance
);
671 if (!(atom
= GlobalFindAtomA( className
)))
673 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
676 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
677 (classPtr
->hInstance
!= hInstance
))
679 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
682 if (!(ret
= CLASS_FreeClass( classPtr
)))
683 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
687 /***********************************************************************
688 * UnregisterClassW (USER32.564)
690 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
695 TRACE("%s %x\n",debugres_w(className
), hInstance
);
697 if (!(atom
= GlobalFindAtomW( className
)))
699 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
702 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
703 (classPtr
->hInstance
!= hInstance
))
705 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
708 if (!(ret
= CLASS_FreeClass( classPtr
)))
709 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
713 /***********************************************************************
714 * GetClassWord16 (USER.129)
716 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
718 return GetClassWord( hwnd
, offset
);
722 /***********************************************************************
723 * GetClassWord (USER32.219)
725 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
730 TRACE("%x %x\n",hwnd
, offset
);
732 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
735 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
737 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
743 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
745 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
747 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
749 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
751 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
757 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
761 WARN("Invalid offset %d\n", offset
);
763 WIN_ReleaseWndPtr(wndPtr
);
768 /***********************************************************************
769 * GetClassLong16 (USER.131)
771 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
776 TRACE("%x %x\n",hwnd
, offset
);
781 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
782 ret
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
783 WIN_ReleaseWndPtr(wndPtr
);
786 ret
= GetClassLongA( hwnd
, offset
);
787 return (LONG
)SEGPTR_GET( (void *)ret
);
789 return GetClassLongA( hwnd
, offset
);
794 /***********************************************************************
795 * GetClassLongA (USER32.215)
797 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
802 TRACE("%x %x\n",hwnd
, offset
);
804 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
807 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
809 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
816 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
818 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
820 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
822 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
825 retvalue
= (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
828 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
831 case GCL_HBRBACKGROUND
:
835 retvalue
= GetClassWord( hwnd
, offset
);
838 WARN("Invalid offset %d\n", offset
);
841 WIN_ReleaseWndPtr(wndPtr
);
846 /***********************************************************************
847 * GetClassLongW (USER32.216)
849 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
854 TRACE("%x %x\n",hwnd
, offset
);
859 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
860 retvalue
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
861 WIN_ReleaseWndPtr(wndPtr
);
864 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
865 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
866 WIN_ReleaseWndPtr(wndPtr
);
869 return GetClassLongA( hwnd
, offset
);
874 /***********************************************************************
875 * SetClassWord16 (USER.130)
877 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
879 return SetClassWord( hwnd
, offset
, newval
);
883 /***********************************************************************
884 * SetClassWord (USER32.469)
886 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
892 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
894 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
897 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
898 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
901 WARN("Invalid offset %d\n", offset
);
902 WIN_ReleaseWndPtr(wndPtr
);
912 WIN_ReleaseWndPtr(wndPtr
);
913 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
914 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
915 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
916 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
917 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
918 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
920 WARN("Invalid offset %d\n", offset
);
921 WIN_ReleaseWndPtr(wndPtr
);
924 retval
= GET_WORD(ptr
);
925 PUT_WORD( ptr
, newval
);
927 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
928 need to be updated as well. Problem is that we can't tell whether the atom is
929 using wide or narrow characters. For now, we'll just NULL out the className
930 fields, and emit a FIXME. */
931 if (offset
== GCW_ATOM
)
933 CLASS_SetClassNameA( wndPtr
->class, NULL
);
934 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
936 WIN_ReleaseWndPtr(wndPtr
);
941 /***********************************************************************
942 * SetClassLong16 (USER.132)
944 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
949 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
954 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
955 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
956 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
957 WIN_PROC_16
, WIN_PROC_CLASS
);
958 WIN_ReleaseWndPtr(wndPtr
);
961 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
963 return SetClassLongA( hwnd
, offset
, newval
);
968 /***********************************************************************
969 * SetClassLongA (USER32.467)
971 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
977 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
979 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
982 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
983 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
986 WARN("Invalid offset %d\n", offset
);
994 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
995 retval
= 0; /* Old value is now meaningless anyway */
998 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
1000 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1001 WIN_PROC_32A
, WIN_PROC_CLASS
);
1003 case GCL_HBRBACKGROUND
:
1007 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
1009 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
1010 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
1011 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
1012 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
1014 WARN("Invalid offset %d\n", offset
);
1018 retval
= GET_DWORD(ptr
);
1019 PUT_DWORD( ptr
, newval
);
1021 WIN_ReleaseWndPtr(wndPtr
);
1026 /***********************************************************************
1027 * SetClassLongW (USER32.468)
1029 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1034 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1039 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1040 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
1041 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1042 WIN_PROC_32W
, WIN_PROC_CLASS
);
1043 WIN_ReleaseWndPtr(wndPtr
);
1046 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1047 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1048 WIN_ReleaseWndPtr(wndPtr
);
1049 return 0; /* Old value is now meaningless anyway */
1051 return SetClassLongA( hwnd
, offset
, newval
);
1056 /***********************************************************************
1057 * GetClassName16 (USER.58)
1059 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1061 return GetClassNameA( hwnd
, buffer
, count
);
1065 /***********************************************************************
1066 * GetClassNameA (USER32.217)
1068 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1072 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1073 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1075 WIN_ReleaseWndPtr(wndPtr
);
1076 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1081 /***********************************************************************
1082 * GetClassNameW (USER32.218)
1084 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1088 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1089 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1090 WIN_ReleaseWndPtr(wndPtr
);
1091 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1097 /***********************************************************************
1098 * GetClassInfo16 (USER.404)
1100 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASS16
*wc
)
1105 TRACE("%x %s %p\n",hInstance
, debugres_a(name
), wc
);
1107 hInstance
= GetExePtr( hInstance
);
1108 if (!(atom
= GlobalFindAtomA( name
)) ||
1109 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1111 if ((hInstance
!= classPtr
->hInstance
) &&
1112 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1114 wc
->style
= (UINT16
)classPtr
->style
;
1115 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1116 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1117 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1118 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1119 wc
->hIcon
= classPtr
->hIcon
;
1120 wc
->hCursor
= classPtr
->hCursor
;
1121 wc
->hbrBackground
= classPtr
->hbrBackground
;
1122 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1123 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1124 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1125 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1126 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1127 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1132 /***********************************************************************
1133 * GetClassInfoA (USER32.211)
1135 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1141 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1143 /* workaround: if hInstance=NULL you expect to get the system classes
1144 but this classes (as example from comctl32.dll SysListView) won't be
1145 registered with hInstance=NULL in WINE because of the late loading
1146 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1148 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1151 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1152 classPtr
->hInstance
&&
1153 (hInstance
!= classPtr
->hInstance
))
1155 if (hInstance
) return FALSE
;
1156 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1159 wc
->style
= classPtr
->style
;
1160 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1162 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1163 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1164 wc
->hInstance
= hInstance
;
1165 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1166 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1167 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1168 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1169 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1174 /***********************************************************************
1175 * GetClassInfoW (USER32.214)
1177 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1183 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1185 if ( !(atom
=GlobalFindAtomW(name
)) ||
1186 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1190 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1191 classPtr
->hInstance
&&
1192 (hInstance
!= classPtr
->hInstance
))
1194 if (hInstance
) return FALSE
;
1195 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1197 wc
->style
= classPtr
->style
;
1198 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1200 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1201 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1202 wc
->hInstance
= hInstance
;
1203 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1204 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1205 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1206 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1207 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1212 /***********************************************************************
1213 * GetClassInfoEx16 (USER.398)
1215 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1216 * same in Win16 as in Win32. --AJ
1218 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASSEX16
*wc
)
1223 TRACE("%x %s %p\n",hInstance
,debugres_a( name
), wc
);
1225 hInstance
= GetExePtr( hInstance
);
1226 if (!(atom
= GlobalFindAtomA( name
)) ||
1227 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1228 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1229 wc
->style
= classPtr
->style
;
1230 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1231 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1232 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1233 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1234 wc
->hIcon
= classPtr
->hIcon
;
1235 wc
->hIconSm
= classPtr
->hIconSm
;
1236 wc
->hCursor
= classPtr
->hCursor
;
1237 wc
->hbrBackground
= classPtr
->hbrBackground
;
1238 wc
->lpszClassName
= (SEGPTR
)0;
1239 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1240 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1241 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1242 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1243 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1244 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1246 /* We must return the atom of the class here instead of just TRUE. */
1251 /***********************************************************************
1252 * GetClassInfoExA (USER32.212)
1254 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1260 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1262 if (!(atom
= GlobalFindAtomA( name
)) ||
1263 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1264 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1265 wc
->style
= classPtr
->style
;
1266 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1268 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1269 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1270 wc
->hInstance
= classPtr
->hInstance
;
1271 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1272 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1273 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1274 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1275 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1276 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1278 /* We must return the atom of the class here instead of just TRUE. */
1283 /***********************************************************************
1284 * GetClassInfoExW (USER32.213)
1286 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1292 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1294 if (!(atom
= GlobalFindAtomW( name
)) ||
1295 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1296 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1297 wc
->style
= classPtr
->style
;
1298 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1300 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1301 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1302 wc
->hInstance
= classPtr
->hInstance
;
1303 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1304 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1305 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1306 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1307 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1308 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1310 /* We must return the atom of the class here instead of just TRUE. */
1315 /***********************************************************************
1316 * ClassFirst (TOOLHELP.69)
1318 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1320 TRACE("%p\n",pClassEntry
);
1321 pClassEntry
->wNext
= 1;
1322 return ClassNext16( pClassEntry
);
1326 /***********************************************************************
1327 * ClassNext (TOOLHELP.70)
1329 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1332 CLASS
*class = firstClass
;
1334 TRACE("%p\n",pClassEntry
);
1336 if (!pClassEntry
->wNext
) return FALSE
;
1337 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1340 pClassEntry
->wNext
= 0;
1343 pClassEntry
->hInst
= class->hInstance
;
1344 pClassEntry
->wNext
++;
1345 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1346 sizeof(pClassEntry
->szClassName
) );