2 * Window classes functions
4 * Copyright 1993, 1996 Alexandre Julliard
5 * 1998 Juergen Schmied (jsch)
7 * FIXME: In win32 all classes are local. They are registered at
8 * program start. Processes CANNOT share classes. (Source: some
9 * win31->NT migration book)
11 * FIXME: There seems to be a general problem with hInstance in WINE
12 * classes are getting registred with wrong hInstance.
17 #include "wine/winbase16.h"
27 #include "wine/winuser16.h"
30 static CLASS
*firstClass
= NULL
;
33 /***********************************************************************
36 * Dump the content of a class structure to stderr.
38 void CLASS_DumpClass( CLASS
*ptr
)
40 char className
[MAX_CLASSNAME
+1];
43 if (ptr
->magic
!= CLASS_MAGIC
)
45 DUMP("%p is not a class\n", ptr
);
49 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
51 DUMP( "Class %p:\n", ptr
);
52 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
53 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
54 "clsExtra=%d winExtra=%d #windows=%d\n",
55 ptr
->next
, ptr
->atomName
, className
, ptr
->style
,
56 (UINT
)ptr
->winproc
, ptr
->hInstance
, (UINT
)ptr
->dce
,
57 ptr
->hIcon
, ptr
->hCursor
, ptr
->hbrBackground
,
58 ptr
->cbClsExtra
, ptr
->cbWndExtra
, ptr
->cWindows
);
61 DUMP( "extra bytes:" );
62 for (i
= 0; i
< ptr
->cbClsExtra
; i
++)
63 DUMP( " %02x", *((BYTE
*)ptr
->wExtra
+i
) );
70 /***********************************************************************
73 * Walk the class list and print each class on stderr.
75 void CLASS_WalkClasses(void)
78 char className
[MAX_CLASSNAME
+1];
80 DUMP( " Class Name Style WndProc\n" );
81 for (ptr
= firstClass
; ptr
; ptr
= ptr
->next
)
83 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
84 DUMP( "%08x %-20.20s %08x %08x\n", (UINT
)ptr
, className
,
85 ptr
->style
, (UINT
)ptr
->winproc
);
91 /***********************************************************************
94 * Get the menu name as a ASCII string.
96 static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
98 if (!classPtr
->menuNameA
&& classPtr
->menuNameW
)
100 /* We need to copy the Unicode string */
101 classPtr
->menuNameA
= SEGPTR_STRDUP_WtoA( classPtr
->menuNameW
);
103 return classPtr
->menuNameA
;
107 /***********************************************************************
110 * Get the menu name as a Unicode string.
112 static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
114 if (!classPtr
->menuNameW
&& classPtr
->menuNameA
)
116 if (!HIWORD(classPtr
->menuNameA
))
117 return (LPWSTR
)classPtr
->menuNameA
;
118 /* Now we need to copy the ASCII string */
119 classPtr
->menuNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
120 classPtr
->menuNameA
);
122 return classPtr
->menuNameW
;
126 /***********************************************************************
129 * Set the menu name in a class structure by copying the string.
131 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
133 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
134 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
135 classPtr
->menuNameA
= SEGPTR_STRDUP( name
);
136 classPtr
->menuNameW
= 0;
140 /***********************************************************************
143 * Set the menu name in a class structure by copying the string.
145 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
149 CLASS_SetMenuNameA( classPtr
, (LPCSTR
)name
);
152 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
153 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
154 if ((classPtr
->menuNameW
= HeapAlloc( SystemHeap
, 0,
155 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
156 lstrcpyW( classPtr
->menuNameW
, name
);
157 classPtr
->menuNameA
= 0;
161 /***********************************************************************
162 * CLASS_GetClassNameA
164 * Get the clas name as a ASCII string.
166 static LPSTR
CLASS_GetClassNameA( CLASS
*classPtr
)
168 if (!classPtr
->classNameA
&& classPtr
->classNameW
)
170 /* We need to copy the Unicode string */
171 classPtr
->classNameA
= SEGPTR_STRDUP_WtoA( classPtr
->classNameW
);
173 return classPtr
->classNameA
;
177 /***********************************************************************
178 * CLASS_GetClassNameW
180 * Get the class name as a Unicode string.
182 static LPWSTR
CLASS_GetClassNameW( CLASS
*classPtr
)
184 if (!classPtr
->classNameW
&& classPtr
->classNameA
)
186 if (!HIWORD(classPtr
->classNameA
))
187 return (LPWSTR
)classPtr
->classNameA
;
188 /* Now we need to copy the ASCII string */
189 classPtr
->classNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
190 classPtr
->classNameA
);
192 return classPtr
->classNameW
;
195 /***********************************************************************
196 * CLASS_SetClassNameA
198 * Set the class name in a class structure by copying the string.
200 static void CLASS_SetClassNameA( CLASS
*classPtr
, LPCSTR name
)
202 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
203 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
204 classPtr
->classNameA
= SEGPTR_STRDUP( name
);
205 classPtr
->classNameW
= 0;
209 /***********************************************************************
210 * CLASS_SetClassNameW
212 * Set the class name in a class structure by copying the string.
214 static void CLASS_SetClassNameW( CLASS
*classPtr
, LPCWSTR name
)
218 CLASS_SetClassNameA( classPtr
, (LPCSTR
)name
);
221 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
222 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
223 if ((classPtr
->classNameW
= HeapAlloc( SystemHeap
, 0,
224 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
225 lstrcpyW( classPtr
->classNameW
, name
);
226 classPtr
->classNameA
= 0;
230 /***********************************************************************
233 * Free a class structure.
235 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
238 TRACE(class,"%p \n", classPtr
);
240 /* Check if we can remove this class */
242 if (classPtr
->cWindows
> 0) return FALSE
;
244 /* Remove the class from the linked list */
246 for (ppClass
= &firstClass
; *ppClass
; ppClass
= &(*ppClass
)->next
)
247 if (*ppClass
== classPtr
) break;
250 ERR( class, "Class list corrupted\n" );
253 *ppClass
= classPtr
->next
;
255 /* Delete the class */
257 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
258 if (classPtr
->hbrBackground
) DeleteObject( classPtr
->hbrBackground
);
259 GlobalDeleteAtom( classPtr
->atomName
);
260 CLASS_SetMenuNameA( classPtr
, NULL
);
261 CLASS_SetClassNameA( classPtr
, NULL
);
262 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
263 HeapFree( SystemHeap
, 0, classPtr
);
268 /***********************************************************************
269 * CLASS_FreeModuleClasses
271 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
275 TRACE(class,"0x%08x \n", hModule
);
277 for (ptr
= firstClass
; ptr
; ptr
= next
)
280 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
285 /***********************************************************************
286 * CLASS_FindClassByAtom
288 * Return a pointer to the class.
289 * hinstance has been normalized by the caller.
292 * 980805 a local class will be found now if registred with hInst=0
293 * and looed up with a hInst!=0. msmoney does it (jsch)
295 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
296 { CLASS
* class, *tclass
=0;
298 TRACE(class,"0x%08x 0x%08x\n", atom
, hinstance
);
300 /* First search task-specific classes */
302 for (class = firstClass
; (class); class = class->next
)
304 if (class->style
& CS_GLOBALCLASS
) continue;
305 if (class->atomName
== atom
)
307 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
309 TRACE(class,"-- found local %p\n", class);
312 if (class->hInstance
==0) tclass
= class;
316 /* Then search global classes */
318 for (class = firstClass
; (class); class = class->next
)
320 if (!(class->style
& CS_GLOBALCLASS
)) continue;
321 if (class->atomName
== atom
)
323 TRACE(class,"-- found global %p\n", class);
328 /* Then check if there was a local class with hInst=0*/
331 WARN(class,"-- found local Class registred with hInst=0\n");
335 TRACE(class,"-- not found\n");
340 /***********************************************************************
341 * CLASS_RegisterClass
343 * The real RegisterClass() functionality.
345 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
346 DWORD style
, INT classExtra
,
347 INT winExtra
, WNDPROC16 wndProc
,
348 WINDOWPROCTYPE wndProcType
)
352 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
353 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
355 /* Check if a class with this name already exists */
356 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
359 /* Class can be created only if it is local and */
360 /* if the class with the same name is global. */
362 if (style
& CS_GLOBALCLASS
) return NULL
;
363 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
366 /* Fix the extra bytes value */
368 if (classExtra
< 0) classExtra
= 0;
369 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
370 WARN(class, "Class extra bytes %d is > 40\n", classExtra
);
371 if (winExtra
< 0) winExtra
= 0;
372 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
373 WARN(class, "Win extra bytes %d is > 40\n", winExtra
);
375 /* Create the class */
377 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
378 classExtra
- sizeof(classPtr
->wExtra
) );
379 if (!classPtr
) return NULL
;
380 classPtr
->next
= firstClass
;
381 classPtr
->magic
= CLASS_MAGIC
;
382 classPtr
->cWindows
= 0;
383 classPtr
->style
= style
;
384 classPtr
->winproc
= (HWINDOWPROC
)0;
385 classPtr
->cbWndExtra
= winExtra
;
386 classPtr
->cbClsExtra
= classExtra
;
387 classPtr
->hInstance
= hInstance
;
388 classPtr
->atomName
= atom
;
389 classPtr
->menuNameA
= 0;
390 classPtr
->menuNameW
= 0;
391 classPtr
->classNameA
= 0;
392 classPtr
->classNameW
= 0;
393 classPtr
->dce
= (style
& CS_CLASSDC
) ?
394 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
396 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
398 /* Other values must be set by caller */
400 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
401 firstClass
= classPtr
;
406 /***********************************************************************
407 * RegisterClass16 (USER.57)
409 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
413 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
415 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
416 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
417 wc
->cbClsExtra
, wc
->cbWndExtra
,
418 wc
->lpfnWndProc
, WIN_PROC_16
)))
420 GlobalDeleteAtom( atom
);
424 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
425 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
426 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
427 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
428 wc
->cbWndExtra
, classPtr
,
429 HIWORD(wc
->lpszClassName
) ?
430 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
432 classPtr
->hIcon
= wc
->hIcon
;
433 classPtr
->hIconSm
= 0;
434 classPtr
->hCursor
= wc
->hCursor
;
435 classPtr
->hbrBackground
= wc
->hbrBackground
;
437 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
438 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
439 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
440 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
446 /***********************************************************************
447 * RegisterClass32A (USER32.427)
449 * >0: Unique identifier
452 ATOM WINAPI
RegisterClassA(
453 const WNDCLASSA
* wc
/* Address of structure with class data */
458 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
460 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
463 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
464 wc
->cbClsExtra
, wc
->cbWndExtra
,
465 (WNDPROC16
)wc
->lpfnWndProc
,
467 { GlobalDeleteAtom( atom
);
468 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
472 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
473 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
474 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
475 wc
->cbWndExtra
, classPtr
,
476 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
478 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
479 classPtr
->hIconSm
= 0;
480 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
481 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
483 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
484 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
489 /***********************************************************************
490 * RegisterClass32W (USER32.430)
492 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
497 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
499 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
502 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
503 wc
->cbClsExtra
, wc
->cbWndExtra
,
504 (WNDPROC16
)wc
->lpfnWndProc
,
507 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
508 GlobalDeleteAtom( atom
);
512 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
513 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
514 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
515 wc
->cbWndExtra
, classPtr
);
517 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
518 classPtr
->hIconSm
= 0;
519 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
520 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
522 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
523 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
528 /***********************************************************************
529 * RegisterClassEx16 (USER.397)
531 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
535 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
537 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
538 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
539 wc
->cbClsExtra
, wc
->cbWndExtra
,
540 wc
->lpfnWndProc
, WIN_PROC_16
)))
542 GlobalDeleteAtom( atom
);
546 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
547 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
548 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
549 wc
->cbWndExtra
, classPtr
);
551 classPtr
->hIcon
= wc
->hIcon
;
552 classPtr
->hIconSm
= wc
->hIconSm
;
553 classPtr
->hCursor
= wc
->hCursor
;
554 classPtr
->hbrBackground
= wc
->hbrBackground
;
556 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
557 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
558 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
559 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
564 /***********************************************************************
565 * RegisterClassEx32A (USER32.428)
567 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
572 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
574 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
577 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
578 wc
->cbClsExtra
, wc
->cbWndExtra
,
579 (WNDPROC16
)wc
->lpfnWndProc
,
582 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
583 GlobalDeleteAtom( atom
);
587 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
588 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
589 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
590 wc
->cbWndExtra
, classPtr
);
592 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
593 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
594 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
595 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
596 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
597 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
602 /***********************************************************************
603 * RegisterClassEx32W (USER32.429)
605 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
610 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
612 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
615 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
616 wc
->cbClsExtra
, wc
->cbWndExtra
,
617 (WNDPROC16
)wc
->lpfnWndProc
,
620 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
621 GlobalDeleteAtom( atom
);
625 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
626 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
627 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
628 wc
->cbWndExtra
, classPtr
);
630 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
631 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
632 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
633 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
634 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
635 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
640 /***********************************************************************
641 * UnregisterClass16 (USER.403)
643 BOOL16 WINAPI
UnregisterClass16( SEGPTR className
, HINSTANCE16 hInstance
)
648 hInstance
= GetExePtr( hInstance
);
649 if (!(atom
= GlobalFindAtom16( className
))) return FALSE
;
650 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
651 (classPtr
->hInstance
!= hInstance
)) return FALSE
;
652 return CLASS_FreeClass( classPtr
);
656 /***********************************************************************
657 * UnregisterClass32A (USER32.563)
660 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
665 TRACE(class,"%s %x\n",className
, hInstance
);
667 if (!(atom
= GlobalFindAtomA( className
)))
669 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
672 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
673 (classPtr
->hInstance
!= hInstance
))
675 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
678 if (!(ret
= CLASS_FreeClass( classPtr
)))
679 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
683 /***********************************************************************
684 * UnregisterClass32W (USER32.564)
686 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
691 TRACE(class,"%s %x\n",debugstr_w(className
), hInstance
);
693 if (!(atom
= GlobalFindAtomW( className
)))
695 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
698 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
699 (classPtr
->hInstance
!= hInstance
))
701 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
704 if (!(ret
= CLASS_FreeClass( classPtr
)))
705 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
709 /***********************************************************************
710 * GetClassWord16 (USER.129)
712 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
714 return GetClassWord( hwnd
, offset
);
718 /***********************************************************************
719 * GetClassWord32 (USER32.219)
721 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
725 TRACE(class,"%x %x\n",hwnd
, offset
);
727 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
730 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
731 return GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
735 case GCW_HBRBACKGROUND
: return wndPtr
->class->hbrBackground
;
736 case GCW_HCURSOR
: return wndPtr
->class->hCursor
;
737 case GCW_HICON
: return wndPtr
->class->hIcon
;
738 case GCW_HICONSM
: return wndPtr
->class->hIconSm
;
739 case GCW_ATOM
: return wndPtr
->class->atomName
;
744 return (WORD
)GetClassLongA( hwnd
, offset
);
747 WARN(class, "Invalid offset %d\n", offset
);
752 /***********************************************************************
753 * GetClassLong16 (USER.131)
755 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
760 TRACE(class,"%x %x\n",hwnd
, offset
);
765 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
766 return (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
768 ret
= GetClassLongA( hwnd
, offset
);
769 return (LONG
)SEGPTR_GET( (void *)ret
);
771 return GetClassLongA( hwnd
, offset
);
776 /***********************************************************************
777 * GetClassLong32A (USER32.215)
779 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
783 TRACE(class,"%x %x\n",hwnd
, offset
);
785 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
788 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
789 return GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
793 case GCL_STYLE
: return (LONG
)wndPtr
->class->style
;
794 case GCL_CBWNDEXTRA
: return (LONG
)wndPtr
->class->cbWndExtra
;
795 case GCL_CBCLSEXTRA
: return (LONG
)wndPtr
->class->cbClsExtra
;
796 case GCL_HMODULE
: return (LONG
)wndPtr
->class->hInstance
;
798 return (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
800 return (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
802 case GCL_HBRBACKGROUND
:
806 return GetClassWord( hwnd
, offset
);
808 WARN(class, "Invalid offset %d\n", offset
);
813 /***********************************************************************
814 * GetClassLong32W (USER32.216)
816 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
820 TRACE(class,"%x %x\n",hwnd
, offset
);
825 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
826 return (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
828 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
829 return (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
831 return GetClassLongA( hwnd
, offset
);
836 /***********************************************************************
837 * SetClassWord16 (USER.130)
839 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
841 return SetClassWord( hwnd
, offset
, newval
);
845 /***********************************************************************
846 * SetClassWord32 (USER32.469)
848 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
854 TRACE(class,"%x %x %x\n",hwnd
, offset
, newval
);
856 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
859 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
860 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
863 WARN( class, "Invalid offset %d\n", offset
);
873 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
874 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
875 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
876 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
877 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
878 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
880 WARN( class, "Invalid offset %d\n", offset
);
883 retval
= GET_WORD(ptr
);
884 PUT_WORD( ptr
, newval
);
886 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
887 need to be updated as well. Problem is that we can't tell whether the atom is
888 using wide or narrow characters. For now, we'll just NULL out the className
889 fields, and emit a FIXME. */
890 if (offset
== GCW_ATOM
)
892 CLASS_SetClassNameA( wndPtr
->class, NULL
);
893 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
899 /***********************************************************************
900 * SetClassLong16 (USER.132)
902 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
907 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
912 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
913 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
914 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
915 WIN_PROC_16
, WIN_PROC_CLASS
);
918 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
920 return SetClassLongA( hwnd
, offset
, newval
);
925 /***********************************************************************
926 * SetClassLong32A (USER32.467)
928 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
934 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
936 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
939 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
940 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
943 WARN( class, "Invalid offset %d\n", offset
);
950 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
951 return 0; /* Old value is now meaningless anyway */
953 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
955 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
956 WIN_PROC_32A
, WIN_PROC_CLASS
);
958 case GCL_HBRBACKGROUND
:
962 return SetClassWord( hwnd
, offset
, (WORD
)newval
);
963 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
964 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
965 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
966 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
968 WARN( class, "Invalid offset %d\n", offset
);
971 retval
= GET_DWORD(ptr
);
972 PUT_DWORD( ptr
, newval
);
977 /***********************************************************************
978 * SetClassLong32W (USER32.468)
980 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
985 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
990 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
991 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
992 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
993 WIN_PROC_32W
, WIN_PROC_CLASS
);
996 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
997 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
998 return 0; /* Old value is now meaningless anyway */
1000 return SetClassLongA( hwnd
, offset
, newval
);
1005 /***********************************************************************
1006 * GetClassName16 (USER.58)
1008 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1011 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1012 return GlobalGetAtomName16( wndPtr
->class->atomName
, buffer
, count
);
1016 /***********************************************************************
1017 * GetClassName32A (USER32.217)
1019 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1023 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1024 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1026 TRACE(class,"%x %s %x\n",hwnd
, buffer
, count
);
1031 /***********************************************************************
1032 * GetClassName32W (USER32.218)
1034 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1038 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1039 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1041 TRACE(class,"%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1047 /***********************************************************************
1048 * GetClassInfo16 (USER.404)
1050 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
,
1056 TRACE(class,"%x %p %p\n",hInstance
, PTR_SEG_TO_LIN (name
), wc
);
1058 hInstance
= GetExePtr( hInstance
);
1059 if (!(atom
= GlobalFindAtom16( name
)) ||
1060 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1062 if ((hInstance
!= classPtr
->hInstance
) &&
1063 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1065 wc
->style
= (UINT16
)classPtr
->style
;
1066 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1067 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1068 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1069 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1070 wc
->hIcon
= classPtr
->hIcon
;
1071 wc
->hCursor
= classPtr
->hCursor
;
1072 wc
->hbrBackground
= classPtr
->hbrBackground
;
1073 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1074 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1075 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1076 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1077 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1078 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1083 /***********************************************************************
1084 * GetClassInfo32A (USER32.211)
1086 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1092 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1094 /* workaround: if hInstance=NULL you expect to get the system classes
1095 but this classes (as example from comctl32.dll SysListView) won't be
1096 registred with hInstance=NULL in WINE because of the late loading
1097 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1099 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1102 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1104 if (hInstance
) return FALSE
;
1106 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1109 wc
->style
= classPtr
->style
;
1110 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1112 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1113 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1114 wc
->hInstance
= classPtr
->hInstance
;
1115 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1116 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1117 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1118 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1119 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1124 /***********************************************************************
1125 * GetClassInfo32W (USER32.214)
1127 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1133 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1135 if (!(atom
= GlobalFindAtomW( name
)) ||
1136 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1137 (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)))
1140 wc
->style
= classPtr
->style
;
1141 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1143 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1144 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1145 wc
->hInstance
= classPtr
->hInstance
;
1146 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1147 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1148 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1149 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1150 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1155 /***********************************************************************
1156 * GetClassInfoEx16 (USER.398)
1158 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1159 * same in Win16 as in Win32. --AJ
1161 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
,
1167 TRACE(class,"%x %p %p\n",hInstance
,PTR_SEG_TO_LIN( name
), wc
);
1169 hInstance
= GetExePtr( hInstance
);
1170 if (!(atom
= GlobalFindAtom16( name
)) ||
1171 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1172 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1173 wc
->style
= classPtr
->style
;
1174 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1175 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1176 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1177 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1178 wc
->hIcon
= classPtr
->hIcon
;
1179 wc
->hIconSm
= classPtr
->hIconSm
;
1180 wc
->hCursor
= classPtr
->hCursor
;
1181 wc
->hbrBackground
= classPtr
->hbrBackground
;
1182 wc
->lpszClassName
= (SEGPTR
)0;
1183 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1184 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1185 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1186 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1187 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1188 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1193 /***********************************************************************
1194 * GetClassInfoEx32A (USER32.212)
1196 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1202 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1204 if (!(atom
= GlobalFindAtomA( name
)) ||
1205 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1206 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1207 wc
->style
= classPtr
->style
;
1208 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1210 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1211 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1212 wc
->hInstance
= classPtr
->hInstance
;
1213 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1214 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1215 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1216 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1217 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1218 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1223 /***********************************************************************
1224 * GetClassInfoEx32W (USER32.213)
1226 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1232 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1234 if (!(atom
= GlobalFindAtomW( name
)) ||
1235 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1236 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1237 wc
->style
= classPtr
->style
;
1238 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1240 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1241 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1242 wc
->hInstance
= classPtr
->hInstance
;
1243 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1244 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1245 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1246 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1247 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1248 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1253 /***********************************************************************
1254 * ClassFirst (TOOLHELP.69)
1256 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1258 TRACE(class,"%p\n",pClassEntry
);
1259 pClassEntry
->wNext
= 1;
1260 return ClassNext16( pClassEntry
);
1264 /***********************************************************************
1265 * ClassNext (TOOLHELP.70)
1267 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1270 CLASS
*class = firstClass
;
1272 TRACE(class,"%p\n",pClassEntry
);
1274 if (!pClassEntry
->wNext
) return FALSE
;
1275 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1278 pClassEntry
->wNext
= 0;
1281 pClassEntry
->hInst
= class->hInstance
;
1282 pClassEntry
->wNext
++;
1283 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1284 sizeof(pClassEntry
->szClassName
) );