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.
28 static CLASS
*firstClass
= NULL
;
31 /***********************************************************************
34 * Dump the content of a class structure to stderr.
36 void CLASS_DumpClass( CLASS
*ptr
)
38 char className
[MAX_CLASSNAME
+1];
41 if (ptr
->magic
!= CLASS_MAGIC
)
43 DUMP("%p is not a class\n", ptr
);
47 GlobalGetAtomName32A( ptr
->atomName
, className
, sizeof(className
) );
49 DUMP( "Class %p:\n", ptr
);
50 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
51 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
52 "clsExtra=%d winExtra=%d #windows=%d\n",
53 ptr
->next
, ptr
->atomName
, className
, ptr
->style
,
54 (UINT32
)ptr
->winproc
, ptr
->hInstance
, (UINT32
)ptr
->dce
,
55 ptr
->hIcon
, ptr
->hCursor
, ptr
->hbrBackground
,
56 ptr
->cbClsExtra
, ptr
->cbWndExtra
, ptr
->cWindows
);
59 DUMP( "extra bytes:" );
60 for (i
= 0; i
< ptr
->cbClsExtra
; i
++)
61 DUMP( " %02x", *((BYTE
*)ptr
->wExtra
+i
) );
68 /***********************************************************************
71 * Walk the class list and print each class on stderr.
73 void CLASS_WalkClasses(void)
76 char className
[MAX_CLASSNAME
+1];
78 DUMP( " Class Name Style WndProc\n" );
79 for (ptr
= firstClass
; ptr
; ptr
= ptr
->next
)
81 GlobalGetAtomName32A( ptr
->atomName
, className
, sizeof(className
) );
82 DUMP( "%08x %-20.20s %08x %08x\n", (UINT32
)ptr
, className
,
83 ptr
->style
, (UINT32
)ptr
->winproc
);
89 /***********************************************************************
92 * Get the menu name as a ASCII string.
94 static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
96 if (!classPtr
->menuNameA
&& classPtr
->menuNameW
)
98 /* We need to copy the Unicode string */
99 classPtr
->menuNameA
= SEGPTR_STRDUP_WtoA( classPtr
->menuNameW
);
101 return classPtr
->menuNameA
;
105 /***********************************************************************
108 * Get the menu name as a Unicode string.
110 static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
112 if (!classPtr
->menuNameW
&& classPtr
->menuNameA
)
114 if (!HIWORD(classPtr
->menuNameA
))
115 return (LPWSTR
)classPtr
->menuNameA
;
116 /* Now we need to copy the ASCII string */
117 classPtr
->menuNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
118 classPtr
->menuNameA
);
120 return classPtr
->menuNameW
;
124 /***********************************************************************
127 * Set the menu name in a class structure by copying the string.
129 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
131 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
132 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
133 classPtr
->menuNameA
= SEGPTR_STRDUP( name
);
134 classPtr
->menuNameW
= 0;
138 /***********************************************************************
141 * Set the menu name in a class structure by copying the string.
143 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
147 CLASS_SetMenuNameA( classPtr
, (LPCSTR
)name
);
150 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
151 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
152 if ((classPtr
->menuNameW
= HeapAlloc( SystemHeap
, 0,
153 (lstrlen32W(name
)+1)*sizeof(WCHAR
) )))
154 lstrcpy32W( classPtr
->menuNameW
, name
);
155 classPtr
->menuNameA
= 0;
159 /***********************************************************************
160 * CLASS_GetClassNameA
162 * Get the clas name as a ASCII string.
164 static LPSTR
CLASS_GetClassNameA( CLASS
*classPtr
)
166 if (!classPtr
->classNameA
&& classPtr
->classNameW
)
168 /* We need to copy the Unicode string */
169 classPtr
->classNameA
= SEGPTR_STRDUP_WtoA( classPtr
->classNameW
);
171 return classPtr
->classNameA
;
175 /***********************************************************************
176 * CLASS_GetClassNameW
178 * Get the class name as a Unicode string.
180 static LPWSTR
CLASS_GetClassNameW( CLASS
*classPtr
)
182 if (!classPtr
->classNameW
&& classPtr
->classNameA
)
184 if (!HIWORD(classPtr
->classNameA
))
185 return (LPWSTR
)classPtr
->classNameA
;
186 /* Now we need to copy the ASCII string */
187 classPtr
->classNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
188 classPtr
->classNameA
);
190 return classPtr
->classNameW
;
193 /***********************************************************************
194 * CLASS_SetClassNameA
196 * Set the class name in a class structure by copying the string.
198 static void CLASS_SetClassNameA( CLASS
*classPtr
, LPCSTR name
)
200 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
201 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
202 classPtr
->classNameA
= SEGPTR_STRDUP( name
);
203 classPtr
->classNameW
= 0;
207 /***********************************************************************
208 * CLASS_SetClassNameW
210 * Set the class name in a class structure by copying the string.
212 static void CLASS_SetClassNameW( CLASS
*classPtr
, LPCWSTR name
)
216 CLASS_SetClassNameA( classPtr
, (LPCSTR
)name
);
219 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
220 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
221 if ((classPtr
->classNameW
= HeapAlloc( SystemHeap
, 0,
222 (lstrlen32W(name
)+1)*sizeof(WCHAR
) )))
223 lstrcpy32W( classPtr
->classNameW
, name
);
224 classPtr
->classNameA
= 0;
228 /***********************************************************************
231 * Free a class structure.
233 static BOOL32
CLASS_FreeClass( CLASS
*classPtr
)
236 TRACE(class,"%p \n", classPtr
);
238 /* Check if we can remove this class */
240 if (classPtr
->cWindows
> 0) return FALSE
;
242 /* Remove the class from the linked list */
244 for (ppClass
= &firstClass
; *ppClass
; ppClass
= &(*ppClass
)->next
)
245 if (*ppClass
== classPtr
) break;
248 ERR( class, "Class list corrupted\n" );
251 *ppClass
= classPtr
->next
;
253 /* Delete the class */
255 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
256 if (classPtr
->hbrBackground
) DeleteObject32( classPtr
->hbrBackground
);
257 GlobalDeleteAtom( classPtr
->atomName
);
258 CLASS_SetMenuNameA( classPtr
, NULL
);
259 CLASS_SetClassNameA( classPtr
, NULL
);
260 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
261 HeapFree( SystemHeap
, 0, classPtr
);
266 /***********************************************************************
267 * CLASS_FreeModuleClasses
269 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
273 TRACE(class,"0x%08x \n", hModule
);
275 for (ptr
= firstClass
; ptr
; ptr
= next
)
278 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
283 /***********************************************************************
284 * CLASS_FindClassByAtom
286 * Return a pointer to the class.
287 * hinstance has been normalized by the caller.
290 * 980805 a local class will be found now if registred with hInst=0
291 * and looed up with a hInst!=0. msmoney does it (jsch)
293 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE32 hinstance
)
294 { CLASS
* class, *tclass
=0;
296 TRACE(class,"0x%08x 0x%08x\n", atom
, hinstance
);
298 /* First search task-specific classes */
300 for (class = firstClass
; (class); class = class->next
)
302 if (class->style
& CS_GLOBALCLASS
) continue;
303 if (class->atomName
== atom
)
305 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
307 TRACE(class,"-- found local %p\n", class);
310 if (class->hInstance
==0) tclass
= class;
314 /* Then search global classes */
316 for (class = firstClass
; (class); class = class->next
)
318 if (!(class->style
& CS_GLOBALCLASS
)) continue;
319 if (class->atomName
== atom
)
321 TRACE(class,"-- found global %p\n", class);
326 /* Then check if there was a local class with hInst=0*/
329 WARN(class,"-- found local Class registred with hInst=0\n");
333 TRACE(class,"-- not found\n");
338 /***********************************************************************
339 * CLASS_RegisterClass
341 * The real RegisterClass() functionality.
343 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE32 hInstance
,
344 DWORD style
, INT32 classExtra
,
345 INT32 winExtra
, WNDPROC16 wndProc
,
346 WINDOWPROCTYPE wndProcType
)
350 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
351 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
353 /* Check if a class with this name already exists */
354 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
357 /* Class can be created only if it is local and */
358 /* if the class with the same name is global. */
360 if (style
& CS_GLOBALCLASS
) return NULL
;
361 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
364 /* Fix the extra bytes value */
366 if (classExtra
< 0) classExtra
= 0;
367 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
368 WARN(class, "Class extra bytes %d is > 40\n", classExtra
);
369 if (winExtra
< 0) winExtra
= 0;
370 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
371 WARN(class, "Win extra bytes %d is > 40\n", winExtra
);
373 /* Create the class */
375 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
376 classExtra
- sizeof(classPtr
->wExtra
) );
377 if (!classPtr
) return NULL
;
378 classPtr
->next
= firstClass
;
379 classPtr
->magic
= CLASS_MAGIC
;
380 classPtr
->cWindows
= 0;
381 classPtr
->style
= style
;
382 classPtr
->winproc
= (HWINDOWPROC
)0;
383 classPtr
->cbWndExtra
= winExtra
;
384 classPtr
->cbClsExtra
= classExtra
;
385 classPtr
->hInstance
= hInstance
;
386 classPtr
->atomName
= atom
;
387 classPtr
->menuNameA
= 0;
388 classPtr
->menuNameW
= 0;
389 classPtr
->classNameA
= 0;
390 classPtr
->classNameW
= 0;
391 classPtr
->dce
= (style
& CS_CLASSDC
) ?
392 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
394 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
396 /* Other values must be set by caller */
398 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
399 firstClass
= classPtr
;
404 /***********************************************************************
405 * RegisterClass16 (USER.57)
407 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
411 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
413 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
414 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
415 wc
->cbClsExtra
, wc
->cbWndExtra
,
416 wc
->lpfnWndProc
, WIN_PROC_16
)))
418 GlobalDeleteAtom( atom
);
422 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
423 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
424 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
425 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
426 wc
->cbWndExtra
, classPtr
,
427 HIWORD(wc
->lpszClassName
) ?
428 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
430 classPtr
->hIcon
= wc
->hIcon
;
431 classPtr
->hIconSm
= 0;
432 classPtr
->hCursor
= wc
->hCursor
;
433 classPtr
->hbrBackground
= wc
->hbrBackground
;
435 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
436 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
437 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
438 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
444 /***********************************************************************
445 * RegisterClass32A (USER32.427)
447 * >0: Unique identifier
450 ATOM WINAPI
RegisterClass32A(
451 const WNDCLASS32A
* wc
/* Address of structure with class data */
456 if (!(atom
= GlobalAddAtom32A( wc
->lpszClassName
)))
458 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
461 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
462 wc
->cbClsExtra
, wc
->cbWndExtra
,
463 (WNDPROC16
)wc
->lpfnWndProc
,
465 { GlobalDeleteAtom( atom
);
466 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
470 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
471 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
472 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
473 wc
->cbWndExtra
, classPtr
,
474 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
476 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
477 classPtr
->hIconSm
= 0;
478 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
479 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
481 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
482 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
487 /***********************************************************************
488 * RegisterClass32W (USER32.430)
490 ATOM WINAPI
RegisterClass32W( const WNDCLASS32W
* wc
)
495 if (!(atom
= GlobalAddAtom32W( wc
->lpszClassName
)))
497 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
500 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
501 wc
->cbClsExtra
, wc
->cbWndExtra
,
502 (WNDPROC16
)wc
->lpfnWndProc
,
505 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
506 GlobalDeleteAtom( atom
);
510 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
511 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
512 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
513 wc
->cbWndExtra
, classPtr
);
515 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
516 classPtr
->hIconSm
= 0;
517 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
518 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
520 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
521 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
526 /***********************************************************************
527 * RegisterClassEx16 (USER.397)
529 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
533 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
535 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
536 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
537 wc
->cbClsExtra
, wc
->cbWndExtra
,
538 wc
->lpfnWndProc
, WIN_PROC_16
)))
540 GlobalDeleteAtom( atom
);
544 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
545 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
546 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
547 wc
->cbWndExtra
, classPtr
);
549 classPtr
->hIcon
= wc
->hIcon
;
550 classPtr
->hIconSm
= wc
->hIconSm
;
551 classPtr
->hCursor
= wc
->hCursor
;
552 classPtr
->hbrBackground
= wc
->hbrBackground
;
554 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
555 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
556 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
557 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
562 /***********************************************************************
563 * RegisterClassEx32A (USER32.428)
565 ATOM WINAPI
RegisterClassEx32A( const WNDCLASSEX32A
* wc
)
570 if (!(atom
= GlobalAddAtom32A( wc
->lpszClassName
)))
572 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
575 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
576 wc
->cbClsExtra
, wc
->cbWndExtra
,
577 (WNDPROC16
)wc
->lpfnWndProc
,
580 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
581 GlobalDeleteAtom( atom
);
585 TRACE(class, "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 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
591 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
592 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
593 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
594 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
595 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
600 /***********************************************************************
601 * RegisterClassEx32W (USER32.429)
603 ATOM WINAPI
RegisterClassEx32W( const WNDCLASSEX32W
* wc
)
608 if (!(atom
= GlobalAddAtom32W( wc
->lpszClassName
)))
610 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
613 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
614 wc
->cbClsExtra
, wc
->cbWndExtra
,
615 (WNDPROC16
)wc
->lpfnWndProc
,
618 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
619 GlobalDeleteAtom( atom
);
623 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
624 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
625 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
626 wc
->cbWndExtra
, classPtr
);
628 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
629 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
630 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
631 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
632 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
633 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
638 /***********************************************************************
639 * UnregisterClass16 (USER.403)
641 BOOL16 WINAPI
UnregisterClass16( SEGPTR className
, HINSTANCE16 hInstance
)
646 hInstance
= GetExePtr( hInstance
);
647 if (!(atom
= GlobalFindAtom16( className
))) return FALSE
;
648 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
649 (classPtr
->hInstance
!= hInstance
)) return FALSE
;
650 return CLASS_FreeClass( classPtr
);
654 /***********************************************************************
655 * UnregisterClass32A (USER32.563)
658 BOOL32 WINAPI
UnregisterClass32A( LPCSTR className
, HINSTANCE32 hInstance
)
663 TRACE(class,"%s %x\n",className
, hInstance
);
665 if (!(atom
= GlobalFindAtom32A( className
)))
667 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
670 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
671 (classPtr
->hInstance
!= hInstance
))
673 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
676 if (!(ret
= CLASS_FreeClass( classPtr
)))
677 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
681 /***********************************************************************
682 * UnregisterClass32W (USER32.564)
684 BOOL32 WINAPI
UnregisterClass32W( LPCWSTR className
, HINSTANCE32 hInstance
)
689 TRACE(class,"%s %x\n",debugstr_w(className
), hInstance
);
691 if (!(atom
= GlobalFindAtom32W( className
)))
693 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
696 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
697 (classPtr
->hInstance
!= hInstance
))
699 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
702 if (!(ret
= CLASS_FreeClass( classPtr
)))
703 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
707 /***********************************************************************
708 * GetClassWord16 (USER.129)
710 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
712 return GetClassWord32( hwnd
, offset
);
716 /***********************************************************************
717 * GetClassWord32 (USER32.219)
719 WORD WINAPI
GetClassWord32( HWND32 hwnd
, INT32 offset
)
723 TRACE(class,"%x %x\n",hwnd
, offset
);
725 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
728 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
729 return GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
733 case GCW_HBRBACKGROUND
: return wndPtr
->class->hbrBackground
;
734 case GCW_HCURSOR
: return wndPtr
->class->hCursor
;
735 case GCW_HICON
: return wndPtr
->class->hIcon
;
736 case GCW_HICONSM
: return wndPtr
->class->hIconSm
;
737 case GCW_ATOM
: return wndPtr
->class->atomName
;
742 return (WORD
)GetClassLong32A( hwnd
, offset
);
745 WARN(class, "Invalid offset %d\n", offset
);
750 /***********************************************************************
751 * GetClassLong16 (USER.131)
753 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
758 TRACE(class,"%x %x\n",hwnd
, offset
);
763 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
764 return (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
766 ret
= GetClassLong32A( hwnd
, offset
);
767 return (LONG
)SEGPTR_GET( (void *)ret
);
769 return GetClassLong32A( hwnd
, offset
);
774 /***********************************************************************
775 * GetClassLong32A (USER32.215)
777 LONG WINAPI
GetClassLong32A( HWND32 hwnd
, INT32 offset
)
781 TRACE(class,"%x %x\n",hwnd
, offset
);
783 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
786 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
787 return GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
791 case GCL_STYLE
: return (LONG
)wndPtr
->class->style
;
792 case GCL_CBWNDEXTRA
: return (LONG
)wndPtr
->class->cbWndExtra
;
793 case GCL_CBCLSEXTRA
: return (LONG
)wndPtr
->class->cbClsExtra
;
794 case GCL_HMODULE
: return (LONG
)wndPtr
->class->hInstance
;
796 return (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
798 return (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
800 case GCL_HBRBACKGROUND
:
804 return GetClassWord32( hwnd
, offset
);
806 WARN(class, "Invalid offset %d\n", offset
);
811 /***********************************************************************
812 * GetClassLong32W (USER32.216)
814 LONG WINAPI
GetClassLong32W( HWND32 hwnd
, INT32 offset
)
818 TRACE(class,"%x %x\n",hwnd
, offset
);
823 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
824 return (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
826 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
827 return (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
829 return GetClassLong32A( hwnd
, offset
);
834 /***********************************************************************
835 * SetClassWord16 (USER.130)
837 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
839 return SetClassWord32( hwnd
, offset
, newval
);
843 /***********************************************************************
844 * SetClassWord32 (USER32.469)
846 WORD WINAPI
SetClassWord32( HWND32 hwnd
, INT32 offset
, WORD newval
)
852 TRACE(class,"%x %x %x\n",hwnd
, offset
, newval
);
854 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
857 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
858 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
861 WARN( class, "Invalid offset %d\n", offset
);
871 return (WORD
)SetClassLong32A( hwnd
, offset
, (LONG
)newval
);
872 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
873 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
874 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
875 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
876 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
878 WARN( class, "Invalid offset %d\n", offset
);
881 retval
= GET_WORD(ptr
);
882 PUT_WORD( ptr
, newval
);
884 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
885 need to be updated as well. Problem is that we can't tell whether the atom is
886 using wide or narrow characters. For now, we'll just NULL out the className
887 fields, and emit a FIXME. */
888 if (offset
== GCW_ATOM
)
890 CLASS_SetClassNameA( wndPtr
->class, NULL
);
891 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
897 /***********************************************************************
898 * SetClassLong16 (USER.132)
900 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
905 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
910 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
911 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
912 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
913 WIN_PROC_16
, WIN_PROC_CLASS
);
916 return SetClassLong32A( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
918 return SetClassLong32A( hwnd
, offset
, newval
);
923 /***********************************************************************
924 * SetClassLong32A (USER32.467)
926 LONG WINAPI
SetClassLong32A( HWND32 hwnd
, INT32 offset
, LONG newval
)
932 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
934 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
937 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
938 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
941 WARN( class, "Invalid offset %d\n", offset
);
948 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
949 return 0; /* Old value is now meaningless anyway */
951 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
953 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
954 WIN_PROC_32A
, WIN_PROC_CLASS
);
956 case GCL_HBRBACKGROUND
:
960 return SetClassWord32( hwnd
, offset
, (WORD
)newval
);
961 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
962 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
963 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
964 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
966 WARN( class, "Invalid offset %d\n", offset
);
969 retval
= GET_DWORD(ptr
);
970 PUT_DWORD( ptr
, newval
);
975 /***********************************************************************
976 * SetClassLong32W (USER32.468)
978 LONG WINAPI
SetClassLong32W( HWND32 hwnd
, INT32 offset
, LONG newval
)
983 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
988 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
989 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
990 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
991 WIN_PROC_32W
, WIN_PROC_CLASS
);
994 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
995 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
996 return 0; /* Old value is now meaningless anyway */
998 return SetClassLong32A( hwnd
, offset
, newval
);
1003 /***********************************************************************
1004 * GetClassName16 (USER.58)
1006 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1009 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1010 return GlobalGetAtomName16( wndPtr
->class->atomName
, buffer
, count
);
1014 /***********************************************************************
1015 * GetClassName32A (USER32.217)
1017 INT32 WINAPI
GetClassName32A( HWND32 hwnd
, LPSTR buffer
, INT32 count
)
1021 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1022 ret
= GlobalGetAtomName32A( wndPtr
->class->atomName
, buffer
, count
);
1024 TRACE(class,"%x %s %x\n",hwnd
, buffer
, count
);
1029 /***********************************************************************
1030 * GetClassName32W (USER32.218)
1032 INT32 WINAPI
GetClassName32W( HWND32 hwnd
, LPWSTR buffer
, INT32 count
)
1036 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1037 ret
= GlobalGetAtomName32W( wndPtr
->class->atomName
, buffer
, count
);
1039 TRACE(class,"%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1045 /***********************************************************************
1046 * GetClassInfo16 (USER.404)
1048 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
,
1054 TRACE(class,"%x %p %p\n",hInstance
, PTR_SEG_TO_LIN (name
), wc
);
1056 hInstance
= GetExePtr( hInstance
);
1057 if (!(atom
= GlobalFindAtom16( name
)) ||
1058 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1060 if ((hInstance
!= classPtr
->hInstance
) &&
1061 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1063 wc
->style
= (UINT16
)classPtr
->style
;
1064 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1065 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1066 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1067 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1068 wc
->hIcon
= classPtr
->hIcon
;
1069 wc
->hCursor
= classPtr
->hCursor
;
1070 wc
->hbrBackground
= classPtr
->hbrBackground
;
1071 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1072 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1073 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1074 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1075 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1076 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1081 /***********************************************************************
1082 * GetClassInfo32A (USER32.211)
1084 BOOL32 WINAPI
GetClassInfo32A( HINSTANCE32 hInstance
, LPCSTR name
,
1090 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1092 /* workaround: if hInstance=NULL you expect to get the system classes
1093 but this classes (as example from comctl32.dll SysListView) won't be
1094 registred with hInstance=NULL in WINE because of the late loading
1095 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1097 if (!(atom
=GlobalFindAtom32A(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1100 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1102 if (hInstance
) return FALSE
;
1104 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1107 wc
->style
= classPtr
->style
;
1108 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1110 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1111 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1112 wc
->hInstance
= classPtr
->hInstance
;
1113 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1114 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1115 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1116 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1117 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1122 /***********************************************************************
1123 * GetClassInfo32W (USER32.214)
1125 BOOL32 WINAPI
GetClassInfo32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1131 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1133 if (!(atom
= GlobalFindAtom32W( name
)) ||
1134 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1135 (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)))
1138 wc
->style
= classPtr
->style
;
1139 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1141 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1142 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1143 wc
->hInstance
= classPtr
->hInstance
;
1144 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1145 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1146 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1147 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1148 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1153 /***********************************************************************
1154 * GetClassInfoEx16 (USER.398)
1156 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1157 * same in Win16 as in Win32. --AJ
1159 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
,
1165 TRACE(class,"%x %p %p\n",hInstance
,PTR_SEG_TO_LIN( name
), wc
);
1167 hInstance
= GetExePtr( hInstance
);
1168 if (!(atom
= GlobalFindAtom16( name
)) ||
1169 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1170 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1171 wc
->style
= classPtr
->style
;
1172 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1173 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1174 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1175 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1176 wc
->hIcon
= classPtr
->hIcon
;
1177 wc
->hIconSm
= classPtr
->hIconSm
;
1178 wc
->hCursor
= classPtr
->hCursor
;
1179 wc
->hbrBackground
= classPtr
->hbrBackground
;
1180 wc
->lpszClassName
= (SEGPTR
)0;
1181 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1182 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1183 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1184 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1185 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1186 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1191 /***********************************************************************
1192 * GetClassInfoEx32A (USER32.212)
1194 BOOL32 WINAPI
GetClassInfoEx32A( HINSTANCE32 hInstance
, LPCSTR name
,
1200 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1202 if (!(atom
= GlobalFindAtom32A( name
)) ||
1203 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1204 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1205 wc
->style
= classPtr
->style
;
1206 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1208 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1209 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1210 wc
->hInstance
= classPtr
->hInstance
;
1211 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1212 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1213 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1214 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1215 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1216 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1221 /***********************************************************************
1222 * GetClassInfoEx32W (USER32.213)
1224 BOOL32 WINAPI
GetClassInfoEx32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1230 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1232 if (!(atom
= GlobalFindAtom32W( name
)) ||
1233 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1234 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1235 wc
->style
= classPtr
->style
;
1236 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1238 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1239 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1240 wc
->hInstance
= classPtr
->hInstance
;
1241 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1242 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1243 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1244 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1245 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1246 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1251 /***********************************************************************
1252 * ClassFirst (TOOLHELP.69)
1254 BOOL16 WINAPI
ClassFirst( CLASSENTRY
*pClassEntry
)
1256 TRACE(class,"%p\n",pClassEntry
);
1257 pClassEntry
->wNext
= 1;
1258 return ClassNext( pClassEntry
);
1262 /***********************************************************************
1263 * ClassNext (TOOLHELP.70)
1265 BOOL16 WINAPI
ClassNext( CLASSENTRY
*pClassEntry
)
1268 CLASS
*class = firstClass
;
1270 TRACE(class,"%p\n",pClassEntry
);
1272 if (!pClassEntry
->wNext
) return FALSE
;
1273 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1276 pClassEntry
->wNext
= 0;
1279 pClassEntry
->hInst
= class->hInstance
;
1280 pClassEntry
->wNext
++;
1281 GlobalGetAtomName32A( class->atomName
, pClassEntry
->szClassName
,
1282 sizeof(pClassEntry
->szClassName
) );