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"
23 #include "wine/port.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 */
53 static CLASS
*firstClass
;
56 /***********************************************************************
59 * Get the class winproc for a given proc type
61 static WNDPROC16
CLASS_GetProc( CLASS
*classPtr
, WINDOWPROCTYPE type
)
63 HWINDOWPROC proc
= classPtr
->winprocA
;
65 if (classPtr
->winprocW
)
67 /* if we have a Unicode proc, use it if we have no ASCII proc
68 * or if we have both and Unicode was requested
70 if (!proc
|| type
== WIN_PROC_32W
) proc
= classPtr
->winprocW
;
72 return WINPROC_GetProc( proc
, type
);
76 /***********************************************************************
79 * Set the class winproc for a given proc type.
80 * Returns the previous window proc.
82 static WNDPROC16
CLASS_SetProc( CLASS
*classPtr
, WNDPROC newproc
, WINDOWPROCTYPE type
)
84 HWINDOWPROC
*proc
= &classPtr
->winprocA
;
87 if (classPtr
->winprocW
)
89 /* if we have a Unicode proc, use it if we have no ASCII proc
90 * or if we have both and Unicode was requested
92 if (!*proc
|| type
== WIN_PROC_32W
) proc
= &classPtr
->winprocW
;
94 ret
= WINPROC_GetProc( *proc
, type
);
95 WINPROC_SetProc( proc
, (HWINDOWPROC
)newproc
, type
, WIN_PROC_CLASS
);
96 /* now free the one that we didn't set */
97 if (classPtr
->winprocA
&& classPtr
->winprocW
)
99 if (proc
== &classPtr
->winprocA
)
101 WINPROC_FreeProc( classPtr
->winprocW
, WIN_PROC_CLASS
);
102 classPtr
->winprocW
= 0;
106 WINPROC_FreeProc( classPtr
->winprocA
, WIN_PROC_CLASS
);
107 classPtr
->winprocA
= 0;
114 /***********************************************************************
117 * Get the menu name as a ASCII string.
119 inline static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
121 if (!HIWORD(classPtr
->menuName
)) return (LPSTR
)classPtr
->menuName
;
122 return (LPSTR
)(classPtr
->menuName
+ strlenW(classPtr
->menuName
) + 1);
126 /***********************************************************************
129 * Get the menu name as a Unicode string.
131 inline static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
133 return classPtr
->menuName
;
137 /***********************************************************************
140 * Set the menu name in a class structure by copying the string.
142 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
144 if (HIWORD(classPtr
->menuName
)) SEGPTR_FREE( classPtr
->menuName
);
147 DWORD lenA
= strlen(name
) + 1;
148 DWORD lenW
= MultiByteToWideChar( CP_ACP
, 0, name
, lenA
, NULL
, 0 );
149 classPtr
->menuName
= SEGPTR_ALLOC( lenA
+ lenW
*sizeof(WCHAR
) );
150 MultiByteToWideChar( CP_ACP
, 0, name
, lenA
, classPtr
->menuName
, lenW
);
151 memcpy( classPtr
->menuName
+ lenW
, name
, lenA
);
153 else classPtr
->menuName
= (LPWSTR
)name
;
157 /***********************************************************************
160 * Set the menu name in a class structure by copying the string.
162 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
164 if (HIWORD(classPtr
->menuName
)) SEGPTR_FREE( classPtr
->menuName
);
167 DWORD lenW
= strlenW(name
) + 1;
168 DWORD lenA
= WideCharToMultiByte( CP_ACP
, 0, name
, lenW
, NULL
, 0, NULL
, NULL
);
169 classPtr
->menuName
= SEGPTR_ALLOC( lenA
+ lenW
*sizeof(WCHAR
) );
170 memcpy( classPtr
->menuName
, name
, lenW
*sizeof(WCHAR
) );
171 WideCharToMultiByte( CP_ACP
, 0, name
, lenW
,
172 (char *)(classPtr
->menuName
+ lenW
), lenA
, NULL
, NULL
);
174 else classPtr
->menuName
= (LPWSTR
)name
;
178 /***********************************************************************
181 * Free a class structure.
183 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
185 TRACE("%p\n", classPtr
);
187 /* Check if we can remove this class */
189 if (classPtr
->cWindows
> 0)
191 SetLastError( ERROR_CLASS_HAS_WINDOWS
);
195 /* Remove the class from the linked list */
197 if (classPtr
->next
) classPtr
->next
->prev
= classPtr
->prev
;
198 if (classPtr
->prev
) classPtr
->prev
->next
= classPtr
->next
;
199 else firstClass
= classPtr
->next
;
201 /* Delete the class */
203 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
204 if (classPtr
->hbrBackground
> (HBRUSH
)(COLOR_GRADIENTINACTIVECAPTION
+ 1))
205 DeleteObject( classPtr
->hbrBackground
);
206 GlobalDeleteAtom( classPtr
->atomName
);
207 WINPROC_FreeProc( classPtr
->winprocA
, WIN_PROC_CLASS
);
208 WINPROC_FreeProc( classPtr
->winprocW
, WIN_PROC_CLASS
);
209 HeapFree( GetProcessHeap(), 0, classPtr
->menuName
);
210 HeapFree( GetProcessHeap(), 0, classPtr
);
215 /***********************************************************************
216 * CLASS_FreeModuleClasses
218 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
222 TRACE("0x%08x\n", hModule
);
224 for (ptr
= firstClass
; ptr
; ptr
= next
)
227 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
232 /***********************************************************************
233 * CLASS_FindClassByAtom
235 * Return a pointer to the class.
236 * hinstance has been normalized by the caller.
239 * 980805 a local class will be found now if registred with hInst=0
240 * and looed up with a hInst!=0. msmoney does it (jsch)
242 static CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
244 CLASS
* class, *tclass
=0;
246 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
248 /* First search task-specific classes */
250 for (class = firstClass
; (class); class = class->next
)
252 if (class->style
& CS_GLOBALCLASS
) continue;
253 if (class->atomName
== atom
)
255 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
257 TRACE("-- found local %p\n", class);
260 if (class->hInstance
==0) tclass
= class;
264 /* Then search global classes */
266 for (class = firstClass
; (class); class = class->next
)
268 if (!(class->style
& CS_GLOBALCLASS
)) continue;
269 if (class->atomName
== atom
)
271 TRACE("-- found global %p\n", class);
276 /* Then check if there was a local class with hInst=0*/
279 WARN("-- found local Class registred with hInst=0\n");
283 TRACE("-- not found\n");
288 /***********************************************************************
289 * CLASS_RegisterClass
291 * The real RegisterClass() functionality.
293 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
294 DWORD style
, INT classExtra
, INT winExtra
)
298 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x\n",
299 atom
, hInstance
, style
, classExtra
, winExtra
);
301 /* Check if a class with this name already exists */
302 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
305 /* Class can be created only if it is local and */
306 /* if the class with the same name is global. */
308 if ((style
& CS_GLOBALCLASS
) || !(classPtr
->style
& CS_GLOBALCLASS
))
310 SetLastError( ERROR_CLASS_ALREADY_EXISTS
);
315 /* Fix the extra bytes value */
317 if (classExtra
< 0) classExtra
= 0;
318 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
319 WARN("Class extra bytes %d is > 40\n", classExtra
);
320 if (winExtra
< 0) winExtra
= 0;
321 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
322 WARN("Win extra bytes %d is > 40\n", winExtra
);
324 /* Create the class */
326 classPtr
= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(CLASS
) + classExtra
);
327 if (!classPtr
) return NULL
;
328 classPtr
->style
= style
;
329 classPtr
->cbWndExtra
= winExtra
;
330 classPtr
->cbClsExtra
= classExtra
;
331 classPtr
->hInstance
= hInstance
;
332 classPtr
->atomName
= atom
;
333 classPtr
->dce
= (style
& CS_CLASSDC
) ? DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
335 /* Other non-null values must be set by caller */
337 if ((classPtr
->next
= firstClass
)) firstClass
->prev
= classPtr
;
338 firstClass
= classPtr
;
343 /***********************************************************************
344 * CLASS_RegisterBuiltinClass
346 * Register a builtin control class.
347 * This allows having both ASCII and Unicode winprocs for the same class.
349 ATOM
CLASS_RegisterBuiltinClass( const struct builtin_class_descr
*descr
)
354 if (!(atom
= GlobalAddAtomA( descr
->name
))) return 0;
356 if (!(classPtr
= CLASS_RegisterClass( atom
, 0, descr
->style
, 0, descr
->extra
)))
358 GlobalDeleteAtom( atom
);
362 classPtr
->hCursor
= LoadCursorA( 0, descr
->cursor
);
363 classPtr
->hbrBackground
= descr
->brush
;
365 if (descr
->procA
) WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)descr
->procA
,
366 WIN_PROC_32A
, WIN_PROC_CLASS
);
367 if (descr
->procW
) WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)descr
->procW
,
368 WIN_PROC_32W
, WIN_PROC_CLASS
);
373 /***********************************************************************
376 * Add a new window using this class, and return the necessary
377 * information for creating the window.
379 CLASS
*CLASS_AddWindow( ATOM atom
, HINSTANCE inst
, WINDOWPROCTYPE type
,
380 INT
*winExtra
, WNDPROC
*winproc
, DWORD
*style
, struct tagDCE
**dce
)
383 if (type
== WIN_PROC_16
) inst
= GetExePtr(inst
);
385 if (!(class = CLASS_FindClassByAtom( atom
, inst
))) return NULL
;
388 if (type
== WIN_PROC_32W
)
390 if (!(*winproc
= class->winprocW
)) *winproc
= class->winprocA
;
394 if (!(*winproc
= class->winprocA
)) *winproc
= class->winprocW
;
396 *winExtra
= class->cbWndExtra
;
397 *style
= class->style
;
403 /***********************************************************************
406 * Remove a window from the class window count.
408 void CLASS_RemoveWindow( CLASS
*cls
)
410 if (cls
&& cls
->cWindows
) cls
->cWindows
--;
414 /***********************************************************************
415 * RegisterClass (USER.57)
417 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
421 int iSmIconWidth
, iSmIconHeight
;
422 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
424 if (!(atom
= GlobalAddAtomA( MapSL(wc
->lpszClassName
) ))) return 0;
425 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
426 wc
->cbClsExtra
, wc
->cbWndExtra
)))
428 GlobalDeleteAtom( atom
);
432 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
433 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
434 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
435 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
436 wc
->cbWndExtra
, classPtr
,
437 HIWORD(wc
->lpszClassName
) ?
438 (char *)MapSL(wc
->lpszClassName
) : "" );
440 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
441 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
443 classPtr
->hIcon
= wc
->hIcon
;
444 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
445 iSmIconWidth
, iSmIconHeight
,
446 LR_COPYFROMRESOURCE
);
447 classPtr
->hCursor
= wc
->hCursor
;
448 classPtr
->hbrBackground
= wc
->hbrBackground
;
450 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
451 WIN_PROC_16
, WIN_PROC_CLASS
);
452 CLASS_SetMenuNameA( classPtr
, MapSL(wc
->lpszMenuName
) );
458 /***********************************************************************
459 * RegisterClassA (USER32.@)
461 * >0: Unique identifier
464 ATOM WINAPI
RegisterClassA( const WNDCLASSA
* wc
) /* [in] Address of structure with class data */
467 int iSmIconWidth
, iSmIconHeight
;
470 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
472 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
473 wc
->cbClsExtra
, wc
->cbWndExtra
)))
475 GlobalDeleteAtom( atom
);
479 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
480 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
481 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
482 wc
->cbWndExtra
, classPtr
,
483 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
485 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
486 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
488 classPtr
->hIcon
= wc
->hIcon
;
489 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
490 iSmIconWidth
, iSmIconHeight
,
491 LR_COPYFROMRESOURCE
);
492 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
493 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
495 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
496 WIN_PROC_32A
, WIN_PROC_CLASS
);
497 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
502 /***********************************************************************
503 * RegisterClassW (USER32.@)
505 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
508 int iSmIconWidth
, iSmIconHeight
;
511 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
513 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
514 wc
->cbClsExtra
, wc
->cbWndExtra
)))
516 GlobalDeleteAtom( atom
);
520 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
521 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
522 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
523 wc
->cbWndExtra
, classPtr
);
525 iSmIconWidth
= GetSystemMetrics(SM_CXSMICON
);
526 iSmIconHeight
= GetSystemMetrics(SM_CYSMICON
);
528 classPtr
->hIcon
= wc
->hIcon
;
529 classPtr
->hIconSm
= CopyImage(wc
->hIcon
, IMAGE_ICON
,
530 iSmIconWidth
, iSmIconHeight
,
531 LR_COPYFROMRESOURCE
);
532 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
533 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
535 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
536 WIN_PROC_32W
, WIN_PROC_CLASS
);
537 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
542 /***********************************************************************
543 * RegisterClassEx (USER.397)
545 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
549 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
551 if (!(atom
= GlobalAddAtomA( MapSL(wc
->lpszClassName
) ))) return 0;
552 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
553 wc
->cbClsExtra
, wc
->cbWndExtra
)))
555 GlobalDeleteAtom( atom
);
559 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
560 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
561 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
562 wc
->cbWndExtra
, classPtr
);
564 classPtr
->hIcon
= wc
->hIcon
;
565 classPtr
->hIconSm
= wc
->hIconSm
;
566 classPtr
->hCursor
= wc
->hCursor
;
567 classPtr
->hbrBackground
= wc
->hbrBackground
;
569 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
570 WIN_PROC_16
, WIN_PROC_CLASS
);
571 CLASS_SetMenuNameA( classPtr
, MapSL(wc
->lpszMenuName
) );
576 /***********************************************************************
577 * RegisterClassExA (USER32.@)
579 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
584 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
))) return 0;
586 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
587 wc
->cbClsExtra
, wc
->cbWndExtra
)))
589 GlobalDeleteAtom( atom
);
593 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
594 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
595 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
596 wc
->cbWndExtra
, classPtr
);
598 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
599 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
600 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
601 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
602 WINPROC_SetProc( &classPtr
->winprocA
, (HWINDOWPROC
)wc
->lpfnWndProc
,
603 WIN_PROC_32A
, WIN_PROC_CLASS
);
604 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
609 /***********************************************************************
610 * RegisterClassExW (USER32.@)
612 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
617 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
))) return 0;
619 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
620 wc
->cbClsExtra
, wc
->cbWndExtra
)))
622 GlobalDeleteAtom( atom
);
626 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
627 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
628 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
629 wc
->cbWndExtra
, classPtr
);
631 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
632 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
633 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
634 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
635 WINPROC_SetProc( &classPtr
->winprocW
, (HWINDOWPROC
)wc
->lpfnWndProc
,
636 WIN_PROC_32W
, WIN_PROC_CLASS
);
637 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
642 /***********************************************************************
643 * UnregisterClass (USER.403)
645 BOOL16 WINAPI
UnregisterClass16( LPCSTR className
, HINSTANCE16 hInstance
)
647 return UnregisterClassA( className
, GetExePtr( hInstance
) );
651 /***********************************************************************
652 * UnregisterClassA (USER32.@)
655 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
660 TRACE("%s %x\n",debugres_a(className
), hInstance
);
662 if (!(atom
= GlobalFindAtomA( className
)))
664 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
667 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
668 (classPtr
->hInstance
!= hInstance
))
670 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
673 return CLASS_FreeClass( classPtr
);
676 /***********************************************************************
677 * UnregisterClassW (USER32.@)
679 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
684 TRACE("%s %x\n",debugres_w(className
), hInstance
);
686 if (!(atom
= GlobalFindAtomW( className
)))
688 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
691 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
692 (classPtr
->hInstance
!= hInstance
))
694 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
697 return CLASS_FreeClass( classPtr
);
700 /***********************************************************************
701 * GetClassWord (USER.129)
703 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
705 return GetClassWord( hwnd
, offset
);
709 /***********************************************************************
710 * GetClassWord (USER32.@)
712 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
717 TRACE("%x %x\n",hwnd
, offset
);
719 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
722 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
724 retvalue
= GET_WORD((char *)(wndPtr
->class + 1) + offset
);
731 retvalue
= wndPtr
->class->atomName
;
733 case GCL_HBRBACKGROUND
:
741 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
745 WARN("Invalid offset %d\n", offset
);
747 WIN_ReleaseWndPtr(wndPtr
);
752 /***********************************************************************
753 * GetClassLong (USER.131)
755 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
760 TRACE("%x %x\n",hwnd
, offset
);
765 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
766 ret
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_16
);
767 WIN_ReleaseWndPtr(wndPtr
);
770 ret
= GetClassLongA( hwnd
, offset
);
771 return (LONG
)SEGPTR_GET( (void *)ret
);
773 return GetClassLongA( hwnd
, offset
);
778 /***********************************************************************
779 * GetClassLongA (USER32.@)
781 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
786 TRACE("%x %x\n",hwnd
, offset
);
788 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
791 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
793 retvalue
= GET_DWORD((char *)(wndPtr
->class + 1) + offset
);
800 case GCL_HBRBACKGROUND
:
801 retvalue
= (LONG
)wndPtr
->class->hbrBackground
;
804 retvalue
= (LONG
)wndPtr
->class->hCursor
;
807 retvalue
= (LONG
)wndPtr
->class->hIcon
;
810 retvalue
= (LONG
)wndPtr
->class->hIconSm
;
813 retvalue
= (LONG
)wndPtr
->class->style
;
816 retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
819 retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
822 retvalue
= (LONG
)wndPtr
->class->hInstance
;
825 retvalue
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_32A
);
828 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
831 retvalue
= GetClassWord( hwnd
, offset
);
834 WARN("Invalid offset %d\n", offset
);
837 WIN_ReleaseWndPtr(wndPtr
);
842 /***********************************************************************
843 * GetClassLongW (USER32.@)
845 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
850 TRACE("%x %x\n",hwnd
, offset
);
855 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
856 retvalue
= (LONG
)CLASS_GetProc( wndPtr
->class, WIN_PROC_32W
);
857 WIN_ReleaseWndPtr(wndPtr
);
860 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
861 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
862 WIN_ReleaseWndPtr(wndPtr
);
865 return GetClassLongA( hwnd
, offset
);
870 /***********************************************************************
871 * SetClassWord (USER.130)
873 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
875 return SetClassWord( hwnd
, offset
, newval
);
879 /***********************************************************************
880 * SetClassWord (USER32.@)
882 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
888 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
890 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
893 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
894 ptr
= (char *)(wndPtr
->class + 1) + offset
;
897 WARN("Invalid offset %d\n", offset
);
898 WIN_ReleaseWndPtr(wndPtr
);
904 case GCL_HBRBACKGROUND
:
912 WIN_ReleaseWndPtr(wndPtr
);
913 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
915 ptr
= &wndPtr
->class->atomName
;
918 WARN("Invalid offset %d\n", offset
);
919 WIN_ReleaseWndPtr(wndPtr
);
922 retval
= GET_WORD(ptr
);
923 PUT_WORD( ptr
, newval
);
924 WIN_ReleaseWndPtr(wndPtr
);
929 /***********************************************************************
930 * SetClassLong (USER.132)
932 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
937 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
942 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
943 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_16
);
944 WIN_ReleaseWndPtr(wndPtr
);
947 return SetClassLongA( hwnd
, offset
, (LONG
)MapSL(newval
) );
949 return SetClassLongA( hwnd
, offset
, newval
);
954 /***********************************************************************
955 * SetClassLongA (USER32.@)
957 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
963 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
965 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
968 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
969 ptr
= (char *)(wndPtr
->class + 1) + offset
;
972 WARN("Invalid offset %d\n", offset
);
980 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
981 retval
= 0; /* Old value is now meaningless anyway */
984 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_32A
);
986 case GCL_HBRBACKGROUND
:
987 ptr
= &wndPtr
->class->hbrBackground
;
990 ptr
= &wndPtr
->class->hCursor
;
993 ptr
= &wndPtr
->class->hIcon
;
996 ptr
= &wndPtr
->class->hIconSm
;
999 ptr
= &wndPtr
->class->style
;
1001 case GCL_CBWNDEXTRA
:
1002 ptr
= &wndPtr
->class->cbWndExtra
;
1004 case GCL_CBCLSEXTRA
:
1005 ptr
= &wndPtr
->class->cbClsExtra
;
1008 ptr
= &wndPtr
->class->hInstance
;
1011 WIN_ReleaseWndPtr(wndPtr
);
1012 return SetClassWord( hwnd
, offset
, newval
);
1014 WARN("Invalid offset %d\n", offset
);
1018 retval
= GET_DWORD(ptr
);
1019 PUT_DWORD( ptr
, newval
);
1021 WIN_ReleaseWndPtr(wndPtr
);
1026 /***********************************************************************
1027 * SetClassLongW (USER32.@)
1029 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1034 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1039 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1040 retval
= (LONG
)CLASS_SetProc( wndPtr
->class, (WNDPROC
)newval
, WIN_PROC_32W
);
1041 WIN_ReleaseWndPtr(wndPtr
);
1044 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1045 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1046 WIN_ReleaseWndPtr(wndPtr
);
1047 return 0; /* Old value is now meaningless anyway */
1049 return SetClassLongA( hwnd
, offset
, newval
);
1054 /***********************************************************************
1055 * GetClassName (USER.58)
1057 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1059 return GetClassNameA( hwnd
, buffer
, count
);
1063 /***********************************************************************
1064 * GetClassNameA (USER32.@)
1066 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1070 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1071 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1073 WIN_ReleaseWndPtr(wndPtr
);
1074 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1079 /***********************************************************************
1080 * GetClassNameW (USER32.@)
1082 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1086 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1087 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1088 WIN_ReleaseWndPtr(wndPtr
);
1089 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1095 /***********************************************************************
1096 * GetClassInfo (USER.404)
1098 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASS16
*wc
)
1103 TRACE("%x %s %p\n",hInstance
, debugres_a(MapSL(name
)), wc
);
1105 hInstance
= GetExePtr( hInstance
);
1106 if (!(atom
= GlobalFindAtomA( MapSL(name
) )) ||
1107 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1109 if ((hInstance
!= classPtr
->hInstance
) &&
1110 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1112 wc
->style
= (UINT16
)classPtr
->style
;
1113 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1114 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1115 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1116 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1117 wc
->hIcon
= classPtr
->hIcon
;
1118 wc
->hCursor
= classPtr
->hCursor
;
1119 wc
->hbrBackground
= classPtr
->hbrBackground
;
1120 wc
->lpszClassName
= name
;
1121 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1122 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1123 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1128 /***********************************************************************
1129 * GetClassInfoA (USER32.@)
1131 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1137 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1139 /* workaround: if hInstance=NULL you expect to get the system classes
1140 but this classes (as example from comctl32.dll SysListView) won't be
1141 registered with hInstance=NULL in WINE because of the late loading
1142 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1144 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1147 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1148 classPtr
->hInstance
&&
1149 (hInstance
!= classPtr
->hInstance
))
1151 if (hInstance
) return FALSE
;
1152 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1155 wc
->style
= classPtr
->style
;
1156 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1157 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1158 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1159 wc
->hInstance
= hInstance
;
1160 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1161 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1162 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1163 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1164 wc
->lpszClassName
= name
;
1169 /***********************************************************************
1170 * GetClassInfoW (USER32.@)
1172 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1178 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1180 if ( !(atom
=GlobalFindAtomW(name
)) ||
1181 !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
))
1185 if (!(classPtr
->style
& CS_GLOBALCLASS
) &&
1186 classPtr
->hInstance
&&
1187 (hInstance
!= classPtr
->hInstance
))
1189 if (hInstance
) return FALSE
;
1190 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name
));
1192 wc
->style
= classPtr
->style
;
1193 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1194 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1195 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1196 wc
->hInstance
= hInstance
;
1197 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1198 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1199 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1200 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1201 wc
->lpszClassName
= name
;
1206 /***********************************************************************
1207 * GetClassInfoEx (USER.398)
1209 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1210 * same in Win16 as in Win32. --AJ
1212 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
, WNDCLASSEX16
*wc
)
1217 TRACE("%x %s %p\n",hInstance
,debugres_a( MapSL(name
) ), wc
);
1219 hInstance
= GetExePtr( hInstance
);
1220 if (!(atom
= GlobalFindAtomA( MapSL(name
) )) ||
1221 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1222 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1223 wc
->style
= classPtr
->style
;
1224 wc
->lpfnWndProc
= CLASS_GetProc( classPtr
, WIN_PROC_16
);
1225 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1226 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1227 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1228 wc
->hIcon
= classPtr
->hIcon
;
1229 wc
->hIconSm
= classPtr
->hIconSm
;
1230 wc
->hCursor
= classPtr
->hCursor
;
1231 wc
->hbrBackground
= classPtr
->hbrBackground
;
1232 wc
->lpszClassName
= (SEGPTR
)0;
1233 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1234 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1235 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1236 wc
->lpszClassName
= name
;
1238 /* We must return the atom of the class here instead of just TRUE. */
1243 /***********************************************************************
1244 * GetClassInfoExA (USER32.@)
1246 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1252 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1254 if (!(atom
= GlobalFindAtomA( name
)) ||
1255 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1256 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1257 wc
->style
= classPtr
->style
;
1258 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32A
);
1259 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1260 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1261 wc
->hInstance
= classPtr
->hInstance
;
1262 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1263 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1264 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1265 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1266 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1267 wc
->lpszClassName
= name
;
1269 /* We must return the atom of the class here instead of just TRUE. */
1274 /***********************************************************************
1275 * GetClassInfoExW (USER32.@)
1277 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1283 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1285 if (!(atom
= GlobalFindAtomW( name
)) ||
1286 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1287 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1288 wc
->style
= classPtr
->style
;
1289 wc
->lpfnWndProc
= (WNDPROC
)CLASS_GetProc( classPtr
, WIN_PROC_32W
);
1290 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1291 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1292 wc
->hInstance
= classPtr
->hInstance
;
1293 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1294 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1295 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1296 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1297 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1298 wc
->lpszClassName
= name
;
1300 /* We must return the atom of the class here instead of just TRUE. */
1305 #if 0 /* toolhelp is in kernel, so this cannot work */
1307 /***********************************************************************
1308 * ClassFirst (TOOLHELP.69)
1310 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1312 TRACE("%p\n",pClassEntry
);
1313 pClassEntry
->wNext
= 1;
1314 return ClassNext16( pClassEntry
);
1318 /***********************************************************************
1319 * ClassNext (TOOLHELP.70)
1321 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1324 CLASS
*class = firstClass
;
1326 TRACE("%p\n",pClassEntry
);
1328 if (!pClassEntry
->wNext
) return FALSE
;
1329 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1332 pClassEntry
->wNext
= 0;
1335 pClassEntry
->hInst
= class->hInstance
;
1336 pClassEntry
->wNext
++;
1337 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1338 sizeof(pClassEntry
->szClassName
) );