2 * Window classes functions
4 * Copyright 1993, 1996 Alexandre Julliard
5 * 1998 Juergen Schmied (jsch)
7 * FIXME: In win32 all classes are local. They are registered at
8 * program start. Processes CANNOT share classes. (Source: some
9 * win31->NT migration book)
11 * FIXME: There seems to be a general problem with hInstance in WINE
12 * classes are getting registred with wrong hInstance.
17 #include "wine/winbase16.h"
25 #include "debugtools.h"
29 #include "wine/winuser16.h"
31 DEFAULT_DEBUG_CHANNEL(class)
34 static CLASS
*firstClass
= NULL
;
37 /***********************************************************************
40 * Dump the content of a class structure to stderr.
42 void CLASS_DumpClass( CLASS
*ptr
)
44 char className
[MAX_CLASSNAME
+1];
47 if (ptr
->magic
!= CLASS_MAGIC
)
49 DPRINTF("%p is not a class\n", ptr
);
53 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
55 DPRINTF( "Class %p:\n", ptr
);
56 DPRINTF( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
57 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
58 "clsExtra=%d winExtra=%d #windows=%d\n",
59 ptr
->next
, ptr
->atomName
, className
, ptr
->style
,
60 (UINT
)ptr
->winproc
, ptr
->hInstance
, (UINT
)ptr
->dce
,
61 ptr
->hIcon
, ptr
->hCursor
, ptr
->hbrBackground
,
62 ptr
->cbClsExtra
, ptr
->cbWndExtra
, ptr
->cWindows
);
65 DPRINTF( "extra bytes:" );
66 for (i
= 0; i
< ptr
->cbClsExtra
; i
++)
67 DPRINTF( " %02x", *((BYTE
*)ptr
->wExtra
+i
) );
74 /***********************************************************************
77 * Walk the class list and print each class on stderr.
79 void CLASS_WalkClasses(void)
82 char className
[MAX_CLASSNAME
+1];
84 DPRINTF( " Class Name Style WndProc\n" );
85 for (ptr
= firstClass
; ptr
; ptr
= ptr
->next
)
87 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
88 DPRINTF( "%08x %-20.20s %08x %08x\n", (UINT
)ptr
, className
,
89 ptr
->style
, (UINT
)ptr
->winproc
);
95 /***********************************************************************
98 * Get the menu name as a ASCII string.
100 static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
102 if (!classPtr
->menuNameA
&& classPtr
->menuNameW
)
104 /* We need to copy the Unicode string */
105 classPtr
->menuNameA
= SEGPTR_STRDUP_WtoA( classPtr
->menuNameW
);
107 return classPtr
->menuNameA
;
111 /***********************************************************************
114 * Get the menu name as a Unicode string.
116 static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
118 if (!classPtr
->menuNameW
&& classPtr
->menuNameA
)
120 if (!HIWORD(classPtr
->menuNameA
))
121 return (LPWSTR
)classPtr
->menuNameA
;
122 /* Now we need to copy the ASCII string */
123 classPtr
->menuNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
124 classPtr
->menuNameA
);
126 return classPtr
->menuNameW
;
130 /***********************************************************************
133 * Set the menu name in a class structure by copying the string.
135 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
137 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
138 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
139 classPtr
->menuNameA
= SEGPTR_STRDUP( name
);
140 classPtr
->menuNameW
= 0;
144 /***********************************************************************
147 * Set the menu name in a class structure by copying the string.
149 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
153 CLASS_SetMenuNameA( classPtr
, (LPCSTR
)name
);
156 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
157 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
158 if ((classPtr
->menuNameW
= HeapAlloc( SystemHeap
, 0,
159 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
160 lstrcpyW( classPtr
->menuNameW
, name
);
161 classPtr
->menuNameA
= 0;
165 /***********************************************************************
166 * CLASS_GetClassNameA
168 * Get the clas name as a ASCII string.
170 static LPSTR
CLASS_GetClassNameA( CLASS
*classPtr
)
172 if (!classPtr
->classNameA
&& classPtr
->classNameW
)
174 /* We need to copy the Unicode string */
175 classPtr
->classNameA
= SEGPTR_STRDUP_WtoA( classPtr
->classNameW
);
177 return classPtr
->classNameA
;
181 /***********************************************************************
182 * CLASS_GetClassNameW
184 * Get the class name as a Unicode string.
186 static LPWSTR
CLASS_GetClassNameW( CLASS
*classPtr
)
188 if (!classPtr
->classNameW
&& classPtr
->classNameA
)
190 if (!HIWORD(classPtr
->classNameA
))
191 return (LPWSTR
)classPtr
->classNameA
;
192 /* Now we need to copy the ASCII string */
193 classPtr
->classNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
194 classPtr
->classNameA
);
196 return classPtr
->classNameW
;
199 /***********************************************************************
200 * CLASS_SetClassNameA
202 * Set the class name in a class structure by copying the string.
204 static void CLASS_SetClassNameA( CLASS
*classPtr
, LPCSTR name
)
206 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
207 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
208 classPtr
->classNameA
= SEGPTR_STRDUP( name
);
209 classPtr
->classNameW
= 0;
213 /***********************************************************************
214 * CLASS_SetClassNameW
216 * Set the class name in a class structure by copying the string.
218 static void CLASS_SetClassNameW( CLASS
*classPtr
, LPCWSTR name
)
222 CLASS_SetClassNameA( classPtr
, (LPCSTR
)name
);
225 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
226 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
227 if ((classPtr
->classNameW
= HeapAlloc( SystemHeap
, 0,
228 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
229 lstrcpyW( classPtr
->classNameW
, name
);
230 classPtr
->classNameA
= 0;
234 /***********************************************************************
237 * Free a class structure.
239 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
242 TRACE("%p \n", classPtr
);
244 /* Check if we can remove this class */
246 if (classPtr
->cWindows
> 0) return FALSE
;
248 /* Remove the class from the linked list */
250 for (ppClass
= &firstClass
; *ppClass
; ppClass
= &(*ppClass
)->next
)
251 if (*ppClass
== classPtr
) break;
254 ERR("Class list corrupted\n" );
257 *ppClass
= classPtr
->next
;
259 /* Delete the class */
261 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
262 if (classPtr
->hbrBackground
) DeleteObject( classPtr
->hbrBackground
);
263 GlobalDeleteAtom( classPtr
->atomName
);
264 CLASS_SetMenuNameA( classPtr
, NULL
);
265 CLASS_SetClassNameA( classPtr
, NULL
);
266 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
267 HeapFree( SystemHeap
, 0, classPtr
);
272 /***********************************************************************
273 * CLASS_FreeModuleClasses
275 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
279 TRACE("0x%08x \n", hModule
);
281 for (ptr
= firstClass
; ptr
; ptr
= next
)
284 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
289 /***********************************************************************
290 * CLASS_FindClassByAtom
292 * Return a pointer to the class.
293 * hinstance has been normalized by the caller.
296 * 980805 a local class will be found now if registred with hInst=0
297 * and looed up with a hInst!=0. msmoney does it (jsch)
299 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
300 { CLASS
* class, *tclass
=0;
302 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
304 /* First search task-specific classes */
306 for (class = firstClass
; (class); class = class->next
)
308 if (class->style
& CS_GLOBALCLASS
) continue;
309 if (class->atomName
== atom
)
311 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
313 TRACE("-- found local %p\n", class);
316 if (class->hInstance
==0) tclass
= class;
320 /* Then search global classes */
322 for (class = firstClass
; (class); class = class->next
)
324 if (!(class->style
& CS_GLOBALCLASS
)) continue;
325 if (class->atomName
== atom
)
327 TRACE("-- found global %p\n", class);
332 /* Then check if there was a local class with hInst=0*/
335 WARN("-- found local Class registred with hInst=0\n");
339 TRACE("-- not found\n");
344 /***********************************************************************
345 * CLASS_RegisterClass
347 * The real RegisterClass() functionality.
349 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
350 DWORD style
, INT classExtra
,
351 INT winExtra
, WNDPROC16 wndProc
,
352 WINDOWPROCTYPE wndProcType
)
356 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
357 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
359 /* Check if a class with this name already exists */
360 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
363 /* Class can be created only if it is local and */
364 /* if the class with the same name is global. */
366 if (style
& CS_GLOBALCLASS
) return NULL
;
367 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
370 /* Fix the extra bytes value */
372 if (classExtra
< 0) classExtra
= 0;
373 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
374 WARN("Class extra bytes %d is > 40\n", classExtra
);
375 if (winExtra
< 0) winExtra
= 0;
376 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
377 WARN("Win extra bytes %d is > 40\n", winExtra
);
379 /* Create the class */
381 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
382 classExtra
- sizeof(classPtr
->wExtra
) );
383 if (!classPtr
) return NULL
;
384 classPtr
->next
= firstClass
;
385 classPtr
->magic
= CLASS_MAGIC
;
386 classPtr
->cWindows
= 0;
387 classPtr
->style
= style
;
388 classPtr
->winproc
= (HWINDOWPROC
)0;
389 classPtr
->cbWndExtra
= winExtra
;
390 classPtr
->cbClsExtra
= classExtra
;
391 classPtr
->hInstance
= hInstance
;
392 classPtr
->atomName
= atom
;
393 classPtr
->menuNameA
= 0;
394 classPtr
->menuNameW
= 0;
395 classPtr
->classNameA
= 0;
396 classPtr
->classNameW
= 0;
397 classPtr
->dce
= (style
& CS_CLASSDC
) ?
398 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
400 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
402 /* Other values must be set by caller */
404 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
405 firstClass
= classPtr
;
410 /***********************************************************************
411 * RegisterClass16 (USER.57)
413 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
417 int iSmIconWidth
, iSmIconHeight
;
418 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
420 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
421 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
422 wc
->cbClsExtra
, wc
->cbWndExtra
,
423 wc
->lpfnWndProc
, WIN_PROC_16
)))
425 GlobalDeleteAtom( atom
);
429 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
430 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
431 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
432 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
433 wc
->cbWndExtra
, classPtr
,
434 HIWORD(wc
->lpszClassName
) ?
435 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
437 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
438 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
440 classPtr
->hIcon
= wc
->hIcon
;
441 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
442 iSmIconWidth
, iSmIconHeight
,
443 LR_COPYFROMRESOURCE
);
444 classPtr
->hCursor
= wc
->hCursor
;
445 classPtr
->hbrBackground
= wc
->hbrBackground
;
447 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
448 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
449 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
450 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
456 /***********************************************************************
457 * RegisterClassA (USER32.427)
459 * >0: Unique identifier
462 ATOM WINAPI
RegisterClassA(
463 const WNDCLASSA
* wc
/* Address of structure with class data */
466 int iSmIconWidth
, iSmIconHeight
;
469 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
471 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
474 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
475 wc
->cbClsExtra
, wc
->cbWndExtra
,
476 (WNDPROC16
)wc
->lpfnWndProc
,
478 { GlobalDeleteAtom( atom
);
479 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
483 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
484 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
485 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
486 wc
->cbWndExtra
, classPtr
,
487 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
489 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
490 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
492 classPtr
->hIcon
= wc
->hIcon
;
493 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
494 iSmIconWidth
, iSmIconHeight
,
495 LR_COPYFROMRESOURCE
);
496 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
497 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
499 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
500 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
505 /***********************************************************************
506 * RegisterClassW (USER32.430)
508 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
511 int iSmIconWidth
, iSmIconHeight
;
514 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
516 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
519 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
520 wc
->cbClsExtra
, wc
->cbWndExtra
,
521 (WNDPROC16
)wc
->lpfnWndProc
,
524 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
525 GlobalDeleteAtom( atom
);
529 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
530 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
531 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
532 wc
->cbWndExtra
, classPtr
);
534 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
535 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
537 classPtr
->hIcon
= wc
->hIcon
;
538 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
539 iSmIconWidth
, iSmIconHeight
,
540 LR_COPYFROMRESOURCE
);
541 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
542 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
544 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
545 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
550 /***********************************************************************
551 * RegisterClassEx16 (USER.397)
553 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
557 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
559 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
560 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
561 wc
->cbClsExtra
, wc
->cbWndExtra
,
562 wc
->lpfnWndProc
, WIN_PROC_16
)))
564 GlobalDeleteAtom( atom
);
568 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
569 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
570 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
571 wc
->cbWndExtra
, classPtr
);
573 classPtr
->hIcon
= wc
->hIcon
;
574 classPtr
->hIconSm
= wc
->hIconSm
;
575 classPtr
->hCursor
= wc
->hCursor
;
576 classPtr
->hbrBackground
= wc
->hbrBackground
;
578 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
579 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
580 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
581 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
586 /***********************************************************************
587 * RegisterClassExA (USER32.428)
589 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
594 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
596 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
599 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
600 wc
->cbClsExtra
, wc
->cbWndExtra
,
601 (WNDPROC16
)wc
->lpfnWndProc
,
604 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
605 GlobalDeleteAtom( atom
);
609 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
610 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
611 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
612 wc
->cbWndExtra
, classPtr
);
614 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
615 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
616 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
617 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
618 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
619 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
624 /***********************************************************************
625 * RegisterClassExW (USER32.429)
627 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
632 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
634 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
637 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
638 wc
->cbClsExtra
, wc
->cbWndExtra
,
639 (WNDPROC16
)wc
->lpfnWndProc
,
642 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
643 GlobalDeleteAtom( atom
);
647 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
648 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
649 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
650 wc
->cbWndExtra
, classPtr
);
652 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
653 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
654 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
655 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
656 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
657 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
662 /***********************************************************************
663 * UnregisterClass16 (USER.403)
665 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
667 return UnregisterClassA( className
, GetExePtr( hInstance
) );
671 /***********************************************************************
672 * UnregisterClassA (USER32.563)
675 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
680 TRACE("%s %x\n",debugres_a(className
), hInstance
);
682 if (!(atom
= GlobalFindAtomA( className
)))
684 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
687 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
688 (classPtr
->hInstance
!= hInstance
))
690 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
693 if (!(ret
= CLASS_FreeClass( classPtr
)))
694 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
698 /***********************************************************************
699 * UnregisterClassW (USER32.564)
701 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
706 TRACE("%s %x\n",debugres_w(className
), hInstance
);
708 if (!(atom
= GlobalFindAtomW( className
)))
710 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
713 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
714 (classPtr
->hInstance
!= hInstance
))
716 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
719 if (!(ret
= CLASS_FreeClass( classPtr
)))
720 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
724 /***********************************************************************
725 * GetClassWord16 (USER.129)
727 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
729 return GetClassWord( hwnd
, offset
);
733 /***********************************************************************
734 * GetClassWord (USER32.219)
736 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
741 TRACE("%x %x\n",hwnd
, offset
);
743 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
746 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
748 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
754 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
756 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
758 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
760 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
762 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
768 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
772 WARN("Invalid offset %d\n", offset
);
774 WIN_ReleaseWndPtr(wndPtr
);
779 /***********************************************************************
780 * GetClassLong16 (USER.131)
782 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
787 TRACE("%x %x\n",hwnd
, offset
);
792 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
793 ret
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
794 WIN_ReleaseWndPtr(wndPtr
);
797 ret
= GetClassLongA( hwnd
, offset
);
798 return (LONG
)SEGPTR_GET( (void *)ret
);
800 return GetClassLongA( hwnd
, offset
);
805 /***********************************************************************
806 * GetClassLongA (USER32.215)
808 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
813 TRACE("%x %x\n",hwnd
, offset
);
815 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
818 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
820 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
827 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
829 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
831 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
833 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
836 retvalue
= (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
839 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
842 case GCL_HBRBACKGROUND
:
846 retvalue
= GetClassWord( hwnd
, offset
);
849 WARN("Invalid offset %d\n", offset
);
852 WIN_ReleaseWndPtr(wndPtr
);
857 /***********************************************************************
858 * GetClassLongW (USER32.216)
860 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
865 TRACE("%x %x\n",hwnd
, offset
);
870 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
871 retvalue
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
872 WIN_ReleaseWndPtr(wndPtr
);
875 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
876 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
877 WIN_ReleaseWndPtr(wndPtr
);
880 return GetClassLongA( hwnd
, offset
);
885 /***********************************************************************
886 * SetClassWord16 (USER.130)
888 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
890 return SetClassWord( hwnd
, offset
, newval
);
894 /***********************************************************************
895 * SetClassWord (USER32.469)
897 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
903 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
905 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
908 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
909 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
912 WARN("Invalid offset %d\n", offset
);
913 WIN_ReleaseWndPtr(wndPtr
);
923 WIN_ReleaseWndPtr(wndPtr
);
924 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
925 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
926 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
927 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
928 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
929 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
931 WARN("Invalid offset %d\n", offset
);
932 WIN_ReleaseWndPtr(wndPtr
);
935 retval
= GET_WORD(ptr
);
936 PUT_WORD( ptr
, newval
);
938 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
939 need to be updated as well. Problem is that we can't tell whether the atom is
940 using wide or narrow characters. For now, we'll just NULL out the className
941 fields, and emit a FIXME. */
942 if (offset
== GCW_ATOM
)
944 CLASS_SetClassNameA( wndPtr
->class, NULL
);
945 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
947 WIN_ReleaseWndPtr(wndPtr
);
952 /***********************************************************************
953 * SetClassLong16 (USER.132)
955 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
960 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
965 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
966 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
967 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
968 WIN_PROC_16
, WIN_PROC_CLASS
);
969 WIN_ReleaseWndPtr(wndPtr
);
972 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
974 return SetClassLongA( hwnd
, offset
, newval
);
979 /***********************************************************************
980 * SetClassLongA (USER32.467)
982 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
988 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
990 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
993 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
994 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
997 WARN("Invalid offset %d\n", offset
);
1005 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
1006 retval
= 0; /* Old value is now meaningless anyway */
1009 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
1011 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1012 WIN_PROC_32A
, WIN_PROC_CLASS
);
1014 case GCL_HBRBACKGROUND
:
1018 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
1020 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
1021 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
1022 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
1023 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
1025 WARN("Invalid offset %d\n", offset
);
1029 retval
= GET_DWORD(ptr
);
1030 PUT_DWORD( ptr
, newval
);
1032 WIN_ReleaseWndPtr(wndPtr
);
1037 /***********************************************************************
1038 * SetClassLongW (USER32.468)
1040 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1045 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1050 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1051 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
1052 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1053 WIN_PROC_32W
, WIN_PROC_CLASS
);
1054 WIN_ReleaseWndPtr(wndPtr
);
1057 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1058 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1059 WIN_ReleaseWndPtr(wndPtr
);
1060 return 0; /* Old value is now meaningless anyway */
1062 return SetClassLongA( hwnd
, offset
, newval
);
1067 /***********************************************************************
1068 * GetClassName16 (USER.58)
1070 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1072 return GetClassNameA( hwnd
, buffer
, count
);
1076 /***********************************************************************
1077 * GetClassNameA (USER32.217)
1079 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1083 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1084 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1086 WIN_ReleaseWndPtr(wndPtr
);
1087 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1092 /***********************************************************************
1093 * GetClassNameW (USER32.218)
1095 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1099 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1100 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1101 WIN_ReleaseWndPtr(wndPtr
);
1102 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1108 /***********************************************************************
1109 * GetClassInfo16 (USER.404)
1111 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASS16
*wc
)
1116 TRACE("%x %s %p\n",hInstance
, debugres_a(name
), wc
);
1118 hInstance
= GetExePtr( hInstance
);
1119 if (!(atom
= GlobalFindAtomA( name
)) ||
1120 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1122 if ((hInstance
!= classPtr
->hInstance
) &&
1123 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1125 wc
->style
= (UINT16
)classPtr
->style
;
1126 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1127 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1128 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1129 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1130 wc
->hIcon
= classPtr
->hIcon
;
1131 wc
->hCursor
= classPtr
->hCursor
;
1132 wc
->hbrBackground
= classPtr
->hbrBackground
;
1133 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1134 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1135 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1136 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1137 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1138 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1143 /***********************************************************************
1144 * GetClassInfoA (USER32.211)
1146 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1152 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1154 /* workaround: if hInstance=NULL you expect to get the system classes
1155 but this classes (as example from comctl32.dll SysListView) won't be
1156 registred with hInstance=NULL in WINE because of the late loading
1157 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1159 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1162 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1164 if (hInstance
) return FALSE
;
1166 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1169 wc
->style
= classPtr
->style
;
1170 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1172 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1173 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1174 wc
->hInstance
= classPtr
->hInstance
;
1175 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1176 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1177 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1178 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1179 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1184 /***********************************************************************
1185 * GetClassInfoW (USER32.214)
1187 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1193 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1195 if ( !(atom
=GlobalFindAtomW(name
)) ||
1196 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1200 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)) {
1204 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1206 wc
->style
= classPtr
->style
;
1207 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1209 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1210 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1211 wc
->hInstance
= classPtr
->hInstance
;
1212 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1213 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1214 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1215 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1216 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1221 /***********************************************************************
1222 * GetClassInfoEx16 (USER.398)
1224 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1225 * same in Win16 as in Win32. --AJ
1227 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASSEX16
*wc
)
1232 TRACE("%x %s %p\n",hInstance
,debugres_a( name
), wc
);
1234 hInstance
= GetExePtr( hInstance
);
1235 if (!(atom
= GlobalFindAtomA( name
)) ||
1236 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1237 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1238 wc
->style
= classPtr
->style
;
1239 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1240 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1241 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1242 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1243 wc
->hIcon
= classPtr
->hIcon
;
1244 wc
->hIconSm
= classPtr
->hIconSm
;
1245 wc
->hCursor
= classPtr
->hCursor
;
1246 wc
->hbrBackground
= classPtr
->hbrBackground
;
1247 wc
->lpszClassName
= (SEGPTR
)0;
1248 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1249 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1250 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1251 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1252 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1253 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1258 /***********************************************************************
1259 * GetClassInfoExA (USER32.212)
1261 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1267 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1269 if (!(atom
= GlobalFindAtomA( name
)) ||
1270 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1271 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1272 wc
->style
= classPtr
->style
;
1273 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1275 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1276 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1277 wc
->hInstance
= classPtr
->hInstance
;
1278 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1279 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1280 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1281 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1282 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1283 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1288 /***********************************************************************
1289 * GetClassInfoExW (USER32.213)
1291 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1297 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1299 if (!(atom
= GlobalFindAtomW( name
)) ||
1300 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1301 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1302 wc
->style
= classPtr
->style
;
1303 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1305 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1306 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1307 wc
->hInstance
= classPtr
->hInstance
;
1308 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1309 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1310 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1311 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1312 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1313 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1318 /***********************************************************************
1319 * ClassFirst (TOOLHELP.69)
1321 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1323 TRACE("%p\n",pClassEntry
);
1324 pClassEntry
->wNext
= 1;
1325 return ClassNext16( pClassEntry
);
1329 /***********************************************************************
1330 * ClassNext (TOOLHELP.70)
1332 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1335 CLASS
*class = firstClass
;
1337 TRACE("%p\n",pClassEntry
);
1339 if (!pClassEntry
->wNext
) return FALSE
;
1340 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1343 pClassEntry
->wNext
= 0;
1346 pClassEntry
->hInst
= class->hInstance
;
1347 pClassEntry
->wNext
++;
1348 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1349 sizeof(pClassEntry
->szClassName
) );