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"
29 #include "debugtools.h"
31 DEFAULT_DEBUG_CHANNEL(class);
33 typedef struct tagCLASS
35 struct tagCLASS
*next
; /* Next class */
36 struct tagCLASS
*prev
; /* Prev class */
37 UINT cWindows
; /* Count of existing windows */
38 UINT style
; /* Class style */
39 HWINDOWPROC winprocA
; /* Window procedure (ASCII) */
40 HWINDOWPROC winprocW
; /* Window procedure (Unicode) */
41 INT cbClsExtra
; /* Class extra bytes */
42 INT cbWndExtra
; /* Window extra bytes */
43 LPWSTR menuName
; /* Default menu name (Unicode followed by ASCII) */
44 struct tagDCE
*dce
; /* Class DCE (if CS_CLASSDC) */
45 HINSTANCE hInstance
; /* Module that created the task */
46 HICON hIcon
; /* Default icon */
47 HICON hIconSm
; /* Default small icon */
48 HCURSOR hCursor
; /* Default cursor */
49 HBRUSH hbrBackground
; /* Default background */
50 ATOM atomName
; /* Name of the class */
51 LONG wExtra
[1]; /* Class extra bytes */
54 static CLASS
*firstClass
;
57 /***********************************************************************
60 * Get the class winproc for a given proc type
62 static WNDPROC16
CLASS_GetProc( CLASS
*classPtr
, WINDOWPROCTYPE type
)
64 HWINDOWPROC proc
= classPtr
->winprocA
;
66 if (classPtr
->winprocW
)
68 /* if we have a Unicode proc, use it if we have no ASCII proc
69 * or if we have both and Unicode was requested
71 if (!proc
|| type
== WIN_PROC_32W
) proc
= classPtr
->winprocW
;
73 return WINPROC_GetProc( proc
, type
);
77 /***********************************************************************
80 * Set the class winproc for a given proc type.
81 * Returns the previous window proc.
83 static WNDPROC16
CLASS_SetProc( CLASS
*classPtr
, WNDPROC newproc
, WINDOWPROCTYPE type
)
85 HWINDOWPROC
*proc
= &classPtr
->winprocA
;
88 if (classPtr
->winprocW
)
90 /* if we have a Unicode proc, use it if we have no ASCII proc
91 * or if we have both and Unicode was requested
93 if (!*proc
|| type
== WIN_PROC_32W
) proc
= &classPtr
->winprocW
;
95 ret
= WINPROC_GetProc( *proc
, type
);
96 WINPROC_SetProc( proc
, (HWINDOWPROC
)newproc
, type
, WIN_PROC_CLASS
);
97 /* now free the one that we didn't set */
98 if (classPtr
->winprocA
&& classPtr
->winprocW
)
100 if (proc
== &classPtr
->winprocA
)
102 WINPROC_FreeProc( classPtr
->winprocW
, WIN_PROC_CLASS
);
103 classPtr
->winprocW
= 0;
107 WINPROC_FreeProc( classPtr
->winprocA
, WIN_PROC_CLASS
);
108 classPtr
->winprocA
= 0;
115 /***********************************************************************
118 * Get the menu name as a ASCII string.
120 inline static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
122 if (!HIWORD(classPtr
->menuName
)) return (LPSTR
)classPtr
->menuName
;
123 return (LPSTR
)(classPtr
->menuName
+ strlenW(classPtr
->menuName
) + 1);
127 /***********************************************************************
130 * Get the menu name as a Unicode string.
132 inline static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
134 return classPtr
->menuName
;
138 /***********************************************************************
141 * Set the menu name in a class structure by copying the string.
143 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
145 if (HIWORD(classPtr
->menuName
)) SEGPTR_FREE( classPtr
->menuName
);
148 DWORD lenA
= strlen(name
) + 1;
149 DWORD lenW
= MultiByteToWideChar( CP_ACP
, 0, name
, lenA
, NULL
, 0 );
150 classPtr
->menuName
= SEGPTR_ALLOC( lenA
+ lenW
*sizeof(WCHAR
) );
151 MultiByteToWideChar( CP_ACP
, 0, name
, lenA
, classPtr
->menuName
, lenW
);
152 memcpy( classPtr
->menuName
+ lenW
, name
, lenA
);
154 else classPtr
->menuName
= (LPWSTR
)name
;
158 /***********************************************************************
161 * Set the menu name in a class structure by copying the string.
163 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
165 if (HIWORD(classPtr
->menuName
)) SEGPTR_FREE( classPtr
->menuName
);
168 DWORD lenW
= strlenW(name
) + 1;
169 DWORD lenA
= WideCharToMultiByte( CP_ACP
, 0, name
, lenW
, NULL
, 0, NULL
, NULL
);
170 classPtr
->menuName
= SEGPTR_ALLOC( lenA
+ lenW
*sizeof(WCHAR
) );
171 memcpy( classPtr
->menuName
, name
, lenW
*sizeof(WCHAR
) );
172 WideCharToMultiByte( CP_ACP
, 0, name
, lenW
,
173 (char *)(classPtr
->menuName
+ lenW
), lenA
, NULL
, NULL
);
175 else classPtr
->menuName
= (LPWSTR
)name
;
179 /***********************************************************************
182 * Free a class structure.
184 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
186 TRACE("%p\n", classPtr
);
188 /* Check if we can remove this class */
190 if (classPtr
->cWindows
> 0)
192 SetLastError( ERROR_CLASS_HAS_WINDOWS
);
196 /* Remove the class from the linked list */
198 if (classPtr
->next
) classPtr
->next
->prev
= classPtr
->prev
;
199 if (classPtr
->prev
) classPtr
->prev
->next
= classPtr
->next
;
200 else firstClass
= classPtr
->next
;
202 /* Delete the class */
204 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
205 if (classPtr
->hbrBackground
> (HBRUSH
)(COLOR_GRADIENTINACTIVECAPTION
+ 1))
206 DeleteObject( classPtr
->hbrBackground
);
207 GlobalDeleteAtom( classPtr
->atomName
);
208 WINPROC_FreeProc( classPtr
->winprocA
, WIN_PROC_CLASS
);
209 WINPROC_FreeProc( classPtr
->winprocW
, WIN_PROC_CLASS
);
210 HeapFree( GetProcessHeap(), 0, classPtr
->menuName
);
211 HeapFree( GetProcessHeap(), 0, classPtr
);
216 /***********************************************************************
217 * CLASS_FreeModuleClasses
219 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
223 TRACE("0x%08x\n", hModule
);
225 for (ptr
= firstClass
; ptr
; ptr
= next
)
228 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
233 /***********************************************************************
234 * CLASS_FindClassByAtom
236 * Return a pointer to the class.
237 * hinstance has been normalized by the caller.
240 * 980805 a local class will be found now if registred with hInst=0
241 * and looed up with a hInst!=0. msmoney does it (jsch)
243 static CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
245 CLASS
* class, *tclass
=0;
247 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
249 /* First search task-specific classes */
251 for (class = firstClass
; (class); class = class->next
)
253 if (class->style
& CS_GLOBALCLASS
) continue;
254 if (class->atomName
== atom
)
256 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
258 TRACE("-- found local %p\n", class);
261 if (class->hInstance
==0) tclass
= class;
265 /* Then search global classes */
267 for (class = firstClass
; (class); class = class->next
)
269 if (!(class->style
& CS_GLOBALCLASS
)) continue;
270 if (class->atomName
== atom
)
272 TRACE("-- found global %p\n", class);
277 /* Then check if there was a local class with hInst=0*/
280 WARN("-- found local Class registred with hInst=0\n");
284 TRACE("-- not found\n");
289 /***********************************************************************
290 * CLASS_RegisterClass
292 * The real RegisterClass() functionality.
294 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
295 DWORD style
, INT classExtra
, INT winExtra
)
299 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x\n",
300 atom
, hInstance
, style
, classExtra
, winExtra
);
302 /* Check if a class with this name already exists */
303 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
306 /* Class can be created only if it is local and */
307 /* if the class with the same name is global. */
309 if ((style
& CS_GLOBALCLASS
) || !(classPtr
->style
& CS_GLOBALCLASS
))
311 SetLastError( ERROR_CLASS_ALREADY_EXISTS
);
316 /* Fix the extra bytes value */
318 if (classExtra
< 0) classExtra
= 0;
319 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
320 WARN("Class extra bytes %d is > 40\n", classExtra
);
321 if (winExtra
< 0) winExtra
= 0;
322 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
323 WARN("Win extra bytes %d is > 40\n", winExtra
);
325 /* Create the class */
327 classPtr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
,
328 sizeof(CLASS
) + classExtra
- sizeof(classPtr
->wExtra
) );
329 if (!classPtr
) return NULL
;
330 classPtr
->style
= style
;
331 classPtr
->cbWndExtra
= winExtra
;
332 classPtr
->cbClsExtra
= classExtra
;
333 classPtr
->hInstance
= hInstance
;
334 classPtr
->atomName
= atom
;
335 classPtr
->dce
= (style
& CS_CLASSDC
) ? DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
337 /* Other non-null values must be set by caller */
339 if ((classPtr
->next
= firstClass
)) firstClass
->prev
= classPtr
;
340 firstClass
= classPtr
;
345 /***********************************************************************
346 * CLASS_RegisterBuiltinClass
348 * Register a builtin control class.
349 * This allows having both ASCII and Unicode winprocs for the same class.
351 ATOM
CLASS_RegisterBuiltinClass( LPCSTR name
, DWORD style
, INT winExtra
, LPCSTR cursor
,
352 HBRUSH brush
, WNDPROC wndProcA
, WNDPROC wndProcW
)
357 if (!(atom
= GlobalAddAtomA( name
))) return 0;
359 if (!(classPtr
= CLASS_RegisterClass( atom
, 0, style
, 0, winExtra
)))
361 GlobalDeleteAtom( atom
);
365 classPtr
->hCursor
= LoadCursorA( 0, cursor
);
366 classPtr
->hbrBackground
= brush
;
368 if (wndProcA
) WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wndProcA
,
369 WIN_PROC_32A
, WIN_PROC_CLASS
);
370 if (wndProcW
) WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wndProcW
,
371 WIN_PROC_32W
, WIN_PROC_CLASS
);
376 /***********************************************************************
379 * Add a new window using this class, and return the necessary
380 * information for creating the window.
382 CLASS
*CLASS_AddWindow( ATOM atom
, HINSTANCE inst
, WINDOWPROCTYPE type
,
383 INT
*winExtra
, WNDPROC
*winproc
, DWORD
*style
, struct tagDCE
**dce
)
386 if (type
== WIN_PROC_16
) inst
= GetExePtr(inst
);
388 if (!(class = CLASS_FindClassByAtom( atom
, inst
))) return NULL
;
391 if (type
== WIN_PROC_32W
)
393 if (!(*winproc
= class->winprocW
)) *winproc
= class->winprocA
;
397 if (!(*winproc
= class->winprocA
)) *winproc
= class->winprocW
;
399 *winExtra
= class->cbWndExtra
;
400 *style
= class->style
;
406 /***********************************************************************
409 * Remove a window from the class window count.
411 void CLASS_RemoveWindow( CLASS
*cls
)
413 if (cls
&& cls
->cWindows
) cls
->cWindows
--;
417 /***********************************************************************
418 * RegisterClass16 (USER.57)
420 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
424 int iSmIconWidth
, iSmIconHeight
;
425 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
427 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
428 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
429 wc
->cbClsExtra
, wc
->cbWndExtra
)))
431 GlobalDeleteAtom( atom
);
435 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
436 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
437 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
438 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
439 wc
->cbWndExtra
, classPtr
,
440 HIWORD(wc
->lpszClassName
) ?
441 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
443 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
444 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
446 classPtr
->hIcon
= wc
->hIcon
;
447 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
448 iSmIconWidth
, iSmIconHeight
,
449 LR_COPYFROMRESOURCE
);
450 classPtr
->hCursor
= wc
->hCursor
;
451 classPtr
->hbrBackground
= wc
->hbrBackground
;
453 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
454 WIN_PROC_16
, WIN_PROC_CLASS
);
455 CLASS_SetMenuNameA( classPtr
, PTR_SEG_TO_LIN(wc
->lpszMenuName
) );
461 /***********************************************************************
462 * RegisterClassA (USER32.427)
464 * >0: Unique identifier
467 ATOM WINAPI
RegisterClassA( const WNDCLASSA
* wc
) /* [in] Address of structure with class data */
470 int iSmIconWidth
, iSmIconHeight
;
473 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
475 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
476 wc
->cbClsExtra
, wc
->cbWndExtra
)))
478 GlobalDeleteAtom( atom
);
482 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
483 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
484 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
485 wc
->cbWndExtra
, classPtr
,
486 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
488 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
489 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
491 classPtr
->hIcon
= wc
->hIcon
;
492 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
493 iSmIconWidth
, iSmIconHeight
,
494 LR_COPYFROMRESOURCE
);
495 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
496 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
498 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
499 WIN_PROC_32A
, WIN_PROC_CLASS
);
500 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
505 /***********************************************************************
506 * RegisterClassW (USER32.430)
508 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
511 int iSmIconWidth
, iSmIconHeight
;
514 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
516 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
517 wc
->cbClsExtra
, wc
->cbWndExtra
)))
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 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
539 WIN_PROC_32W
, WIN_PROC_CLASS
);
540 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
545 /***********************************************************************
546 * RegisterClassEx16 (USER.397)
548 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
552 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
554 if (!(atom
= GlobalAddAtomA( PTR_SEG_TO_LIN(wc
->lpszClassName
) ))) return 0;
555 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
556 wc
->cbClsExtra
, wc
->cbWndExtra
)))
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 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
573 WIN_PROC_16
, WIN_PROC_CLASS
);
574 CLASS_SetMenuNameA( classPtr
, PTR_SEG_TO_LIN(wc
->lpszMenuName
) );
579 /***********************************************************************
580 * RegisterClassExA (USER32.428)
582 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
587 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
589 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
590 wc
->cbClsExtra
, wc
->cbWndExtra
)))
592 GlobalDeleteAtom( atom
);
596 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
597 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
598 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
599 wc
->cbWndExtra
, classPtr
);
601 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
602 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
603 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
604 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
605 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
606 WIN_PROC_32A
, WIN_PROC_CLASS
);
607 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
612 /***********************************************************************
613 * RegisterClassExW (USER32.429)
615 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
620 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
622 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
623 wc
->cbClsExtra
, wc
->cbWndExtra
)))
625 GlobalDeleteAtom( atom
);
629 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
630 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
631 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
632 wc
->cbWndExtra
, classPtr
);
634 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
635 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
636 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
637 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
638 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
639 WIN_PROC_32W
, WIN_PROC_CLASS
);
640 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
645 /***********************************************************************
646 * UnregisterClass16 (USER.403)
648 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
650 return UnregisterClassA( className
, GetExePtr( hInstance
) );
654 /***********************************************************************
655 * UnregisterClassA (USER32.563)
658 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
663 TRACE("%s %x\n",debugres_a(className
), hInstance
);
665 if (!(atom
= GlobalFindAtomA( className
)))
667 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
670 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
671 (classPtr
->hInstance
!= hInstance
))
673 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
676 return CLASS_FreeClass( classPtr
);
679 /***********************************************************************
680 * UnregisterClassW (USER32.564)
682 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
687 TRACE("%s %x\n",debugres_w(className
), hInstance
);
689 if (!(atom
= GlobalFindAtomW( className
)))
691 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
694 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
695 (classPtr
->hInstance
!= hInstance
))
697 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
700 return CLASS_FreeClass( classPtr
);
703 /***********************************************************************
704 * GetClassWord16 (USER.129)
706 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
708 return GetClassWord( hwnd
, offset
);
712 /***********************************************************************
713 * GetClassWord (USER32.219)
715 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
720 TRACE("%x %x\n",hwnd
, offset
);
722 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
725 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
727 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
733 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
735 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
737 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
739 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
741 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
747 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
751 WARN("Invalid offset %d\n", offset
);
753 WIN_ReleaseWndPtr(wndPtr
);
758 /***********************************************************************
759 * GetClassLong16 (USER.131)
761 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
766 TRACE("%x %x\n",hwnd
, offset
);
771 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
772 ret
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_16
);
773 WIN_ReleaseWndPtr(wndPtr
);
776 ret
= GetClassLongA( hwnd
, offset
);
777 return (LONG
)SEGPTR_GET( (void *)ret
);
779 return GetClassLongA( hwnd
, offset
);
784 /***********************************************************************
785 * GetClassLongA (USER32.215)
787 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
792 TRACE("%x %x\n",hwnd
, offset
);
794 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
797 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
799 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
806 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
808 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
810 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
812 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
815 retvalue
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_32A
);
818 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
821 case GCL_HBRBACKGROUND
:
825 retvalue
= GetClassWord( hwnd
, offset
);
828 WARN("Invalid offset %d\n", offset
);
831 WIN_ReleaseWndPtr(wndPtr
);
836 /***********************************************************************
837 * GetClassLongW (USER32.216)
839 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
844 TRACE("%x %x\n",hwnd
, offset
);
849 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
850 retvalue
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_32W
);
851 WIN_ReleaseWndPtr(wndPtr
);
854 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
855 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
856 WIN_ReleaseWndPtr(wndPtr
);
859 return GetClassLongA( hwnd
, offset
);
864 /***********************************************************************
865 * SetClassWord16 (USER.130)
867 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
869 return SetClassWord( hwnd
, offset
, newval
);
873 /***********************************************************************
874 * SetClassWord (USER32.469)
876 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
882 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
884 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
887 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
888 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
891 WARN("Invalid offset %d\n", offset
);
892 WIN_ReleaseWndPtr(wndPtr
);
902 WIN_ReleaseWndPtr(wndPtr
);
903 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
904 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
905 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
906 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
907 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
908 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
910 WARN("Invalid offset %d\n", offset
);
911 WIN_ReleaseWndPtr(wndPtr
);
914 retval
= GET_WORD(ptr
);
915 PUT_WORD( ptr
, newval
);
916 WIN_ReleaseWndPtr(wndPtr
);
921 /***********************************************************************
922 * SetClassLong16 (USER.132)
924 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
929 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
934 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
935 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_16
);
936 WIN_ReleaseWndPtr(wndPtr
);
939 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
941 return SetClassLongA( hwnd
, offset
, newval
);
946 /***********************************************************************
947 * SetClassLongA (USER32.467)
949 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
955 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
957 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
960 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
961 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
964 WARN("Invalid offset %d\n", offset
);
972 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
973 retval
= 0; /* Old value is now meaningless anyway */
976 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_32A
);
978 case GCL_HBRBACKGROUND
:
982 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
984 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
985 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
986 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
987 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
989 WARN("Invalid offset %d\n", offset
);
993 retval
= GET_DWORD(ptr
);
994 PUT_DWORD( ptr
, newval
);
996 WIN_ReleaseWndPtr(wndPtr
);
1001 /***********************************************************************
1002 * SetClassLongW (USER32.468)
1004 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1009 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1014 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1015 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_32W
);
1016 WIN_ReleaseWndPtr(wndPtr
);
1019 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1020 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1021 WIN_ReleaseWndPtr(wndPtr
);
1022 return 0; /* Old value is now meaningless anyway */
1024 return SetClassLongA( hwnd
, offset
, newval
);
1029 /***********************************************************************
1030 * GetClassName16 (USER.58)
1032 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1034 return GetClassNameA( hwnd
, buffer
, count
);
1038 /***********************************************************************
1039 * GetClassNameA (USER32.217)
1041 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1045 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1046 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1048 WIN_ReleaseWndPtr(wndPtr
);
1049 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1054 /***********************************************************************
1055 * GetClassNameW (USER32.218)
1057 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1061 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1062 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1063 WIN_ReleaseWndPtr(wndPtr
);
1064 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1070 /***********************************************************************
1071 * GetClassInfo16 (USER.404)
1073 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASS16
*wc
)
1078 TRACE("%x %s %p\n",hInstance
, debugres_a(PTR_SEG_TO_LIN(name
)), wc
);
1080 hInstance
= GetExePtr( hInstance
);
1081 if (!(atom
= GlobalFindAtomA( PTR_SEG_TO_LIN(name
) )) ||
1082 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1084 if ((hInstance
!= classPtr
->hInstance
) &&
1085 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1087 wc
->style
= (UINT16
)classPtr
->style
;
1088 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1089 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1090 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1091 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1092 wc
->hIcon
= classPtr
->hIcon
;
1093 wc
->hCursor
= classPtr
->hCursor
;
1094 wc
->hbrBackground
= classPtr
->hbrBackground
;
1095 wc
->lpszClassName
= name
;
1096 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1097 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1098 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1103 /***********************************************************************
1104 * GetClassInfoA (USER32.211)
1106 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1112 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1114 /* workaround: if hInstance=NULL you expect to get the system classes
1115 but this classes (as example from comctl32.dll SysListView) won't be
1116 registered with hInstance=NULL in WINE because of the late loading
1117 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1119 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1122 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1123 classPtr
->hInstance
&&
1124 (hInstance
!= classPtr
->hInstance
))
1126 if (hInstance
) return FALSE
;
1127 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1130 wc
->style
= classPtr
->style
;
1131 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1132 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1133 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1134 wc
->hInstance
= hInstance
;
1135 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1136 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1137 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1138 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1139 wc
->lpszClassName
= name
;
1144 /***********************************************************************
1145 * GetClassInfoW (USER32.214)
1147 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1153 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1155 if ( !(atom
=GlobalFindAtomW(name
)) ||
1156 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1160 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1161 classPtr
->hInstance
&&
1162 (hInstance
!= classPtr
->hInstance
))
1164 if (hInstance
) return FALSE
;
1165 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1167 wc
->style
= classPtr
->style
;
1168 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1169 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1170 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1171 wc
->hInstance
= hInstance
;
1172 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1173 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1174 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1175 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1176 wc
->lpszClassName
= name
;
1181 /***********************************************************************
1182 * GetClassInfoEx16 (USER.398)
1184 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1185 * same in Win16 as in Win32. --AJ
1187 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASSEX16
*wc
)
1192 TRACE("%x %s %p\n",hInstance
,debugres_a( PTR_SEG_TO_LIN(name
) ), wc
);
1194 hInstance
= GetExePtr( hInstance
);
1195 if (!(atom
= GlobalFindAtomA( PTR_SEG_TO_LIN(name
) )) ||
1196 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1197 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1198 wc
->style
= classPtr
->style
;
1199 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1200 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1201 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1202 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1203 wc
->hIcon
= classPtr
->hIcon
;
1204 wc
->hIconSm
= classPtr
->hIconSm
;
1205 wc
->hCursor
= classPtr
->hCursor
;
1206 wc
->hbrBackground
= classPtr
->hbrBackground
;
1207 wc
->lpszClassName
= (SEGPTR
)0;
1208 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1209 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1210 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1211 wc
->lpszClassName
= name
;
1213 /* We must return the atom of the class here instead of just TRUE. */
1218 /***********************************************************************
1219 * GetClassInfoExA (USER32.212)
1221 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1227 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1229 if (!(atom
= GlobalFindAtomA( name
)) ||
1230 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1231 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1232 wc
->style
= classPtr
->style
;
1233 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1234 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1235 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1236 wc
->hInstance
= classPtr
->hInstance
;
1237 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1238 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1239 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1240 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1241 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1242 wc
->lpszClassName
= name
;
1244 /* We must return the atom of the class here instead of just TRUE. */
1249 /***********************************************************************
1250 * GetClassInfoExW (USER32.213)
1252 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1258 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1260 if (!(atom
= GlobalFindAtomW( name
)) ||
1261 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1262 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1263 wc
->style
= classPtr
->style
;
1264 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1265 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1266 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1267 wc
->hInstance
= classPtr
->hInstance
;
1268 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1269 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1270 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1271 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1272 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1273 wc
->lpszClassName
= name
;
1275 /* We must return the atom of the class here instead of just TRUE. */
1280 /***********************************************************************
1281 * ClassFirst (TOOLHELP.69)
1283 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1285 TRACE("%p\n",pClassEntry
);
1286 pClassEntry
->wNext
= 1;
1287 return ClassNext16( pClassEntry
);
1291 /***********************************************************************
1292 * ClassNext (TOOLHELP.70)
1294 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1297 CLASS
*class = firstClass
;
1299 TRACE("%p\n",pClassEntry
);
1301 if (!pClassEntry
->wNext
) return FALSE
;
1302 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1305 pClassEntry
->wNext
= 0;
1308 pClassEntry
->hInst
= class->hInstance
;
1309 pClassEntry
->wNext
++;
1310 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1311 sizeof(pClassEntry
->szClassName
) );