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 registered 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( const struct builtin_class_descr
*descr
)
356 if (!(atom
= GlobalAddAtomA( descr
->name
))) return 0;
358 if (!(classPtr
= CLASS_RegisterClass( atom
, 0, descr
->style
, 0, descr
->extra
)))
360 GlobalDeleteAtom( atom
);
364 classPtr
->hCursor
= LoadCursorA( 0, descr
->cursor
);
365 classPtr
->hbrBackground
= descr
->brush
;
367 if (descr
->procA
) WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)descr
->procA
,
368 WIN_PROC_32A
, WIN_PROC_CLASS
);
369 if (descr
->procW
) WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)descr
->procW
,
370 WIN_PROC_32W
, WIN_PROC_CLASS
);
375 /***********************************************************************
378 * Add a new window using this class, and return the necessary
379 * information for creating the window.
381 CLASS
*CLASS_AddWindow( ATOM atom
, HINSTANCE inst
, WINDOWPROCTYPE type
,
382 INT
*winExtra
, WNDPROC
*winproc
, DWORD
*style
, struct tagDCE
**dce
)
385 if (type
== WIN_PROC_16
) inst
= GetExePtr(inst
);
387 if (!(class = CLASS_FindClassByAtom( atom
, inst
))) return NULL
;
390 if (type
== WIN_PROC_32W
)
392 if (!(*winproc
= class->winprocW
)) *winproc
= class->winprocA
;
396 if (!(*winproc
= class->winprocA
)) *winproc
= class->winprocW
;
398 *winExtra
= class->cbWndExtra
;
399 *style
= class->style
;
405 /***********************************************************************
408 * Remove a window from the class window count.
410 void CLASS_RemoveWindow( CLASS
*cls
)
412 if (cls
&& cls
->cWindows
) cls
->cWindows
--;
416 /***********************************************************************
417 * RegisterClass16 (USER.57)
419 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
423 int iSmIconWidth
, iSmIconHeight
;
424 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
426 if (!(atom
= GlobalAddAtomA( MapSL(wc
->lpszClassName
) ))) return 0;
427 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
428 wc
->cbClsExtra
, wc
->cbWndExtra
)))
430 GlobalDeleteAtom( atom
);
434 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
435 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
436 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
437 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
438 wc
->cbWndExtra
, classPtr
,
439 HIWORD(wc
->lpszClassName
) ?
440 (char *)MapSL(wc
->lpszClassName
) : "" );
442 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
443 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
445 classPtr
->hIcon
= wc
->hIcon
;
446 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
447 iSmIconWidth
, iSmIconHeight
,
448 LR_COPYFROMRESOURCE
);
449 classPtr
->hCursor
= wc
->hCursor
;
450 classPtr
->hbrBackground
= wc
->hbrBackground
;
452 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
453 WIN_PROC_16
, WIN_PROC_CLASS
);
454 CLASS_SetMenuNameA( classPtr
, MapSL(wc
->lpszMenuName
) );
460 /***********************************************************************
461 * RegisterClassA (USER32.427)
463 * >0: Unique identifier
466 ATOM WINAPI
RegisterClassA( const WNDCLASSA
* wc
) /* [in] Address of structure with class data */
469 int iSmIconWidth
, iSmIconHeight
;
472 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
474 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
475 wc
->cbClsExtra
, wc
->cbWndExtra
)))
477 GlobalDeleteAtom( atom
);
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 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
498 WIN_PROC_32A
, WIN_PROC_CLASS
);
499 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
504 /***********************************************************************
505 * RegisterClassW (USER32.430)
507 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
510 int iSmIconWidth
, iSmIconHeight
;
513 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
515 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
516 wc
->cbClsExtra
, wc
->cbWndExtra
)))
518 GlobalDeleteAtom( atom
);
522 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
523 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
524 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
525 wc
->cbWndExtra
, classPtr
);
527 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
528 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
530 classPtr
->hIcon
= wc
->hIcon
;
531 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
532 iSmIconWidth
, iSmIconHeight
,
533 LR_COPYFROMRESOURCE
);
534 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
535 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
537 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
538 WIN_PROC_32W
, WIN_PROC_CLASS
);
539 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
544 /***********************************************************************
545 * RegisterClassEx16 (USER.397)
547 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
551 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
553 if (!(atom
= GlobalAddAtomA( MapSL(wc
->lpszClassName
) ))) return 0;
554 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
555 wc
->cbClsExtra
, wc
->cbWndExtra
)))
557 GlobalDeleteAtom( atom
);
561 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
562 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
563 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
564 wc
->cbWndExtra
, classPtr
);
566 classPtr
->hIcon
= wc
->hIcon
;
567 classPtr
->hIconSm
= wc
->hIconSm
;
568 classPtr
->hCursor
= wc
->hCursor
;
569 classPtr
->hbrBackground
= wc
->hbrBackground
;
571 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
572 WIN_PROC_16
, WIN_PROC_CLASS
);
573 CLASS_SetMenuNameA( classPtr
, MapSL(wc
->lpszMenuName
) );
578 /***********************************************************************
579 * RegisterClassExA (USER32.428)
581 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
586 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
588 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
589 wc
->cbClsExtra
, wc
->cbWndExtra
)))
591 GlobalDeleteAtom( atom
);
595 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
596 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
597 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
598 wc
->cbWndExtra
, classPtr
);
600 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
601 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
602 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
603 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
604 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
605 WIN_PROC_32A
, WIN_PROC_CLASS
);
606 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
611 /***********************************************************************
612 * RegisterClassExW (USER32.429)
614 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
619 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
621 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
622 wc
->cbClsExtra
, wc
->cbWndExtra
)))
624 GlobalDeleteAtom( atom
);
628 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
629 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
630 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
631 wc
->cbWndExtra
, classPtr
);
633 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
634 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
635 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
636 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
637 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
638 WIN_PROC_32W
, WIN_PROC_CLASS
);
639 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
644 /***********************************************************************
645 * UnregisterClass16 (USER.403)
647 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
649 return UnregisterClassA( className
, GetExePtr( hInstance
) );
653 /***********************************************************************
654 * UnregisterClassA (USER32.563)
657 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
662 TRACE("%s %x\n",debugres_a(className
), hInstance
);
664 if (!(atom
= GlobalFindAtomA( className
)))
666 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
669 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
670 (classPtr
->hInstance
!= hInstance
))
672 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
675 return CLASS_FreeClass( classPtr
);
678 /***********************************************************************
679 * UnregisterClassW (USER32.564)
681 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
686 TRACE("%s %x\n",debugres_w(className
), hInstance
);
688 if (!(atom
= GlobalFindAtomW( className
)))
690 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
693 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
694 (classPtr
->hInstance
!= hInstance
))
696 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
699 return CLASS_FreeClass( classPtr
);
702 /***********************************************************************
703 * GetClassWord16 (USER.129)
705 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
707 return GetClassWord( hwnd
, offset
);
711 /***********************************************************************
712 * GetClassWord (USER32.219)
714 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
719 TRACE("%x %x\n",hwnd
, offset
);
721 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
724 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
726 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
732 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
734 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
736 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
738 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
740 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
746 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
750 WARN("Invalid offset %d\n", offset
);
752 WIN_ReleaseWndPtr(wndPtr
);
757 /***********************************************************************
758 * GetClassLong16 (USER.131)
760 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
765 TRACE("%x %x\n",hwnd
, offset
);
770 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
771 ret
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_16
);
772 WIN_ReleaseWndPtr(wndPtr
);
775 ret
= GetClassLongA( hwnd
, offset
);
776 return (LONG
)SEGPTR_GET( (void *)ret
);
778 return GetClassLongA( hwnd
, offset
);
783 /***********************************************************************
784 * GetClassLongA (USER32.215)
786 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
791 TRACE("%x %x\n",hwnd
, offset
);
793 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
796 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
798 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
805 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
807 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
809 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
811 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
814 retvalue
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_32A
);
817 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
820 case GCL_HBRBACKGROUND
:
824 retvalue
= GetClassWord( hwnd
, offset
);
827 WARN("Invalid offset %d\n", offset
);
830 WIN_ReleaseWndPtr(wndPtr
);
835 /***********************************************************************
836 * GetClassLongW (USER32.216)
838 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
843 TRACE("%x %x\n",hwnd
, offset
);
848 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
849 retvalue
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_32W
);
850 WIN_ReleaseWndPtr(wndPtr
);
853 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
854 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
855 WIN_ReleaseWndPtr(wndPtr
);
858 return GetClassLongA( hwnd
, offset
);
863 /***********************************************************************
864 * SetClassWord16 (USER.130)
866 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
868 return SetClassWord( hwnd
, offset
, newval
);
872 /***********************************************************************
873 * SetClassWord (USER32.469)
875 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
881 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
883 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
886 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
887 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
890 WARN("Invalid offset %d\n", offset
);
891 WIN_ReleaseWndPtr(wndPtr
);
901 WIN_ReleaseWndPtr(wndPtr
);
902 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
903 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
904 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
905 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
906 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
907 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
909 WARN("Invalid offset %d\n", offset
);
910 WIN_ReleaseWndPtr(wndPtr
);
913 retval
= GET_WORD(ptr
);
914 PUT_WORD( ptr
, newval
);
915 WIN_ReleaseWndPtr(wndPtr
);
920 /***********************************************************************
921 * SetClassLong16 (USER.132)
923 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
928 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
933 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
934 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_16
);
935 WIN_ReleaseWndPtr(wndPtr
);
938 return SetClassLongA( hwnd
, offset
, (LONG
)MapSL(newval
) );
940 return SetClassLongA( hwnd
, offset
, newval
);
945 /***********************************************************************
946 * SetClassLongA (USER32.467)
948 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
954 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
956 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
959 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
960 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
963 WARN("Invalid offset %d\n", offset
);
971 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
972 retval
= 0; /* Old value is now meaningless anyway */
975 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_32A
);
977 case GCL_HBRBACKGROUND
:
981 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
983 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
984 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
985 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
986 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
988 WARN("Invalid offset %d\n", offset
);
992 retval
= GET_DWORD(ptr
);
993 PUT_DWORD( ptr
, newval
);
995 WIN_ReleaseWndPtr(wndPtr
);
1000 /***********************************************************************
1001 * SetClassLongW (USER32.468)
1003 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1008 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1013 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1014 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_32W
);
1015 WIN_ReleaseWndPtr(wndPtr
);
1018 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1019 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1020 WIN_ReleaseWndPtr(wndPtr
);
1021 return 0; /* Old value is now meaningless anyway */
1023 return SetClassLongA( hwnd
, offset
, newval
);
1028 /***********************************************************************
1029 * GetClassName16 (USER.58)
1031 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1033 return GetClassNameA( hwnd
, buffer
, count
);
1037 /***********************************************************************
1038 * GetClassNameA (USER32.217)
1040 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1044 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1045 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1047 WIN_ReleaseWndPtr(wndPtr
);
1048 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1053 /***********************************************************************
1054 * GetClassNameW (USER32.218)
1056 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1060 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1061 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1062 WIN_ReleaseWndPtr(wndPtr
);
1063 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1069 /***********************************************************************
1070 * GetClassInfo16 (USER.404)
1072 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASS16
*wc
)
1077 TRACE("%x %s %p\n",hInstance
, debugres_a(MapSL(name
)), wc
);
1079 hInstance
= GetExePtr( hInstance
);
1080 if (!(atom
= GlobalFindAtomA( MapSL(name
) )) ||
1081 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1083 if ((hInstance
!= classPtr
->hInstance
) &&
1084 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1086 wc
->style
= (UINT16
)classPtr
->style
;
1087 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1088 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1089 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1090 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1091 wc
->hIcon
= classPtr
->hIcon
;
1092 wc
->hCursor
= classPtr
->hCursor
;
1093 wc
->hbrBackground
= classPtr
->hbrBackground
;
1094 wc
->lpszClassName
= name
;
1095 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1096 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1097 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1102 /***********************************************************************
1103 * GetClassInfoA (USER32.211)
1105 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1111 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1113 /* workaround: if hInstance=NULL you expect to get the system classes
1114 but this classes (as example from comctl32.dll SysListView) won't be
1115 registered with hInstance=NULL in WINE because of the late loading
1116 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1118 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1121 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1122 classPtr
->hInstance
&&
1123 (hInstance
!= classPtr
->hInstance
))
1125 if (hInstance
) return FALSE
;
1126 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1129 wc
->style
= classPtr
->style
;
1130 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1131 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1132 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1133 wc
->hInstance
= hInstance
;
1134 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1135 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1136 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1137 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1138 wc
->lpszClassName
= name
;
1143 /***********************************************************************
1144 * GetClassInfoW (USER32.214)
1146 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1152 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1154 if ( !(atom
=GlobalFindAtomW(name
)) ||
1155 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1159 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1160 classPtr
->hInstance
&&
1161 (hInstance
!= classPtr
->hInstance
))
1163 if (hInstance
) return FALSE
;
1164 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1166 wc
->style
= classPtr
->style
;
1167 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1168 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1169 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1170 wc
->hInstance
= hInstance
;
1171 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1172 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1173 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1174 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1175 wc
->lpszClassName
= name
;
1180 /***********************************************************************
1181 * GetClassInfoEx16 (USER.398)
1183 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1184 * same in Win16 as in Win32. --AJ
1186 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASSEX16
*wc
)
1191 TRACE("%x %s %p\n",hInstance
,debugres_a( MapSL(name
) ), wc
);
1193 hInstance
= GetExePtr( hInstance
);
1194 if (!(atom
= GlobalFindAtomA( MapSL(name
) )) ||
1195 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1196 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1197 wc
->style
= classPtr
->style
;
1198 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1199 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1200 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1201 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1202 wc
->hIcon
= classPtr
->hIcon
;
1203 wc
->hIconSm
= classPtr
->hIconSm
;
1204 wc
->hCursor
= classPtr
->hCursor
;
1205 wc
->hbrBackground
= classPtr
->hbrBackground
;
1206 wc
->lpszClassName
= (SEGPTR
)0;
1207 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1208 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1209 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1210 wc
->lpszClassName
= name
;
1212 /* We must return the atom of the class here instead of just TRUE. */
1217 /***********************************************************************
1218 * GetClassInfoExA (USER32.212)
1220 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1226 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1228 if (!(atom
= GlobalFindAtomA( name
)) ||
1229 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1230 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1231 wc
->style
= classPtr
->style
;
1232 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1233 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1234 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1235 wc
->hInstance
= classPtr
->hInstance
;
1236 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1237 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1238 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1239 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1240 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1241 wc
->lpszClassName
= name
;
1243 /* We must return the atom of the class here instead of just TRUE. */
1248 /***********************************************************************
1249 * GetClassInfoExW (USER32.213)
1251 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1257 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1259 if (!(atom
= GlobalFindAtomW( name
)) ||
1260 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1261 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1262 wc
->style
= classPtr
->style
;
1263 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1264 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1265 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1266 wc
->hInstance
= classPtr
->hInstance
;
1267 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1268 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1269 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1270 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1271 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1272 wc
->lpszClassName
= name
;
1274 /* We must return the atom of the class here instead of just TRUE. */
1279 /***********************************************************************
1280 * ClassFirst (TOOLHELP.69)
1282 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1284 TRACE("%p\n",pClassEntry
);
1285 pClassEntry
->wNext
= 1;
1286 return ClassNext16( pClassEntry
);
1290 /***********************************************************************
1291 * ClassNext (TOOLHELP.70)
1293 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1296 CLASS
*class = firstClass
;
1298 TRACE("%p\n",pClassEntry
);
1300 if (!pClassEntry
->wNext
) return FALSE
;
1301 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1304 pClassEntry
->wNext
= 0;
1307 pClassEntry
->hInst
= class->hInstance
;
1308 pClassEntry
->wNext
++;
1309 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1310 sizeof(pClassEntry
->szClassName
) );