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"
27 #include "wine/winuser16.h"
29 DEFAULT_DEBUG_CHANNEL(class)
32 static CLASS
*firstClass
= NULL
;
35 /***********************************************************************
38 * Dump the content of a class structure to stderr.
40 void CLASS_DumpClass( CLASS
*ptr
)
42 char className
[MAX_CLASSNAME
+1];
45 if (ptr
->magic
!= CLASS_MAGIC
)
47 DPRINTF("%p is not a class\n", ptr
);
51 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
53 DPRINTF( "Class %p:\n", ptr
);
54 DPRINTF( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
55 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
56 "clsExtra=%d winExtra=%d #windows=%d\n",
57 ptr
->next
, ptr
->atomName
, className
, ptr
->style
,
58 (UINT
)ptr
->winproc
, ptr
->hInstance
, (UINT
)ptr
->dce
,
59 ptr
->hIcon
, ptr
->hCursor
, ptr
->hbrBackground
,
60 ptr
->cbClsExtra
, ptr
->cbWndExtra
, ptr
->cWindows
);
63 DPRINTF( "extra bytes:" );
64 for (i
= 0; i
< ptr
->cbClsExtra
; i
++)
65 DPRINTF( " %02x", *((BYTE
*)ptr
->wExtra
+i
) );
72 /***********************************************************************
75 * Walk the class list and print each class on stderr.
77 void CLASS_WalkClasses(void)
80 char className
[MAX_CLASSNAME
+1];
82 DPRINTF( " Class Name Style WndProc\n" );
83 for (ptr
= firstClass
; ptr
; ptr
= ptr
->next
)
85 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
86 DPRINTF( "%08x %-20.20s %08x %08x\n", (UINT
)ptr
, className
,
87 ptr
->style
, (UINT
)ptr
->winproc
);
93 /***********************************************************************
96 * Get the menu name as a ASCII string.
98 static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
100 if (!classPtr
->menuNameA
&& classPtr
->menuNameW
)
102 /* We need to copy the Unicode string */
103 classPtr
->menuNameA
= SEGPTR_STRDUP_WtoA( classPtr
->menuNameW
);
105 return classPtr
->menuNameA
;
109 /***********************************************************************
112 * Get the menu name as a Unicode string.
114 static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
116 if (!classPtr
->menuNameW
&& classPtr
->menuNameA
)
118 if (!HIWORD(classPtr
->menuNameA
))
119 return (LPWSTR
)classPtr
->menuNameA
;
120 /* Now we need to copy the ASCII string */
121 classPtr
->menuNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
122 classPtr
->menuNameA
);
124 return classPtr
->menuNameW
;
128 /***********************************************************************
131 * Set the menu name in a class structure by copying the string.
133 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
135 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
136 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
137 classPtr
->menuNameA
= SEGPTR_STRDUP( name
);
138 classPtr
->menuNameW
= 0;
142 /***********************************************************************
145 * Set the menu name in a class structure by copying the string.
147 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
151 CLASS_SetMenuNameA( classPtr
, (LPCSTR
)name
);
154 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
155 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
156 if ((classPtr
->menuNameW
= HeapAlloc( SystemHeap
, 0,
157 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
158 lstrcpyW( classPtr
->menuNameW
, name
);
159 classPtr
->menuNameA
= 0;
163 /***********************************************************************
164 * CLASS_GetClassNameA
166 * Get the clas name as a ASCII string.
168 static LPSTR
CLASS_GetClassNameA( CLASS
*classPtr
)
170 if (!classPtr
->classNameA
&& classPtr
->classNameW
)
172 /* We need to copy the Unicode string */
173 classPtr
->classNameA
= SEGPTR_STRDUP_WtoA( classPtr
->classNameW
);
175 return classPtr
->classNameA
;
179 /***********************************************************************
180 * CLASS_GetClassNameW
182 * Get the class name as a Unicode string.
184 static LPWSTR
CLASS_GetClassNameW( CLASS
*classPtr
)
186 if (!classPtr
->classNameW
&& classPtr
->classNameA
)
188 if (!HIWORD(classPtr
->classNameA
))
189 return (LPWSTR
)classPtr
->classNameA
;
190 /* Now we need to copy the ASCII string */
191 classPtr
->classNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
192 classPtr
->classNameA
);
194 return classPtr
->classNameW
;
197 /***********************************************************************
198 * CLASS_SetClassNameA
200 * Set the class name in a class structure by copying the string.
202 static void CLASS_SetClassNameA( CLASS
*classPtr
, LPCSTR name
)
204 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
205 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
206 classPtr
->classNameA
= SEGPTR_STRDUP( name
);
207 classPtr
->classNameW
= 0;
211 /***********************************************************************
212 * CLASS_SetClassNameW
214 * Set the class name in a class structure by copying the string.
216 static void CLASS_SetClassNameW( CLASS
*classPtr
, LPCWSTR name
)
220 CLASS_SetClassNameA( classPtr
, (LPCSTR
)name
);
223 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
224 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
225 if ((classPtr
->classNameW
= HeapAlloc( SystemHeap
, 0,
226 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
227 lstrcpyW( classPtr
->classNameW
, name
);
228 classPtr
->classNameA
= 0;
232 /***********************************************************************
235 * Free a class structure.
237 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
240 TRACE("%p \n", classPtr
);
242 /* Check if we can remove this class */
244 if (classPtr
->cWindows
> 0) return FALSE
;
246 /* Remove the class from the linked list */
248 for (ppClass
= &firstClass
; *ppClass
; ppClass
= &(*ppClass
)->next
)
249 if (*ppClass
== classPtr
) break;
252 ERR("Class list corrupted\n" );
255 *ppClass
= classPtr
->next
;
257 /* Delete the class */
259 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
260 if (classPtr
->hbrBackground
) DeleteObject( classPtr
->hbrBackground
);
261 GlobalDeleteAtom( classPtr
->atomName
);
262 CLASS_SetMenuNameA( classPtr
, NULL
);
263 CLASS_SetClassNameA( classPtr
, NULL
);
264 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
265 HeapFree( SystemHeap
, 0, classPtr
);
270 /***********************************************************************
271 * CLASS_FreeModuleClasses
273 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
277 TRACE("0x%08x \n", hModule
);
279 for (ptr
= firstClass
; ptr
; ptr
= next
)
282 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
287 /***********************************************************************
288 * CLASS_FindClassByAtom
290 * Return a pointer to the class.
291 * hinstance has been normalized by the caller.
294 * 980805 a local class will be found now if registred with hInst=0
295 * and looed up with a hInst!=0. msmoney does it (jsch)
297 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
298 { CLASS
* class, *tclass
=0;
300 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
302 /* First search task-specific classes */
304 for (class = firstClass
; (class); class = class->next
)
306 if (class->style
& CS_GLOBALCLASS
) continue;
307 if (class->atomName
== atom
)
309 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
311 TRACE("-- found local %p\n", class);
314 if (class->hInstance
==0) tclass
= class;
318 /* Then search global classes */
320 for (class = firstClass
; (class); class = class->next
)
322 if (!(class->style
& CS_GLOBALCLASS
)) continue;
323 if (class->atomName
== atom
)
325 TRACE("-- found global %p\n", class);
330 /* Then check if there was a local class with hInst=0*/
333 WARN("-- found local Class registred with hInst=0\n");
337 TRACE("-- not found\n");
342 /***********************************************************************
343 * CLASS_RegisterClass
345 * The real RegisterClass() functionality.
347 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
348 DWORD style
, INT classExtra
,
349 INT winExtra
, WNDPROC16 wndProc
,
350 WINDOWPROCTYPE wndProcType
)
354 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
355 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
357 /* Check if a class with this name already exists */
358 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
361 /* Class can be created only if it is local and */
362 /* if the class with the same name is global. */
364 if (style
& CS_GLOBALCLASS
) return NULL
;
365 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
368 /* Fix the extra bytes value */
370 if (classExtra
< 0) classExtra
= 0;
371 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
372 WARN("Class extra bytes %d is > 40\n", classExtra
);
373 if (winExtra
< 0) winExtra
= 0;
374 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
375 WARN("Win extra bytes %d is > 40\n", winExtra
);
377 /* Create the class */
379 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
380 classExtra
- sizeof(classPtr
->wExtra
) );
381 if (!classPtr
) return NULL
;
382 classPtr
->next
= firstClass
;
383 classPtr
->magic
= CLASS_MAGIC
;
384 classPtr
->cWindows
= 0;
385 classPtr
->style
= style
;
386 classPtr
->winproc
= (HWINDOWPROC
)0;
387 classPtr
->cbWndExtra
= winExtra
;
388 classPtr
->cbClsExtra
= classExtra
;
389 classPtr
->hInstance
= hInstance
;
390 classPtr
->atomName
= atom
;
391 classPtr
->menuNameA
= 0;
392 classPtr
->menuNameW
= 0;
393 classPtr
->classNameA
= 0;
394 classPtr
->classNameW
= 0;
395 classPtr
->dce
= (style
& CS_CLASSDC
) ?
396 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
398 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
400 /* Other values must be set by caller */
402 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
403 firstClass
= classPtr
;
408 /***********************************************************************
409 * RegisterClass16 (USER.57)
411 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
415 int iSmIconWidth
, iSmIconHeight
;
416 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
418 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
419 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
420 wc
->cbClsExtra
, wc
->cbWndExtra
,
421 wc
->lpfnWndProc
, WIN_PROC_16
)))
423 GlobalDeleteAtom( atom
);
427 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
428 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
429 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
430 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
431 wc
->cbWndExtra
, classPtr
,
432 HIWORD(wc
->lpszClassName
) ?
433 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
435 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
436 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
438 classPtr
->hIcon
= wc
->hIcon
;
439 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
440 iSmIconWidth
, iSmIconHeight
,
441 LR_COPYFROMRESOURCE
);
442 classPtr
->hCursor
= wc
->hCursor
;
443 classPtr
->hbrBackground
= wc
->hbrBackground
;
445 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
446 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
447 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
448 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
454 /***********************************************************************
455 * RegisterClass32A (USER32.427)
457 * >0: Unique identifier
460 ATOM WINAPI
RegisterClassA(
461 const WNDCLASSA
* wc
/* Address of structure with class data */
464 int iSmIconWidth
, iSmIconHeight
;
467 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
469 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
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 * RegisterClass32W (USER32.430)
506 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
509 int iSmIconWidth
, iSmIconHeight
;
512 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
514 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
517 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
518 wc
->cbClsExtra
, wc
->cbWndExtra
,
519 (WNDPROC16
)wc
->lpfnWndProc
,
522 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
523 GlobalDeleteAtom( atom
);
527 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
528 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
529 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
530 wc
->cbWndExtra
, classPtr
);
532 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
533 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
535 classPtr
->hIcon
= wc
->hIcon
;
536 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
537 iSmIconWidth
, iSmIconHeight
,
538 LR_COPYFROMRESOURCE
);
539 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
540 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
542 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
543 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
548 /***********************************************************************
549 * RegisterClassEx16 (USER.397)
551 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
555 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
557 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
558 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
559 wc
->cbClsExtra
, wc
->cbWndExtra
,
560 wc
->lpfnWndProc
, WIN_PROC_16
)))
562 GlobalDeleteAtom( atom
);
566 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
567 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
568 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
569 wc
->cbWndExtra
, classPtr
);
571 classPtr
->hIcon
= wc
->hIcon
;
572 classPtr
->hIconSm
= wc
->hIconSm
;
573 classPtr
->hCursor
= wc
->hCursor
;
574 classPtr
->hbrBackground
= wc
->hbrBackground
;
576 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
577 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
578 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
579 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
584 /***********************************************************************
585 * RegisterClassEx32A (USER32.428)
587 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
592 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
594 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
597 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
598 wc
->cbClsExtra
, wc
->cbWndExtra
,
599 (WNDPROC16
)wc
->lpfnWndProc
,
602 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
603 GlobalDeleteAtom( atom
);
607 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
608 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
609 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
610 wc
->cbWndExtra
, classPtr
);
612 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
613 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
614 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
615 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
616 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
617 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
622 /***********************************************************************
623 * RegisterClassEx32W (USER32.429)
625 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
630 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
632 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
635 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
636 wc
->cbClsExtra
, wc
->cbWndExtra
,
637 (WNDPROC16
)wc
->lpfnWndProc
,
640 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
641 GlobalDeleteAtom( atom
);
645 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
646 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
647 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
648 wc
->cbWndExtra
, classPtr
);
650 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
651 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
652 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
653 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
654 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
655 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
660 /***********************************************************************
661 * UnregisterClass16 (USER.403)
663 BOOL16 WINAPI
UnregisterClass16( SEGPTR className
, HINSTANCE16 hInstance
)
668 hInstance
= GetExePtr( hInstance
);
669 if (!(atom
= GlobalFindAtom16( className
))) return FALSE
;
670 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
671 (classPtr
->hInstance
!= hInstance
)) return FALSE
;
672 return CLASS_FreeClass( classPtr
);
676 /***********************************************************************
677 * UnregisterClass32A (USER32.563)
680 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
685 TRACE("%s %x\n",debugres_a(className
), hInstance
);
687 if (!(atom
= GlobalFindAtomA( className
)))
689 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
692 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
693 (classPtr
->hInstance
!= hInstance
))
695 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
698 if (!(ret
= CLASS_FreeClass( classPtr
)))
699 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
703 /***********************************************************************
704 * UnregisterClass32W (USER32.564)
706 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
711 TRACE("%s %x\n",debugres_w(className
), hInstance
);
713 if (!(atom
= GlobalFindAtomW( className
)))
715 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
718 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
719 (classPtr
->hInstance
!= hInstance
))
721 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
724 if (!(ret
= CLASS_FreeClass( classPtr
)))
725 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
729 /***********************************************************************
730 * GetClassWord16 (USER.129)
732 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
734 return GetClassWord( hwnd
, offset
);
738 /***********************************************************************
739 * GetClassWord32 (USER32.219)
741 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
746 TRACE("%x %x\n",hwnd
, offset
);
748 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
751 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
753 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
759 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
761 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
763 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
765 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
767 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
773 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
776 WARN("Invalid offset %d\n", offset
);
778 WIN_ReleaseWndPtr(wndPtr
);
783 /***********************************************************************
784 * GetClassLong16 (USER.131)
786 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
791 TRACE("%x %x\n",hwnd
, offset
);
796 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
797 ret
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
798 WIN_ReleaseWndPtr(wndPtr
);
801 ret
= GetClassLongA( hwnd
, offset
);
802 return (LONG
)SEGPTR_GET( (void *)ret
);
804 return GetClassLongA( hwnd
, offset
);
809 /***********************************************************************
810 * GetClassLong32A (USER32.215)
812 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
817 TRACE("%x %x\n",hwnd
, offset
);
819 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
822 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
824 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
831 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
833 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
835 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
837 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
840 retvalue
= (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
843 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
846 case GCL_HBRBACKGROUND
:
850 retvalue
= GetClassWord( hwnd
, offset
);
853 WARN("Invalid offset %d\n", offset
);
856 WIN_ReleaseWndPtr(wndPtr
);
861 /***********************************************************************
862 * GetClassLong32W (USER32.216)
864 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
869 TRACE("%x %x\n",hwnd
, offset
);
874 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
875 retvalue
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
876 WIN_ReleaseWndPtr(wndPtr
);
879 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
880 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
881 WIN_ReleaseWndPtr(wndPtr
);
884 return GetClassLongA( hwnd
, offset
);
889 /***********************************************************************
890 * SetClassWord16 (USER.130)
892 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
894 return SetClassWord( hwnd
, offset
, newval
);
898 /***********************************************************************
899 * SetClassWord32 (USER32.469)
901 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
907 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
909 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
912 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
913 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
916 WARN("Invalid offset %d\n", offset
);
917 WIN_ReleaseWndPtr(wndPtr
);
927 WIN_ReleaseWndPtr(wndPtr
);
928 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
929 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
930 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
931 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
932 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
933 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
935 WARN("Invalid offset %d\n", offset
);
936 WIN_ReleaseWndPtr(wndPtr
);
939 retval
= GET_WORD(ptr
);
940 PUT_WORD( ptr
, newval
);
942 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
943 need to be updated as well. Problem is that we can't tell whether the atom is
944 using wide or narrow characters. For now, we'll just NULL out the className
945 fields, and emit a FIXME. */
946 if (offset
== GCW_ATOM
)
948 CLASS_SetClassNameA( wndPtr
->class, NULL
);
949 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
951 WIN_ReleaseWndPtr(wndPtr
);
956 /***********************************************************************
957 * SetClassLong16 (USER.132)
959 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
964 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
969 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
970 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
971 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
972 WIN_PROC_16
, WIN_PROC_CLASS
);
973 WIN_ReleaseWndPtr(wndPtr
);
976 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
978 return SetClassLongA( hwnd
, offset
, newval
);
983 /***********************************************************************
984 * SetClassLong32A (USER32.467)
986 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
992 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
994 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
997 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
998 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
1001 WARN("Invalid offset %d\n", offset
);
1009 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
1010 retval
= 0; /* Old value is now meaningless anyway */
1013 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
1015 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1016 WIN_PROC_32A
, WIN_PROC_CLASS
);
1018 case GCL_HBRBACKGROUND
:
1022 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
1024 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
1025 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
1026 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
1027 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
1029 WARN("Invalid offset %d\n", offset
);
1033 retval
= GET_DWORD(ptr
);
1034 PUT_DWORD( ptr
, newval
);
1036 WIN_ReleaseWndPtr(wndPtr
);
1041 /***********************************************************************
1042 * SetClassLong32W (USER32.468)
1044 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1049 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1054 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1055 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
1056 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1057 WIN_PROC_32W
, WIN_PROC_CLASS
);
1058 WIN_ReleaseWndPtr(wndPtr
);
1061 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1062 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1063 WIN_ReleaseWndPtr(wndPtr
);
1064 return 0; /* Old value is now meaningless anyway */
1066 return SetClassLongA( hwnd
, offset
, newval
);
1071 /***********************************************************************
1072 * GetClassName16 (USER.58)
1074 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1078 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1079 retvalue
= GlobalGetAtomName16( wndPtr
->class->atomName
, buffer
, count
);
1080 WIN_ReleaseWndPtr(wndPtr
);
1085 /***********************************************************************
1086 * GetClassName32A (USER32.217)
1088 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1092 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1093 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1095 WIN_ReleaseWndPtr(wndPtr
);
1096 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1101 /***********************************************************************
1102 * GetClassName32W (USER32.218)
1104 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1108 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1109 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1110 WIN_ReleaseWndPtr(wndPtr
);
1111 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1117 /***********************************************************************
1118 * GetClassInfo16 (USER.404)
1120 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
,
1126 TRACE("%x %p %p\n",hInstance
, PTR_SEG_TO_LIN (name
), wc
);
1128 hInstance
= GetExePtr( hInstance
);
1129 if (!(atom
= GlobalFindAtom16( name
)) ||
1130 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1132 if ((hInstance
!= classPtr
->hInstance
) &&
1133 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1135 wc
->style
= (UINT16
)classPtr
->style
;
1136 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1137 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1138 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1139 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1140 wc
->hIcon
= classPtr
->hIcon
;
1141 wc
->hCursor
= classPtr
->hCursor
;
1142 wc
->hbrBackground
= classPtr
->hbrBackground
;
1143 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1144 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1145 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1146 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1147 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1148 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1153 /***********************************************************************
1154 * GetClassInfo32A (USER32.211)
1156 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1162 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1164 /* workaround: if hInstance=NULL you expect to get the system classes
1165 but this classes (as example from comctl32.dll SysListView) won't be
1166 registred with hInstance=NULL in WINE because of the late loading
1167 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1169 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1172 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1174 if (hInstance
) return FALSE
;
1176 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1179 wc
->style
= classPtr
->style
;
1180 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1182 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1183 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1184 wc
->hInstance
= classPtr
->hInstance
;
1185 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1186 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1187 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1188 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1189 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1194 /***********************************************************************
1195 * GetClassInfo32W (USER32.214)
1197 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1203 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1205 if ( !(atom
=GlobalFindAtomW(name
)) ||
1206 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1210 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)) {
1214 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1216 wc
->style
= classPtr
->style
;
1217 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1219 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1220 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1221 wc
->hInstance
= classPtr
->hInstance
;
1222 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1223 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1224 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1225 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1226 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1231 /***********************************************************************
1232 * GetClassInfoEx16 (USER.398)
1234 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1235 * same in Win16 as in Win32. --AJ
1237 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
,
1243 TRACE("%x %p %p\n",hInstance
,PTR_SEG_TO_LIN( name
), wc
);
1245 hInstance
= GetExePtr( hInstance
);
1246 if (!(atom
= GlobalFindAtom16( name
)) ||
1247 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1248 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1249 wc
->style
= classPtr
->style
;
1250 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1251 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1252 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1253 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1254 wc
->hIcon
= classPtr
->hIcon
;
1255 wc
->hIconSm
= classPtr
->hIconSm
;
1256 wc
->hCursor
= classPtr
->hCursor
;
1257 wc
->hbrBackground
= classPtr
->hbrBackground
;
1258 wc
->lpszClassName
= (SEGPTR
)0;
1259 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1260 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1261 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1262 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1263 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1264 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1269 /***********************************************************************
1270 * GetClassInfoEx32A (USER32.212)
1272 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1278 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1280 if (!(atom
= GlobalFindAtomA( name
)) ||
1281 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1282 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1283 wc
->style
= classPtr
->style
;
1284 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1286 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1287 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1288 wc
->hInstance
= classPtr
->hInstance
;
1289 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1290 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1291 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1292 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1293 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1294 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1299 /***********************************************************************
1300 * GetClassInfoEx32W (USER32.213)
1302 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1308 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1310 if (!(atom
= GlobalFindAtomW( name
)) ||
1311 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1312 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1313 wc
->style
= classPtr
->style
;
1314 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1316 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1317 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1318 wc
->hInstance
= classPtr
->hInstance
;
1319 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1320 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1321 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1322 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1323 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1324 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1329 /***********************************************************************
1330 * ClassFirst (TOOLHELP.69)
1332 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1334 TRACE("%p\n",pClassEntry
);
1335 pClassEntry
->wNext
= 1;
1336 return ClassNext16( pClassEntry
);
1340 /***********************************************************************
1341 * ClassNext (TOOLHELP.70)
1343 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1346 CLASS
*class = firstClass
;
1348 TRACE("%p\n",pClassEntry
);
1350 if (!pClassEntry
->wNext
) return FALSE
;
1351 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1354 pClassEntry
->wNext
= 0;
1357 pClassEntry
->hInst
= class->hInstance
;
1358 pClassEntry
->wNext
++;
1359 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1360 sizeof(pClassEntry
->szClassName
) );