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 );
799 case GCL_HBRBACKGROUND
:
803 return GetClassWord32( hwnd
, offset
);
805 WARN(class, "Invalid offset %d\n", offset
);
810 /***********************************************************************
811 * GetClassLong32W (USER32.216)
813 LONG WINAPI
GetClassLong32W( HWND32 hwnd
, INT32 offset
)
817 TRACE(class,"%x %x\n",hwnd
, offset
);
822 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
823 return (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
825 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
826 return (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
828 return GetClassLong32A( hwnd
, offset
);
833 /***********************************************************************
834 * SetClassWord16 (USER.130)
836 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
838 return SetClassWord32( hwnd
, offset
, newval
);
842 /***********************************************************************
843 * SetClassWord32 (USER32.469)
845 WORD WINAPI
SetClassWord32( HWND32 hwnd
, INT32 offset
, WORD newval
)
851 TRACE(class,"%x %x %x\n",hwnd
, offset
, newval
);
853 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
856 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
857 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
860 WARN( class, "Invalid offset %d\n", offset
);
870 return (WORD
)SetClassLong32A( hwnd
, offset
, (LONG
)newval
);
871 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
872 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
873 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
874 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
875 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
877 WARN( class, "Invalid offset %d\n", offset
);
880 retval
= GET_WORD(ptr
);
881 PUT_WORD( ptr
, newval
);
883 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
884 need to be updated as well. Problem is that we can't tell whether the atom is
885 using wide or narrow characters. For now, we'll just NULL out the className
886 fields, and emit a FIXME. */
887 if (offset
== GCW_ATOM
)
889 CLASS_SetClassNameA( wndPtr
->class, NULL
);
890 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
896 /***********************************************************************
897 * SetClassLong16 (USER.132)
899 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
904 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
909 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
910 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
911 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
912 WIN_PROC_16
, WIN_PROC_CLASS
);
915 return SetClassLong32A( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
917 return SetClassLong32A( hwnd
, offset
, newval
);
922 /***********************************************************************
923 * SetClassLong32A (USER32.467)
925 LONG WINAPI
SetClassLong32A( HWND32 hwnd
, INT32 offset
, LONG newval
)
931 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
933 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
936 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
937 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
940 WARN( class, "Invalid offset %d\n", offset
);
947 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
948 return 0; /* Old value is now meaningless anyway */
950 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
952 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
953 WIN_PROC_32A
, WIN_PROC_CLASS
);
955 case GCL_HBRBACKGROUND
:
959 return SetClassWord32( hwnd
, offset
, (WORD
)newval
);
960 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
961 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
962 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
963 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
965 WARN( class, "Invalid offset %d\n", offset
);
968 retval
= GET_DWORD(ptr
);
969 PUT_DWORD( ptr
, newval
);
974 /***********************************************************************
975 * SetClassLong32W (USER32.468)
977 LONG WINAPI
SetClassLong32W( HWND32 hwnd
, INT32 offset
, LONG newval
)
982 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
987 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
988 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
989 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
990 WIN_PROC_32W
, WIN_PROC_CLASS
);
993 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
994 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
995 return 0; /* Old value is now meaningless anyway */
997 return SetClassLong32A( hwnd
, offset
, newval
);
1002 /***********************************************************************
1003 * GetClassName16 (USER.58)
1005 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1008 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1009 return GlobalGetAtomName16( wndPtr
->class->atomName
, buffer
, count
);
1013 /***********************************************************************
1014 * GetClassName32A (USER32.217)
1016 INT32 WINAPI
GetClassName32A( HWND32 hwnd
, LPSTR buffer
, INT32 count
)
1020 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1021 ret
= GlobalGetAtomName32A( wndPtr
->class->atomName
, buffer
, count
);
1023 TRACE(class,"%x %s %x\n",hwnd
, buffer
, count
);
1028 /***********************************************************************
1029 * GetClassName32W (USER32.218)
1031 INT32 WINAPI
GetClassName32W( HWND32 hwnd
, LPWSTR buffer
, INT32 count
)
1035 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1036 ret
= GlobalGetAtomName32W( wndPtr
->class->atomName
, buffer
, count
);
1038 TRACE(class,"%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1044 /***********************************************************************
1045 * GetClassInfo16 (USER.404)
1047 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
,
1053 TRACE(class,"%x %p %p\n",hInstance
, PTR_SEG_TO_LIN (name
), wc
);
1055 hInstance
= GetExePtr( hInstance
);
1056 if (!(atom
= GlobalFindAtom16( name
)) ||
1057 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1059 if ((hInstance
!= classPtr
->hInstance
) &&
1060 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1062 wc
->style
= (UINT16
)classPtr
->style
;
1063 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1064 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1065 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1066 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1067 wc
->hIcon
= classPtr
->hIcon
;
1068 wc
->hCursor
= classPtr
->hCursor
;
1069 wc
->hbrBackground
= classPtr
->hbrBackground
;
1070 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1071 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1072 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1073 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1078 /***********************************************************************
1079 * GetClassInfo32A (USER32.211)
1081 BOOL32 WINAPI
GetClassInfo32A( HINSTANCE32 hInstance
, LPCSTR name
,
1087 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1089 /* workaround: if hInstance=NULL you expect to get the system classes
1090 but this classes (as example from comctl32.dll SysListView) won't be
1091 registred with hInstance=NULL in WINE because of the late loading
1092 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1094 if (!(atom
=GlobalFindAtom32A(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1097 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1099 if (hInstance
) return FALSE
;
1101 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1104 wc
->style
= classPtr
->style
;
1105 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1107 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1108 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1109 wc
->hInstance
= classPtr
->hInstance
;
1110 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1111 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1112 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1113 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1114 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1119 /***********************************************************************
1120 * GetClassInfo32W (USER32.214)
1122 BOOL32 WINAPI
GetClassInfo32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1128 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1130 if (!(atom
= GlobalFindAtom32W( name
)) ||
1131 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1132 (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)))
1135 wc
->style
= classPtr
->style
;
1136 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1138 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1139 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1140 wc
->hInstance
= classPtr
->hInstance
;
1141 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1142 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1143 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1144 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1145 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1150 /***********************************************************************
1151 * GetClassInfoEx16 (USER.398)
1153 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1154 * same in Win16 as in Win32. --AJ
1156 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
,
1162 TRACE(class,"%x %p %p\n",hInstance
,PTR_SEG_TO_LIN( name
), wc
);
1164 hInstance
= GetExePtr( hInstance
);
1165 if (!(atom
= GlobalFindAtom16( name
)) ||
1166 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1167 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1168 wc
->style
= classPtr
->style
;
1169 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1170 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1171 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1172 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1173 wc
->hIcon
= classPtr
->hIcon
;
1174 wc
->hIconSm
= classPtr
->hIconSm
;
1175 wc
->hCursor
= classPtr
->hCursor
;
1176 wc
->hbrBackground
= classPtr
->hbrBackground
;
1177 wc
->lpszClassName
= (SEGPTR
)0;
1178 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1179 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1180 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1181 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1182 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1183 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1188 /***********************************************************************
1189 * GetClassInfoEx32A (USER32.212)
1191 BOOL32 WINAPI
GetClassInfoEx32A( HINSTANCE32 hInstance
, LPCSTR name
,
1197 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1199 if (!(atom
= GlobalFindAtom32A( name
)) ||
1200 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1201 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1202 wc
->style
= classPtr
->style
;
1203 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1205 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1206 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1207 wc
->hInstance
= classPtr
->hInstance
;
1208 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1209 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1210 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1211 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1212 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1213 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1218 /***********************************************************************
1219 * GetClassInfoEx32W (USER32.213)
1221 BOOL32 WINAPI
GetClassInfoEx32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1227 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1229 if (!(atom
= GlobalFindAtom32W( name
)) ||
1230 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1231 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1232 wc
->style
= classPtr
->style
;
1233 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1235 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1236 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1237 wc
->hInstance
= classPtr
->hInstance
;
1238 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1239 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1240 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1241 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1242 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1243 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1248 /***********************************************************************
1249 * ClassFirst (TOOLHELP.69)
1251 BOOL16 WINAPI
ClassFirst( CLASSENTRY
*pClassEntry
)
1253 TRACE(class,"%p\n",pClassEntry
);
1254 pClassEntry
->wNext
= 1;
1255 return ClassNext( pClassEntry
);
1259 /***********************************************************************
1260 * ClassNext (TOOLHELP.70)
1262 BOOL16 WINAPI
ClassNext( CLASSENTRY
*pClassEntry
)
1265 CLASS
*class = firstClass
;
1267 TRACE(class,"%p\n",pClassEntry
);
1269 if (!pClassEntry
->wNext
) return FALSE
;
1270 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1273 pClassEntry
->wNext
= 0;
1276 pClassEntry
->hInst
= class->hInstance
;
1277 pClassEntry
->wNext
++;
1278 GlobalGetAtomName32A( class->atomName
, pClassEntry
->szClassName
,
1279 sizeof(pClassEntry
->szClassName
) );