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.
16 #include "wine/port.h"
21 #include "wine/winbase16.h"
25 #include "wine/winuser16.h"
26 #include "wine/unicode.h"
33 #include "debugtools.h"
35 DEFAULT_DEBUG_CHANNEL(class);
37 typedef struct tagCLASS
39 struct tagCLASS
*next
; /* Next class */
40 struct tagCLASS
*prev
; /* Prev class */
41 UINT cWindows
; /* Count of existing windows */
42 UINT style
; /* Class style */
43 HWINDOWPROC winprocA
; /* Window procedure (ASCII) */
44 HWINDOWPROC winprocW
; /* Window procedure (Unicode) */
45 INT cbClsExtra
; /* Class extra bytes */
46 INT cbWndExtra
; /* Window extra bytes */
47 LPWSTR menuName
; /* Default menu name (Unicode followed by ASCII) */
48 struct tagDCE
*dce
; /* Class DCE (if CS_CLASSDC) */
49 HINSTANCE hInstance
; /* Module that created the task */
50 HICON hIcon
; /* Default icon */
51 HICON hIconSm
; /* Default small icon */
52 HCURSOR hCursor
; /* Default cursor */
53 HBRUSH hbrBackground
; /* Default background */
54 ATOM atomName
; /* Name of the class */
57 static CLASS
*firstClass
;
59 /***********************************************************************
62 static CLASS
*get_class_ptr( HWND hwnd
, BOOL write_access
)
64 WND
*ptr
= WIN_GetPtr( hwnd
);
68 if (ptr
!= WND_OTHER_PROCESS
) return ptr
->class;
69 if (IsWindow( hwnd
)) /* check other processes */
73 /* modifying classes in other processes is not allowed */
74 SetLastError( ERROR_ACCESS_DENIED
);
77 FIXME( "reading from class of other process window %04x\n", hwnd
);
78 /* DbgBreakPoint(); */
81 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
86 /***********************************************************************
89 inline static void release_class_ptr( CLASS
*ptr
)
95 /***********************************************************************
98 * Get the class winproc for a given proc type
100 static WNDPROC16
CLASS_GetProc( CLASS
*classPtr
, WINDOWPROCTYPE type
)
102 HWINDOWPROC proc
= classPtr
->winprocA
;
104 if (classPtr
->winprocW
)
106 /* if we have a Unicode proc, use it if we have no ASCII proc
107 * or if we have both and Unicode was requested
109 if (!proc
|| type
== WIN_PROC_32W
) proc
= classPtr
->winprocW
;
111 return WINPROC_GetProc( proc
, type
);
115 /***********************************************************************
118 * Set the class winproc for a given proc type.
119 * Returns the previous window proc.
121 static WNDPROC16
CLASS_SetProc( CLASS
*classPtr
, WNDPROC newproc
, WINDOWPROCTYPE type
)
123 HWINDOWPROC
*proc
= &classPtr
->winprocA
;
126 if (classPtr
->winprocW
)
128 /* if we have a Unicode proc, use it if we have no ASCII proc
129 * or if we have both and Unicode was requested
131 if (!*proc
|| type
== WIN_PROC_32W
) proc
= &classPtr
->winprocW
;
133 ret
= WINPROC_GetProc( *proc
, type
);
134 WINPROC_SetProc( proc
, (HWINDOWPROC
)newproc
, type
, WIN_PROC_CLASS
);
135 /* now free the one that we didn't set */
136 if (classPtr
->winprocA
&& classPtr
->winprocW
)
138 if (proc
== &classPtr
->winprocA
)
140 WINPROC_FreeProc( classPtr
->winprocW
, WIN_PROC_CLASS
);
141 classPtr
->winprocW
= 0;
145 WINPROC_FreeProc( classPtr
->winprocA
, WIN_PROC_CLASS
);
146 classPtr
->winprocA
= 0;
153 /***********************************************************************
156 * Get the menu name as a ASCII string.
158 inline static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
160 if (!HIWORD(classPtr
->menuName
)) return (LPSTR
)classPtr
->menuName
;
161 return (LPSTR
)(classPtr
->menuName
+ strlenW(classPtr
->menuName
) + 1);
165 /***********************************************************************
168 * Get the menu name as a Unicode string.
170 inline static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
172 return classPtr
->menuName
;
176 /***********************************************************************
179 * Set the menu name in a class structure by copying the string.
181 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
183 if (HIWORD(classPtr
->menuName
)) SEGPTR_FREE( classPtr
->menuName
);
186 DWORD lenA
= strlen(name
) + 1;
187 DWORD lenW
= MultiByteToWideChar( CP_ACP
, 0, name
, lenA
, NULL
, 0 );
188 classPtr
->menuName
= SEGPTR_ALLOC( lenA
+ lenW
*sizeof(WCHAR
) );
189 MultiByteToWideChar( CP_ACP
, 0, name
, lenA
, classPtr
->menuName
, lenW
);
190 memcpy( classPtr
->menuName
+ lenW
, name
, lenA
);
192 else classPtr
->menuName
= (LPWSTR
)name
;
196 /***********************************************************************
199 * Set the menu name in a class structure by copying the string.
201 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
203 if (HIWORD(classPtr
->menuName
)) SEGPTR_FREE( classPtr
->menuName
);
206 DWORD lenW
= strlenW(name
) + 1;
207 DWORD lenA
= WideCharToMultiByte( CP_ACP
, 0, name
, lenW
, NULL
, 0, NULL
, NULL
);
208 classPtr
->menuName
= SEGPTR_ALLOC( lenA
+ lenW
*sizeof(WCHAR
) );
209 memcpy( classPtr
->menuName
, name
, lenW
*sizeof(WCHAR
) );
210 WideCharToMultiByte( CP_ACP
, 0, name
, lenW
,
211 (char *)(classPtr
->menuName
+ lenW
), lenA
, NULL
, NULL
);
213 else classPtr
->menuName
= (LPWSTR
)name
;
217 /***********************************************************************
220 * Free a class structure.
222 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
224 TRACE("%p\n", classPtr
);
226 /* Check if we can remove this class */
228 if (classPtr
->cWindows
> 0)
230 SetLastError( ERROR_CLASS_HAS_WINDOWS
);
234 /* Remove the class from the linked list */
236 if (classPtr
->next
) classPtr
->next
->prev
= classPtr
->prev
;
237 if (classPtr
->prev
) classPtr
->prev
->next
= classPtr
->next
;
238 else firstClass
= classPtr
->next
;
240 /* Delete the class */
242 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
243 if (classPtr
->hbrBackground
> (HBRUSH
)(COLOR_GRADIENTINACTIVECAPTION
+ 1))
244 DeleteObject( classPtr
->hbrBackground
);
245 GlobalDeleteAtom( classPtr
->atomName
);
246 WINPROC_FreeProc( classPtr
->winprocA
, WIN_PROC_CLASS
);
247 WINPROC_FreeProc( classPtr
->winprocW
, WIN_PROC_CLASS
);
248 HeapFree( GetProcessHeap(), 0, classPtr
->menuName
);
249 HeapFree( GetProcessHeap(), 0, classPtr
);
254 /***********************************************************************
255 * CLASS_FreeModuleClasses
257 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
261 TRACE("0x%08x\n", hModule
);
264 for (ptr
= firstClass
; ptr
; ptr
= next
)
267 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
273 /***********************************************************************
274 * CLASS_FindClassByAtom
276 * Return a pointer to the class.
277 * hinstance has been normalized by the caller.
280 * 980805 a local class will be found now if registred with hInst=0
281 * and looed up with a hInst!=0. msmoney does it (jsch)
283 static CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
285 CLASS
* class, *tclass
=0;
287 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
289 /* First search task-specific classes */
291 for (class = firstClass
; (class); class = class->next
)
293 if (class->style
& CS_GLOBALCLASS
) continue;
294 if (class->atomName
== atom
)
296 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
298 TRACE("-- found local %p\n", class);
301 if (class->hInstance
==0) tclass
= class;
305 /* Then search global classes */
307 for (class = firstClass
; (class); class = class->next
)
309 if (!(class->style
& CS_GLOBALCLASS
)) continue;
310 if (class->atomName
== atom
)
312 TRACE("-- found global %p\n", class);
317 /* Then check if there was a local class with hInst=0*/
320 WARN("-- found local Class registred with hInst=0\n");
324 TRACE("-- not found\n");
329 /***********************************************************************
330 * CLASS_RegisterClass
332 * The real RegisterClass() functionality.
334 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
335 DWORD style
, INT classExtra
, INT winExtra
)
339 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x\n",
340 atom
, hInstance
, style
, classExtra
, winExtra
);
342 /* Check if a class with this name already exists */
343 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
346 /* Class can be created only if it is local and */
347 /* if the class with the same name is global. */
349 if ((style
& CS_GLOBALCLASS
) || !(classPtr
->style
& CS_GLOBALCLASS
))
351 SetLastError( ERROR_CLASS_ALREADY_EXISTS
);
356 /* Fix the extra bytes value */
358 if (classExtra
< 0) classExtra
= 0;
359 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
360 WARN("Class extra bytes %d is > 40\n", classExtra
);
361 if (winExtra
< 0) winExtra
= 0;
362 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
363 WARN("Win extra bytes %d is > 40\n", winExtra
);
365 /* Create the class */
367 classPtr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CLASS
) + classExtra
);
368 if (!classPtr
) return NULL
;
369 classPtr
->style
= style
;
370 classPtr
->cbWndExtra
= winExtra
;
371 classPtr
->cbClsExtra
= classExtra
;
372 classPtr
->hInstance
= hInstance
;
373 classPtr
->atomName
= atom
;
374 classPtr
->dce
= (style
& CS_CLASSDC
) ? DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
376 /* Other non-null values must be set by caller */
378 if ((classPtr
->next
= firstClass
)) firstClass
->prev
= classPtr
;
379 firstClass
= classPtr
;
384 /***********************************************************************
385 * CLASS_UnregisterClass
387 * The real UnregisterClass() functionality.
389 static BOOL
CLASS_UnregisterClass( ATOM atom
, HINSTANCE hInstance
)
396 (classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) &&
397 (classPtr
->hInstance
== hInstance
))
399 ret
= CLASS_FreeClass( classPtr
);
401 else SetLastError( ERROR_CLASS_DOES_NOT_EXIST
);
408 /***********************************************************************
409 * CLASS_RegisterBuiltinClass
411 * Register a builtin control class.
412 * This allows having both ASCII and Unicode winprocs for the same class.
414 ATOM
CLASS_RegisterBuiltinClass( const struct builtin_class_descr
*descr
)
419 if (!(atom
= GlobalAddAtomA( descr
->name
))) return 0;
421 if (!(classPtr
= CLASS_RegisterClass( atom
, 0, descr
->style
, 0, descr
->extra
)))
423 GlobalDeleteAtom( atom
);
427 classPtr
->hCursor
= LoadCursorA( 0, descr
->cursor
);
428 classPtr
->hbrBackground
= descr
->brush
;
430 if (descr
->procA
) WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)descr
->procA
,
431 WIN_PROC_32A
, WIN_PROC_CLASS
);
432 if (descr
->procW
) WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)descr
->procW
,
433 WIN_PROC_32W
, WIN_PROC_CLASS
);
438 /***********************************************************************
441 * Add a new window using this class, and return the necessary
442 * information for creating the window.
444 CLASS
*CLASS_AddWindow( ATOM atom
, HINSTANCE inst
, WINDOWPROCTYPE type
,
445 INT
*winExtra
, WNDPROC
*winproc
, DWORD
*style
, struct tagDCE
**dce
)
448 if (type
== WIN_PROC_16
) inst
= GetExePtr(inst
);
450 if (!(class = CLASS_FindClassByAtom( atom
, inst
))) return NULL
;
453 if (type
== WIN_PROC_32W
)
455 if (!(*winproc
= class->winprocW
)) *winproc
= class->winprocA
;
459 if (!(*winproc
= class->winprocA
)) *winproc
= class->winprocW
;
461 *winExtra
= class->cbWndExtra
;
462 *style
= class->style
;
468 /***********************************************************************
471 * Remove a window from the class window count.
473 void CLASS_RemoveWindow( CLASS
*cls
)
475 if (cls
&& cls
->cWindows
) cls
->cWindows
--;
479 /***********************************************************************
480 * RegisterClass (USER.57)
482 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
486 int iSmIconWidth
, iSmIconHeight
;
487 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
489 if (!(atom
= GlobalAddAtomA( MapSL(wc
->lpszClassName
) ))) return 0;
490 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
491 wc
->cbClsExtra
, wc
->cbWndExtra
)))
493 GlobalDeleteAtom( atom
);
497 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
498 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
499 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
500 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
501 wc
->cbWndExtra
, classPtr
,
502 HIWORD(wc
->lpszClassName
) ?
503 (char *)MapSL(wc
->lpszClassName
) : "" );
505 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
506 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
508 classPtr
->hIcon
= wc
->hIcon
;
509 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
510 iSmIconWidth
, iSmIconHeight
,
511 LR_COPYFROMRESOURCE
);
512 classPtr
->hCursor
= wc
->hCursor
;
513 classPtr
->hbrBackground
= wc
->hbrBackground
;
515 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
516 WIN_PROC_16
, WIN_PROC_CLASS
);
517 CLASS_SetMenuNameA( classPtr
, MapSL(wc
->lpszMenuName
) );
523 /***********************************************************************
524 * RegisterClassA (USER32.@)
526 * >0: Unique identifier
529 ATOM WINAPI
RegisterClassA( const WNDCLASSA
* wc
) /* [in] Address of structure with class data */
532 int iSmIconWidth
, iSmIconHeight
;
535 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
537 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
538 wc
->cbClsExtra
, wc
->cbWndExtra
)))
540 GlobalDeleteAtom( atom
);
544 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
545 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
546 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
547 wc
->cbWndExtra
, classPtr
,
548 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
550 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
551 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
553 classPtr
->hIcon
= wc
->hIcon
;
554 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
555 iSmIconWidth
, iSmIconHeight
,
556 LR_COPYFROMRESOURCE
);
557 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
558 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
560 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
561 WIN_PROC_32A
, WIN_PROC_CLASS
);
562 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
567 /***********************************************************************
568 * RegisterClassW (USER32.@)
570 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
573 int iSmIconWidth
, iSmIconHeight
;
576 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
578 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
579 wc
->cbClsExtra
, wc
->cbWndExtra
)))
581 GlobalDeleteAtom( atom
);
585 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
586 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
587 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
588 wc
->cbWndExtra
, classPtr
);
590 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
591 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
593 classPtr
->hIcon
= wc
->hIcon
;
594 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
595 iSmIconWidth
, iSmIconHeight
,
596 LR_COPYFROMRESOURCE
);
597 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
598 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
600 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
601 WIN_PROC_32W
, WIN_PROC_CLASS
);
602 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
607 /***********************************************************************
608 * RegisterClassEx (USER.397)
610 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
614 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
616 if (!(atom
= GlobalAddAtomA( MapSL(wc
->lpszClassName
) ))) return 0;
617 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
618 wc
->cbClsExtra
, wc
->cbWndExtra
)))
620 GlobalDeleteAtom( atom
);
624 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
625 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
626 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
627 wc
->cbWndExtra
, classPtr
);
629 classPtr
->hIcon
= wc
->hIcon
;
630 classPtr
->hIconSm
= wc
->hIconSm
;
631 classPtr
->hCursor
= wc
->hCursor
;
632 classPtr
->hbrBackground
= wc
->hbrBackground
;
634 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
635 WIN_PROC_16
, WIN_PROC_CLASS
);
636 CLASS_SetMenuNameA( classPtr
, MapSL(wc
->lpszMenuName
) );
641 /***********************************************************************
642 * RegisterClassExA (USER32.@)
644 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
649 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
651 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
652 wc
->cbClsExtra
, wc
->cbWndExtra
)))
654 GlobalDeleteAtom( atom
);
658 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
659 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
660 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
661 wc
->cbWndExtra
, classPtr
);
663 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
664 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
665 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
666 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
667 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
668 WIN_PROC_32A
, WIN_PROC_CLASS
);
669 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
674 /***********************************************************************
675 * RegisterClassExW (USER32.@)
677 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
682 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
684 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
685 wc
->cbClsExtra
, wc
->cbWndExtra
)))
687 GlobalDeleteAtom( atom
);
691 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
692 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
693 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
694 wc
->cbWndExtra
, classPtr
);
696 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
697 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
698 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
699 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
700 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
701 WIN_PROC_32W
, WIN_PROC_CLASS
);
702 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
707 /***********************************************************************
708 * UnregisterClass (USER.403)
710 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
712 return UnregisterClassA( className
, GetExePtr( hInstance
) );
715 /***********************************************************************
716 * UnregisterClassA (USER32.@)
719 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
721 TRACE("%s %x\n",debugres_a(className
), hInstance
);
722 return CLASS_UnregisterClass( GlobalFindAtomA( className
), hInstance
);
725 /***********************************************************************
726 * UnregisterClassW (USER32.@)
728 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
730 TRACE("%s %x\n",debugres_w(className
), hInstance
);
731 return CLASS_UnregisterClass( GlobalFindAtomW( className
), hInstance
);
735 /***********************************************************************
736 * GetClassWord (USER32.@)
738 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
743 if (offset
< 0) return GetClassLongA( hwnd
, offset
);
745 TRACE("%x %x\n",hwnd
, offset
);
747 if (!(class = get_class_ptr( hwnd
, FALSE
))) return 0;
749 if (offset
<= class->cbClsExtra
- sizeof(WORD
))
750 retvalue
= GET_WORD((char *)(class + 1) + offset
);
752 SetLastError( ERROR_INVALID_INDEX
);
753 release_class_ptr( class );
758 /***********************************************************************
759 * GetClassLong (USER.131)
761 LONG WINAPI
GetClassLong16( HWND16 hwnd16
, INT16 offset
)
765 HWND hwnd
= (HWND
)(ULONG_PTR
)hwnd16
; /* no need for full handle */
767 TRACE("%x %d\n",hwnd
, offset
);
772 if (!(class = get_class_ptr( hwnd
, FALSE
))) return 0;
773 ret
= (LONG
)CLASS_GetProc( class, WIN_PROC_16
);
774 release_class_ptr( class );
777 ret
= GetClassLongA( hwnd
, offset
);
778 return (LONG
)SEGPTR_GET( (void *)ret
);
780 return GetClassLongA( hwnd
, offset
);
785 /***********************************************************************
786 * GetClassLongA (USER32.@)
788 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
793 TRACE("%x %d\n", hwnd
, offset
);
795 if (!(class = get_class_ptr( hwnd
, FALSE
))) return 0;
799 if (offset
<= class->cbClsExtra
- sizeof(LONG
))
800 retvalue
= GET_DWORD((char *)(class + 1) + offset
);
802 SetLastError( ERROR_INVALID_INDEX
);
803 release_class_ptr( class );
809 case GCL_HBRBACKGROUND
:
810 retvalue
= (LONG
)class->hbrBackground
;
813 retvalue
= (LONG
)class->hCursor
;
816 retvalue
= (LONG
)class->hIcon
;
819 retvalue
= (LONG
)class->hIconSm
;
822 retvalue
= (LONG
)class->style
;
825 retvalue
= (LONG
)class->cbWndExtra
;
828 retvalue
= (LONG
)class->cbClsExtra
;
831 retvalue
= (LONG
)class->hInstance
;
834 retvalue
= (LONG
)CLASS_GetProc( class, WIN_PROC_32A
);
837 retvalue
= (LONG
)CLASS_GetMenuNameA( class );
840 retvalue
= (DWORD
)class->atomName
;
843 SetLastError( ERROR_INVALID_INDEX
);
846 release_class_ptr( class );
851 /***********************************************************************
852 * GetClassLongW (USER32.@)
854 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
859 if (offset
!= GCL_WNDPROC
&& offset
!= GCL_MENUNAME
)
860 return GetClassLongA( hwnd
, offset
);
862 TRACE("%x %d\n", hwnd
, offset
);
864 if (!(class = get_class_ptr( hwnd
, FALSE
))) return 0;
866 if (offset
== GCL_WNDPROC
)
867 retvalue
= (LONG
)CLASS_GetProc( class, WIN_PROC_32W
);
868 else /* GCL_MENUNAME */
869 retvalue
= (LONG
)CLASS_GetMenuNameW( class );
871 release_class_ptr( class );
876 /***********************************************************************
877 * SetClassWord (USER32.@)
879 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
884 if (offset
< 0) return SetClassLongA( hwnd
, offset
, (DWORD
)newval
);
886 TRACE("%x %d %x\n", hwnd
, offset
, newval
);
888 if (!(class = get_class_ptr( hwnd
, TRUE
))) return 0;
890 if (offset
<= class->cbClsExtra
- sizeof(WORD
))
892 void *ptr
= (char *)(class + 1) + offset
;
893 retval
= GET_WORD(ptr
);
894 PUT_WORD( ptr
, newval
);
896 else SetLastError( ERROR_INVALID_INDEX
);
898 release_class_ptr( class );
903 /***********************************************************************
904 * SetClassLong (USER.132)
906 LONG WINAPI
SetClassLong16( HWND16 hwnd16
, INT16 offset
, LONG newval
)
910 HWND hwnd
= (HWND
)(ULONG_PTR
)hwnd16
; /* no need for full handle */
912 TRACE("%x %d %lx\n", hwnd
, offset
, newval
);
917 if (!(class = get_class_ptr( hwnd
, TRUE
))) return 0;
918 retval
= (LONG
)CLASS_SetProc( class, (WNDPROC
)newval
, WIN_PROC_16
);
919 release_class_ptr( class );
922 newval
= (LONG
)MapSL( newval
);
925 return SetClassLongA( hwnd
, offset
, newval
);
930 /***********************************************************************
931 * SetClassLongA (USER32.@)
933 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
938 TRACE("%x %d %lx\n", hwnd
, offset
, newval
);
940 if (!(class = get_class_ptr( hwnd
, TRUE
))) return 0;
944 if (offset
<= class->cbClsExtra
- sizeof(LONG
))
946 void *ptr
= (char *)(class + 1) + offset
;
947 retval
= GET_DWORD(ptr
);
948 PUT_DWORD( ptr
, newval
);
950 else SetLastError( ERROR_INVALID_INDEX
);
955 CLASS_SetMenuNameA( class, (LPCSTR
)newval
);
956 retval
= 0; /* Old value is now meaningless anyway */
959 retval
= (LONG
)CLASS_SetProc( class, (WNDPROC
)newval
, WIN_PROC_32A
);
961 case GCL_HBRBACKGROUND
:
962 retval
= (LONG
)class->hbrBackground
;
963 class->hbrBackground
= newval
;
966 retval
= (LONG
)class->hCursor
;
967 class->hCursor
= newval
;
970 retval
= (LONG
)class->hIcon
;
971 class->hIcon
= newval
;
974 retval
= (LONG
)class->hIconSm
;
975 class->hIconSm
= newval
;
978 retval
= (LONG
)class->style
;
979 class->style
= newval
;
982 retval
= (LONG
)class->cbWndExtra
;
983 class->cbWndExtra
= newval
;
986 retval
= (LONG
)class->hInstance
;
987 class->hInstance
= newval
;
990 retval
= (DWORD
)class->atomName
;
991 class->atomName
= newval
;
993 case GCL_CBCLSEXTRA
: /* cannot change this one */
994 SetLastError( ERROR_INVALID_PARAMETER
);
997 SetLastError( ERROR_INVALID_INDEX
);
1000 release_class_ptr( class );
1005 /***********************************************************************
1006 * SetClassLongW (USER32.@)
1008 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1013 if (offset
!= GCL_WNDPROC
&& offset
!= GCL_MENUNAME
)
1014 return SetClassLongA( hwnd
, offset
, newval
);
1016 TRACE("%x %d %lx\n", hwnd
, offset
, newval
);
1018 if (!(class = get_class_ptr( hwnd
, TRUE
))) return 0;
1020 if (offset
== GCL_WNDPROC
)
1021 retval
= (LONG
)CLASS_SetProc( class, (WNDPROC
)newval
, WIN_PROC_32W
);
1022 else /* GCL_MENUNAME */
1024 CLASS_SetMenuNameW( class, (LPCWSTR
)newval
);
1025 retval
= 0; /* Old value is now meaningless anyway */
1027 release_class_ptr( class );
1032 /***********************************************************************
1033 * GetClassNameA (USER32.@)
1035 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1037 INT ret
= GlobalGetAtomNameA( GetClassLongA( hwnd
, GCW_ATOM
), buffer
, count
);
1039 TRACE("%x %s %x\n",hwnd
, debugstr_a(buffer
), count
);
1044 /***********************************************************************
1045 * GetClassNameW (USER32.@)
1047 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1049 INT ret
= GlobalGetAtomNameW( GetClassLongW( hwnd
, GCW_ATOM
), buffer
, count
);
1051 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1056 /***********************************************************************
1057 * GetClassInfo (USER.404)
1059 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASS16
*wc
)
1064 TRACE("%x %s %p\n",hInstance
, debugres_a(MapSL(name
)), wc
);
1066 hInstance
= GetExePtr( hInstance
);
1067 if (!(atom
= GlobalFindAtomA( MapSL(name
) )) ||
1068 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1070 if ((hInstance
!= classPtr
->hInstance
) &&
1071 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1073 wc
->style
= (UINT16
)classPtr
->style
;
1074 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1075 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1076 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1077 wc
->hInstance
= classPtr
->style
& CS_GLOBALCLASS
? GetModuleHandle16("USER") : (HINSTANCE16
)classPtr
->hInstance
;
1078 wc
->hIcon
= classPtr
->hIcon
;
1079 wc
->hCursor
= classPtr
->hCursor
;
1080 wc
->hbrBackground
= classPtr
->hbrBackground
;
1081 wc
->lpszClassName
= name
;
1082 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1083 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1084 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1089 /***********************************************************************
1090 * GetClassInfoA (USER32.@)
1092 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1098 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1100 /* workaround: if hInstance=NULL you expect to get the system classes
1101 but this classes (as example from comctl32.dll SysListView) won't be
1102 registered with hInstance=NULL in WINE because of the late loading
1103 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1105 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1108 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1109 classPtr
->hInstance
&&
1110 (hInstance
!= classPtr
->hInstance
))
1112 if (hInstance
) return FALSE
;
1113 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1116 wc
->style
= classPtr
->style
;
1117 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1118 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1119 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1120 wc
->hInstance
= hInstance
;
1121 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1122 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1123 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1124 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1125 wc
->lpszClassName
= name
;
1130 /***********************************************************************
1131 * GetClassInfoW (USER32.@)
1133 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1139 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1141 if ( !(atom
=GlobalFindAtomW(name
)) ||
1142 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1146 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1147 classPtr
->hInstance
&&
1148 (hInstance
!= classPtr
->hInstance
))
1150 if (hInstance
) return FALSE
;
1151 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1153 wc
->style
= classPtr
->style
;
1154 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1155 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1156 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1157 wc
->hInstance
= hInstance
;
1158 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1159 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1160 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1161 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1162 wc
->lpszClassName
= name
;
1167 /***********************************************************************
1168 * GetClassInfoEx (USER.398)
1170 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1171 * same in Win16 as in Win32. --AJ
1173 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASSEX16
*wc
)
1178 TRACE("%x %s %p\n",hInstance
,debugres_a( MapSL(name
) ), wc
);
1180 hInstance
= GetExePtr( hInstance
);
1181 if (!(atom
= GlobalFindAtomA( MapSL(name
) )) ||
1182 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1183 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1184 wc
->style
= classPtr
->style
;
1185 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1186 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1187 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1188 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1189 wc
->hIcon
= classPtr
->hIcon
;
1190 wc
->hIconSm
= classPtr
->hIconSm
;
1191 wc
->hCursor
= classPtr
->hCursor
;
1192 wc
->hbrBackground
= classPtr
->hbrBackground
;
1193 wc
->lpszClassName
= (SEGPTR
)0;
1194 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1195 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1196 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1197 wc
->lpszClassName
= name
;
1199 /* We must return the atom of the class here instead of just TRUE. */
1204 /***********************************************************************
1205 * GetClassInfoExA (USER32.@)
1207 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1213 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1215 if (!(atom
= GlobalFindAtomA( name
)) ||
1216 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1217 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1218 wc
->style
= classPtr
->style
;
1219 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1220 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1221 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1222 wc
->hInstance
= classPtr
->hInstance
;
1223 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1224 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1225 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1226 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1227 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1228 wc
->lpszClassName
= name
;
1230 /* We must return the atom of the class here instead of just TRUE. */
1235 /***********************************************************************
1236 * GetClassInfoExW (USER32.@)
1238 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1244 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1246 if (!(atom
= GlobalFindAtomW( name
)) ||
1247 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1248 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1249 wc
->style
= classPtr
->style
;
1250 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1251 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1252 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1253 wc
->hInstance
= classPtr
->hInstance
;
1254 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1255 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1256 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1257 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1258 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1259 wc
->lpszClassName
= name
;
1261 /* We must return the atom of the class here instead of just TRUE. */
1266 #if 0 /* toolhelp is in kernel, so this cannot work */
1268 /***********************************************************************
1269 * ClassFirst (TOOLHELP.69)
1271 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1273 TRACE("%p\n",pClassEntry
);
1274 pClassEntry
->wNext
= 1;
1275 return ClassNext16( pClassEntry
);
1279 /***********************************************************************
1280 * ClassNext (TOOLHELP.70)
1282 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1285 CLASS
*class = firstClass
;
1287 TRACE("%p\n",pClassEntry
);
1289 if (!pClassEntry
->wNext
) return FALSE
;
1290 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1293 pClassEntry
->wNext
= 0;
1296 pClassEntry
->hInst
= class->hInstance
;
1297 pClassEntry
->wNext
++;
1298 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1299 sizeof(pClassEntry
->szClassName
) );