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( const WNDCLASSA
* wc
) /* Address of structure with class data */
466 int iSmIconWidth
, iSmIconHeight
;
469 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
471 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
472 wc
->cbClsExtra
, wc
->cbWndExtra
,
473 (WNDPROC16
)wc
->lpfnWndProc
,
475 { GlobalDeleteAtom( atom
);
476 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
480 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
481 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
482 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
483 wc
->cbWndExtra
, classPtr
,
484 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
486 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
487 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
489 classPtr
->hIcon
= wc
->hIcon
;
490 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
491 iSmIconWidth
, iSmIconHeight
,
492 LR_COPYFROMRESOURCE
);
493 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
494 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
496 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
497 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
502 /***********************************************************************
503 * RegisterClassW (USER32.430)
505 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
508 int iSmIconWidth
, iSmIconHeight
;
511 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
513 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
514 wc
->cbClsExtra
, wc
->cbWndExtra
,
515 (WNDPROC16
)wc
->lpfnWndProc
,
518 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
519 GlobalDeleteAtom( atom
);
523 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
524 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
525 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
526 wc
->cbWndExtra
, classPtr
);
528 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
529 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
531 classPtr
->hIcon
= wc
->hIcon
;
532 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
533 iSmIconWidth
, iSmIconHeight
,
534 LR_COPYFROMRESOURCE
);
535 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
536 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
538 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
539 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
544 /***********************************************************************
545 * RegisterClassEx16 (USER.397)
547 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
551 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
553 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
554 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
555 wc
->cbClsExtra
, wc
->cbWndExtra
,
556 wc
->lpfnWndProc
, WIN_PROC_16
)))
558 GlobalDeleteAtom( atom
);
562 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
563 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
564 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
565 wc
->cbWndExtra
, classPtr
);
567 classPtr
->hIcon
= wc
->hIcon
;
568 classPtr
->hIconSm
= wc
->hIconSm
;
569 classPtr
->hCursor
= wc
->hCursor
;
570 classPtr
->hbrBackground
= wc
->hbrBackground
;
572 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
573 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
574 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
575 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
580 /***********************************************************************
581 * RegisterClassExA (USER32.428)
583 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
588 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
590 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
591 wc
->cbClsExtra
, wc
->cbWndExtra
,
592 (WNDPROC16
)wc
->lpfnWndProc
,
595 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
596 GlobalDeleteAtom( atom
);
600 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
601 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
602 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
603 wc
->cbWndExtra
, classPtr
);
605 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
606 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
607 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
608 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
609 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
610 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
615 /***********************************************************************
616 * RegisterClassExW (USER32.429)
618 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
623 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
625 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
626 wc
->cbClsExtra
, wc
->cbWndExtra
,
627 (WNDPROC16
)wc
->lpfnWndProc
,
630 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
631 GlobalDeleteAtom( atom
);
635 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
636 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
637 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
638 wc
->cbWndExtra
, classPtr
);
640 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
641 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
642 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
643 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
644 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
645 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
650 /***********************************************************************
651 * UnregisterClass16 (USER.403)
653 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
655 return UnregisterClassA( className
, GetExePtr( hInstance
) );
659 /***********************************************************************
660 * UnregisterClassA (USER32.563)
663 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
668 TRACE("%s %x\n",debugres_a(className
), hInstance
);
670 if (!(atom
= GlobalFindAtomA( className
)))
672 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
675 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
676 (classPtr
->hInstance
!= hInstance
))
678 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
681 if (!(ret
= CLASS_FreeClass( classPtr
)))
682 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
686 /***********************************************************************
687 * UnregisterClassW (USER32.564)
689 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
694 TRACE("%s %x\n",debugres_w(className
), hInstance
);
696 if (!(atom
= GlobalFindAtomW( className
)))
698 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
701 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
702 (classPtr
->hInstance
!= hInstance
))
704 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
707 if (!(ret
= CLASS_FreeClass( classPtr
)))
708 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
712 /***********************************************************************
713 * GetClassWord16 (USER.129)
715 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
717 return GetClassWord( hwnd
, offset
);
721 /***********************************************************************
722 * GetClassWord (USER32.219)
724 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
729 TRACE("%x %x\n",hwnd
, offset
);
731 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
734 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
736 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
742 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
744 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
746 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
748 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
750 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
756 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
760 WARN("Invalid offset %d\n", offset
);
762 WIN_ReleaseWndPtr(wndPtr
);
767 /***********************************************************************
768 * GetClassLong16 (USER.131)
770 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
775 TRACE("%x %x\n",hwnd
, offset
);
780 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
781 ret
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
782 WIN_ReleaseWndPtr(wndPtr
);
785 ret
= GetClassLongA( hwnd
, offset
);
786 return (LONG
)SEGPTR_GET( (void *)ret
);
788 return GetClassLongA( hwnd
, offset
);
793 /***********************************************************************
794 * GetClassLongA (USER32.215)
796 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
801 TRACE("%x %x\n",hwnd
, offset
);
803 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
806 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
808 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
815 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
817 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
819 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
821 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
824 retvalue
= (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
827 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
830 case GCL_HBRBACKGROUND
:
834 retvalue
= GetClassWord( hwnd
, offset
);
837 WARN("Invalid offset %d\n", offset
);
840 WIN_ReleaseWndPtr(wndPtr
);
845 /***********************************************************************
846 * GetClassLongW (USER32.216)
848 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
853 TRACE("%x %x\n",hwnd
, offset
);
858 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
859 retvalue
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
860 WIN_ReleaseWndPtr(wndPtr
);
863 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
864 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
865 WIN_ReleaseWndPtr(wndPtr
);
868 return GetClassLongA( hwnd
, offset
);
873 /***********************************************************************
874 * SetClassWord16 (USER.130)
876 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
878 return SetClassWord( hwnd
, offset
, newval
);
882 /***********************************************************************
883 * SetClassWord (USER32.469)
885 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
891 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
893 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
896 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
897 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
900 WARN("Invalid offset %d\n", offset
);
901 WIN_ReleaseWndPtr(wndPtr
);
911 WIN_ReleaseWndPtr(wndPtr
);
912 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
913 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
914 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
915 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
916 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
917 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
919 WARN("Invalid offset %d\n", offset
);
920 WIN_ReleaseWndPtr(wndPtr
);
923 retval
= GET_WORD(ptr
);
924 PUT_WORD( ptr
, newval
);
926 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
927 need to be updated as well. Problem is that we can't tell whether the atom is
928 using wide or narrow characters. For now, we'll just NULL out the className
929 fields, and emit a FIXME. */
930 if (offset
== GCW_ATOM
)
932 CLASS_SetClassNameA( wndPtr
->class, NULL
);
933 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
935 WIN_ReleaseWndPtr(wndPtr
);
940 /***********************************************************************
941 * SetClassLong16 (USER.132)
943 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
948 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
953 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
954 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
955 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
956 WIN_PROC_16
, WIN_PROC_CLASS
);
957 WIN_ReleaseWndPtr(wndPtr
);
960 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
962 return SetClassLongA( hwnd
, offset
, newval
);
967 /***********************************************************************
968 * SetClassLongA (USER32.467)
970 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
976 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
978 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
981 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
982 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
985 WARN("Invalid offset %d\n", offset
);
993 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
994 retval
= 0; /* Old value is now meaningless anyway */
997 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
999 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1000 WIN_PROC_32A
, WIN_PROC_CLASS
);
1002 case GCL_HBRBACKGROUND
:
1006 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
1008 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
1009 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
1010 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
1011 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
1013 WARN("Invalid offset %d\n", offset
);
1017 retval
= GET_DWORD(ptr
);
1018 PUT_DWORD( ptr
, newval
);
1020 WIN_ReleaseWndPtr(wndPtr
);
1025 /***********************************************************************
1026 * SetClassLongW (USER32.468)
1028 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1033 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1038 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1039 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
1040 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1041 WIN_PROC_32W
, WIN_PROC_CLASS
);
1042 WIN_ReleaseWndPtr(wndPtr
);
1045 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1046 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1047 WIN_ReleaseWndPtr(wndPtr
);
1048 return 0; /* Old value is now meaningless anyway */
1050 return SetClassLongA( hwnd
, offset
, newval
);
1055 /***********************************************************************
1056 * GetClassName16 (USER.58)
1058 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1060 return GetClassNameA( hwnd
, buffer
, count
);
1064 /***********************************************************************
1065 * GetClassNameA (USER32.217)
1067 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1071 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1072 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1074 WIN_ReleaseWndPtr(wndPtr
);
1075 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1080 /***********************************************************************
1081 * GetClassNameW (USER32.218)
1083 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1087 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1088 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1089 WIN_ReleaseWndPtr(wndPtr
);
1090 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1096 /***********************************************************************
1097 * GetClassInfo16 (USER.404)
1099 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASS16
*wc
)
1104 TRACE("%x %s %p\n",hInstance
, debugres_a(name
), wc
);
1106 hInstance
= GetExePtr( hInstance
);
1107 if (!(atom
= GlobalFindAtomA( name
)) ||
1108 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1110 if ((hInstance
!= classPtr
->hInstance
) &&
1111 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1113 wc
->style
= (UINT16
)classPtr
->style
;
1114 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1115 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1116 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1117 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1118 wc
->hIcon
= classPtr
->hIcon
;
1119 wc
->hCursor
= classPtr
->hCursor
;
1120 wc
->hbrBackground
= classPtr
->hbrBackground
;
1121 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1122 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1123 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1124 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1125 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1126 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1131 /***********************************************************************
1132 * GetClassInfoA (USER32.211)
1134 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1140 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1142 /* workaround: if hInstance=NULL you expect to get the system classes
1143 but this classes (as example from comctl32.dll SysListView) won't be
1144 registered with hInstance=NULL in WINE because of the late loading
1145 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1147 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1150 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1151 classPtr
->hInstance
&&
1152 (hInstance
!= classPtr
->hInstance
))
1154 if (hInstance
) return FALSE
;
1155 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1158 wc
->style
= classPtr
->style
;
1159 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1161 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1162 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1163 wc
->hInstance
= hInstance
;
1164 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1165 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1166 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1167 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1168 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1173 /***********************************************************************
1174 * GetClassInfoW (USER32.214)
1176 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1182 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1184 if ( !(atom
=GlobalFindAtomW(name
)) ||
1185 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1189 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1190 classPtr
->hInstance
&&
1191 (hInstance
!= classPtr
->hInstance
))
1193 if (hInstance
) return FALSE
;
1194 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1196 wc
->style
= classPtr
->style
;
1197 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1199 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1200 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1201 wc
->hInstance
= hInstance
;
1202 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1203 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1204 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1205 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1206 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1211 /***********************************************************************
1212 * GetClassInfoEx16 (USER.398)
1214 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1215 * same in Win16 as in Win32. --AJ
1217 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, LPCSTR name
, WNDCLASSEX16
*wc
)
1222 TRACE("%x %s %p\n",hInstance
,debugres_a( name
), wc
);
1224 hInstance
= GetExePtr( hInstance
);
1225 if (!(atom
= GlobalFindAtomA( name
)) ||
1226 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1227 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1228 wc
->style
= classPtr
->style
;
1229 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1230 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1231 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1232 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1233 wc
->hIcon
= classPtr
->hIcon
;
1234 wc
->hIconSm
= classPtr
->hIconSm
;
1235 wc
->hCursor
= classPtr
->hCursor
;
1236 wc
->hbrBackground
= classPtr
->hbrBackground
;
1237 wc
->lpszClassName
= (SEGPTR
)0;
1238 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1239 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1240 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1241 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1242 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1243 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1245 /* We must return the atom of the class here instead of just TRUE. */
1250 /***********************************************************************
1251 * GetClassInfoExA (USER32.212)
1253 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1259 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1261 if (!(atom
= GlobalFindAtomA( name
)) ||
1262 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1263 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1264 wc
->style
= classPtr
->style
;
1265 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1267 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1268 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1269 wc
->hInstance
= classPtr
->hInstance
;
1270 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1271 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1272 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1273 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1274 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1275 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1277 /* We must return the atom of the class here instead of just TRUE. */
1282 /***********************************************************************
1283 * GetClassInfoExW (USER32.213)
1285 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1291 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1293 if (!(atom
= GlobalFindAtomW( name
)) ||
1294 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1295 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1296 wc
->style
= classPtr
->style
;
1297 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1299 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1300 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1301 wc
->hInstance
= classPtr
->hInstance
;
1302 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1303 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1304 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1305 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1306 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1307 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1309 /* We must return the atom of the class here instead of just TRUE. */
1314 /***********************************************************************
1315 * ClassFirst (TOOLHELP.69)
1317 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1319 TRACE("%p\n",pClassEntry
);
1320 pClassEntry
->wNext
= 1;
1321 return ClassNext16( pClassEntry
);
1325 /***********************************************************************
1326 * ClassNext (TOOLHELP.70)
1328 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1331 CLASS
*class = firstClass
;
1333 TRACE("%p\n",pClassEntry
);
1335 if (!pClassEntry
->wNext
) return FALSE
;
1336 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1339 pClassEntry
->wNext
= 0;
1342 pClassEntry
->hInst
= class->hInstance
;
1343 pClassEntry
->wNext
++;
1344 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1345 sizeof(pClassEntry
->szClassName
) );