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.
29 static CLASS
*firstClass
= NULL
;
32 /***********************************************************************
35 * Dump the content of a class structure to stderr.
37 void CLASS_DumpClass( CLASS
*ptr
)
39 char className
[MAX_CLASSNAME
+1];
42 if (ptr
->magic
!= CLASS_MAGIC
)
44 DUMP("%p is not a class\n", ptr
);
48 GlobalGetAtomName32A( ptr
->atomName
, className
, sizeof(className
) );
50 DUMP( "Class %p:\n", ptr
);
51 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
52 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
53 "clsExtra=%d winExtra=%d #windows=%d\n",
54 ptr
->next
, ptr
->atomName
, className
, ptr
->style
,
55 (UINT32
)ptr
->winproc
, ptr
->hInstance
, (UINT32
)ptr
->dce
,
56 ptr
->hIcon
, ptr
->hCursor
, ptr
->hbrBackground
,
57 ptr
->cbClsExtra
, ptr
->cbWndExtra
, ptr
->cWindows
);
60 DUMP( "extra bytes:" );
61 for (i
= 0; i
< ptr
->cbClsExtra
; i
++)
62 DUMP( " %02x", *((BYTE
*)ptr
->wExtra
+i
) );
69 /***********************************************************************
72 * Walk the class list and print each class on stderr.
74 void CLASS_WalkClasses(void)
77 char className
[MAX_CLASSNAME
+1];
79 DUMP( " Class Name Style WndProc\n" );
80 for (ptr
= firstClass
; ptr
; ptr
= ptr
->next
)
82 GlobalGetAtomName32A( ptr
->atomName
, className
, sizeof(className
) );
83 DUMP( "%08x %-20.20s %08x %08x\n", (UINT32
)ptr
, className
,
84 ptr
->style
, (UINT32
)ptr
->winproc
);
90 /***********************************************************************
93 * Get the menu name as a ASCII string.
95 static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
97 if (!classPtr
->menuNameA
&& classPtr
->menuNameW
)
99 /* We need to copy the Unicode string */
100 classPtr
->menuNameA
= SEGPTR_STRDUP_WtoA( classPtr
->menuNameW
);
102 return classPtr
->menuNameA
;
106 /***********************************************************************
109 * Get the menu name as a Unicode string.
111 static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
113 if (!classPtr
->menuNameW
&& classPtr
->menuNameA
)
115 if (!HIWORD(classPtr
->menuNameA
))
116 return (LPWSTR
)classPtr
->menuNameA
;
117 /* Now we need to copy the ASCII string */
118 classPtr
->menuNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
119 classPtr
->menuNameA
);
121 return classPtr
->menuNameW
;
125 /***********************************************************************
128 * Set the menu name in a class structure by copying the string.
130 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
132 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
133 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
134 classPtr
->menuNameA
= SEGPTR_STRDUP( name
);
135 classPtr
->menuNameW
= 0;
139 /***********************************************************************
142 * Set the menu name in a class structure by copying the string.
144 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
148 CLASS_SetMenuNameA( classPtr
, (LPCSTR
)name
);
151 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
152 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
153 if ((classPtr
->menuNameW
= HeapAlloc( SystemHeap
, 0,
154 (lstrlen32W(name
)+1)*sizeof(WCHAR
) )))
155 lstrcpy32W( classPtr
->menuNameW
, name
);
156 classPtr
->menuNameA
= 0;
160 /***********************************************************************
161 * CLASS_GetClassNameA
163 * Get the clas name as a ASCII string.
165 static LPSTR
CLASS_GetClassNameA( CLASS
*classPtr
)
167 if (!classPtr
->classNameA
&& classPtr
->classNameW
)
169 /* We need to copy the Unicode string */
170 classPtr
->classNameA
= SEGPTR_STRDUP_WtoA( classPtr
->classNameW
);
172 return classPtr
->classNameA
;
176 /***********************************************************************
177 * CLASS_GetClassNameW
179 * Get the class name as a Unicode string.
181 static LPWSTR
CLASS_GetClassNameW( CLASS
*classPtr
)
183 if (!classPtr
->classNameW
&& classPtr
->classNameA
)
185 if (!HIWORD(classPtr
->classNameA
))
186 return (LPWSTR
)classPtr
->classNameA
;
187 /* Now we need to copy the ASCII string */
188 classPtr
->classNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
189 classPtr
->classNameA
);
191 return classPtr
->classNameW
;
194 /***********************************************************************
195 * CLASS_SetClassNameA
197 * Set the class name in a class structure by copying the string.
199 static void CLASS_SetClassNameA( CLASS
*classPtr
, LPCSTR name
)
201 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
202 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
203 classPtr
->classNameA
= SEGPTR_STRDUP( name
);
204 classPtr
->classNameW
= 0;
208 /***********************************************************************
209 * CLASS_SetClassNameW
211 * Set the class name in a class structure by copying the string.
213 static void CLASS_SetClassNameW( CLASS
*classPtr
, LPCWSTR name
)
217 CLASS_SetClassNameA( classPtr
, (LPCSTR
)name
);
220 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
221 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
222 if ((classPtr
->classNameW
= HeapAlloc( SystemHeap
, 0,
223 (lstrlen32W(name
)+1)*sizeof(WCHAR
) )))
224 lstrcpy32W( classPtr
->classNameW
, name
);
225 classPtr
->classNameA
= 0;
229 /***********************************************************************
232 * Free a class structure.
234 static BOOL32
CLASS_FreeClass( CLASS
*classPtr
)
237 TRACE(class,"%p \n", classPtr
);
239 /* Check if we can remove this class */
241 if (classPtr
->cWindows
> 0) return FALSE
;
243 /* Remove the class from the linked list */
245 for (ppClass
= &firstClass
; *ppClass
; ppClass
= &(*ppClass
)->next
)
246 if (*ppClass
== classPtr
) break;
249 ERR( class, "Class list corrupted\n" );
252 *ppClass
= classPtr
->next
;
254 /* Delete the class */
256 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
257 if (classPtr
->hbrBackground
) DeleteObject32( classPtr
->hbrBackground
);
258 GlobalDeleteAtom( classPtr
->atomName
);
259 CLASS_SetMenuNameA( classPtr
, NULL
);
260 CLASS_SetClassNameA( classPtr
, NULL
);
261 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
262 HeapFree( SystemHeap
, 0, classPtr
);
267 /***********************************************************************
268 * CLASS_FreeModuleClasses
270 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
274 TRACE(class,"0x%08x \n", hModule
);
276 for (ptr
= firstClass
; ptr
; ptr
= next
)
279 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
284 /***********************************************************************
285 * CLASS_FindClassByAtom
287 * Return a pointer to the class.
288 * hinstance has been normalized by the caller.
291 * 980805 a local class will be found now if registred with hInst=0
292 * and looed up with a hInst!=0. msmoney does it (jsch)
294 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE32 hinstance
)
295 { CLASS
* class, *tclass
=0;
297 TRACE(class,"0x%08x 0x%08x\n", atom
, hinstance
);
299 /* First search task-specific classes */
301 for (class = firstClass
; (class); class = class->next
)
303 if (class->style
& CS_GLOBALCLASS
) continue;
304 if (class->atomName
== atom
)
306 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
308 TRACE(class,"-- found local %p\n", class);
311 if (class->hInstance
==0) tclass
= class;
315 /* Then search global classes */
317 for (class = firstClass
; (class); class = class->next
)
319 if (!(class->style
& CS_GLOBALCLASS
)) continue;
320 if (class->atomName
== atom
)
322 TRACE(class,"-- found global %p\n", class);
327 /* Then check if there was a local class with hInst=0*/
330 WARN(class,"-- found local Class registred with hInst=0\n");
334 TRACE(class,"-- not found\n");
339 /***********************************************************************
340 * CLASS_RegisterClass
342 * The real RegisterClass() functionality.
344 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE32 hInstance
,
345 DWORD style
, INT32 classExtra
,
346 INT32 winExtra
, WNDPROC16 wndProc
,
347 WINDOWPROCTYPE wndProcType
)
351 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
352 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
354 /* Check if a class with this name already exists */
355 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
358 /* Class can be created only if it is local and */
359 /* if the class with the same name is global. */
361 if (style
& CS_GLOBALCLASS
) return NULL
;
362 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
365 /* Fix the extra bytes value */
367 if (classExtra
< 0) classExtra
= 0;
368 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
369 WARN(class, "Class extra bytes %d is > 40\n", classExtra
);
370 if (winExtra
< 0) winExtra
= 0;
371 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
372 WARN(class, "Win extra bytes %d is > 40\n", winExtra
);
374 /* Create the class */
376 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
377 classExtra
- sizeof(classPtr
->wExtra
) );
378 if (!classPtr
) return NULL
;
379 classPtr
->next
= firstClass
;
380 classPtr
->magic
= CLASS_MAGIC
;
381 classPtr
->cWindows
= 0;
382 classPtr
->style
= style
;
383 classPtr
->winproc
= (HWINDOWPROC
)0;
384 classPtr
->cbWndExtra
= winExtra
;
385 classPtr
->cbClsExtra
= classExtra
;
386 classPtr
->hInstance
= hInstance
;
387 classPtr
->atomName
= atom
;
388 classPtr
->menuNameA
= 0;
389 classPtr
->menuNameW
= 0;
390 classPtr
->classNameA
= 0;
391 classPtr
->classNameA
= 0;
392 classPtr
->dce
= (style
& CS_CLASSDC
) ?
393 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
395 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
397 /* Other values must be set by caller */
399 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
400 firstClass
= classPtr
;
405 /***********************************************************************
406 * RegisterClass16 (USER.57)
408 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
412 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
414 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
415 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
416 wc
->cbClsExtra
, wc
->cbWndExtra
,
417 wc
->lpfnWndProc
, WIN_PROC_16
)))
419 GlobalDeleteAtom( atom
);
423 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
424 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
425 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
426 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
427 wc
->cbWndExtra
, classPtr
,
428 HIWORD(wc
->lpszClassName
) ?
429 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
431 classPtr
->hIcon
= wc
->hIcon
;
432 classPtr
->hIconSm
= 0;
433 classPtr
->hCursor
= wc
->hCursor
;
434 classPtr
->hbrBackground
= wc
->hbrBackground
;
436 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
437 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
438 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
439 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
445 /***********************************************************************
446 * RegisterClass32A (USER32.427)
448 * >0: Unique identifier
451 ATOM WINAPI
RegisterClass32A(
452 const WNDCLASS32A
* wc
/* Address of structure with class data */
457 if (!(atom
= GlobalAddAtom32A( wc
->lpszClassName
)))
459 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
462 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
463 wc
->cbClsExtra
, wc
->cbWndExtra
,
464 (WNDPROC16
)wc
->lpfnWndProc
,
466 { GlobalDeleteAtom( atom
);
467 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
471 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
472 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
473 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
474 wc
->cbWndExtra
, classPtr
,
475 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
477 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
478 classPtr
->hIconSm
= 0;
479 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
480 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
482 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
483 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
488 /***********************************************************************
489 * RegisterClass32W (USER32.430)
491 ATOM WINAPI
RegisterClass32W( const WNDCLASS32W
* wc
)
496 if (!(atom
= GlobalAddAtom32W( wc
->lpszClassName
)))
498 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
501 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
502 wc
->cbClsExtra
, wc
->cbWndExtra
,
503 (WNDPROC16
)wc
->lpfnWndProc
,
506 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
507 GlobalDeleteAtom( atom
);
511 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
512 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
513 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
514 wc
->cbWndExtra
, classPtr
);
516 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
517 classPtr
->hIconSm
= 0;
518 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
519 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
521 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
522 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
527 /***********************************************************************
528 * RegisterClassEx16 (USER.397)
530 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
534 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
536 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
537 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
538 wc
->cbClsExtra
, wc
->cbWndExtra
,
539 wc
->lpfnWndProc
, WIN_PROC_16
)))
541 GlobalDeleteAtom( atom
);
545 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
546 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
547 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
548 wc
->cbWndExtra
, classPtr
);
550 classPtr
->hIcon
= wc
->hIcon
;
551 classPtr
->hIconSm
= wc
->hIconSm
;
552 classPtr
->hCursor
= wc
->hCursor
;
553 classPtr
->hbrBackground
= wc
->hbrBackground
;
555 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
556 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
557 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
558 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
563 /***********************************************************************
564 * RegisterClassEx32A (USER32.428)
566 ATOM WINAPI
RegisterClassEx32A( const WNDCLASSEX32A
* wc
)
571 if (!(atom
= GlobalAddAtom32A( wc
->lpszClassName
)))
573 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
576 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
577 wc
->cbClsExtra
, wc
->cbWndExtra
,
578 (WNDPROC16
)wc
->lpfnWndProc
,
581 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
582 GlobalDeleteAtom( atom
);
586 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
587 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
588 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
589 wc
->cbWndExtra
, classPtr
);
591 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
592 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
593 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
594 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
595 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
596 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
601 /***********************************************************************
602 * RegisterClassEx32W (USER32.429)
604 ATOM WINAPI
RegisterClassEx32W( const WNDCLASSEX32W
* wc
)
609 if (!(atom
= GlobalAddAtom32W( wc
->lpszClassName
)))
611 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
614 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
615 wc
->cbClsExtra
, wc
->cbWndExtra
,
616 (WNDPROC16
)wc
->lpfnWndProc
,
619 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
620 GlobalDeleteAtom( atom
);
624 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
625 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
626 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
627 wc
->cbWndExtra
, classPtr
);
629 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
630 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
631 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
632 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
633 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
634 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
639 /***********************************************************************
640 * UnregisterClass16 (USER.403)
642 BOOL16 WINAPI
UnregisterClass16( SEGPTR className
, HINSTANCE16 hInstance
)
647 hInstance
= GetExePtr( hInstance
);
648 if (!(atom
= GlobalFindAtom16( className
))) return FALSE
;
649 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
650 (classPtr
->hInstance
!= hInstance
)) return FALSE
;
651 return CLASS_FreeClass( classPtr
);
655 /***********************************************************************
656 * UnregisterClass32A (USER32.563)
659 BOOL32 WINAPI
UnregisterClass32A( LPCSTR className
, HINSTANCE32 hInstance
)
664 TRACE(class,"%s %x\n",className
, hInstance
);
666 if (!(atom
= GlobalFindAtom32A( className
)))
668 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
671 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
672 (classPtr
->hInstance
!= hInstance
))
674 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
677 if (!(ret
= CLASS_FreeClass( classPtr
)))
678 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
682 /***********************************************************************
683 * UnregisterClass32W (USER32.564)
685 BOOL32 WINAPI
UnregisterClass32W( LPCWSTR className
, HINSTANCE32 hInstance
)
690 TRACE(class,"%s %x\n",debugstr_w(className
), hInstance
);
692 if (!(atom
= GlobalFindAtom32W( className
)))
694 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
697 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
698 (classPtr
->hInstance
!= hInstance
))
700 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
703 if (!(ret
= CLASS_FreeClass( classPtr
)))
704 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
708 /***********************************************************************
709 * GetClassWord16 (USER.129)
711 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
713 return GetClassWord32( hwnd
, offset
);
717 /***********************************************************************
718 * GetClassWord32 (USER32.219)
720 WORD WINAPI
GetClassWord32( HWND32 hwnd
, INT32 offset
)
724 TRACE(class,"%x %x\n",hwnd
, offset
);
726 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
729 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
730 return GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
734 case GCW_HBRBACKGROUND
: return wndPtr
->class->hbrBackground
;
735 case GCW_HCURSOR
: return wndPtr
->class->hCursor
;
736 case GCW_HICON
: return wndPtr
->class->hIcon
;
737 case GCW_HICONSM
: return wndPtr
->class->hIconSm
;
738 case GCW_ATOM
: return wndPtr
->class->atomName
;
743 return (WORD
)GetClassLong32A( hwnd
, offset
);
746 WARN(class, "Invalid offset %d\n", offset
);
751 /***********************************************************************
752 * GetClassLong16 (USER.131)
754 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
759 TRACE(class,"%x %x\n",hwnd
, offset
);
764 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
765 return (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
767 ret
= GetClassLong32A( hwnd
, offset
);
768 return (LONG
)SEGPTR_GET( (void *)ret
);
770 return GetClassLong32A( hwnd
, offset
);
775 /***********************************************************************
776 * GetClassLong32A (USER32.215)
778 LONG WINAPI
GetClassLong32A( HWND32 hwnd
, INT32 offset
)
782 TRACE(class,"%x %x\n",hwnd
, offset
);
784 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
787 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
788 return GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
792 case GCL_STYLE
: return (LONG
)wndPtr
->class->style
;
793 case GCL_CBWNDEXTRA
: return (LONG
)wndPtr
->class->cbWndExtra
;
794 case GCL_CBCLSEXTRA
: return (LONG
)wndPtr
->class->cbClsExtra
;
795 case GCL_HMODULE
: return (LONG
)wndPtr
->class->hInstance
;
797 return (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
799 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 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1073 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1074 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1079 /***********************************************************************
1080 * GetClassInfo32A (USER32.211)
1082 BOOL32 WINAPI
GetClassInfo32A( HINSTANCE32 hInstance
, LPCSTR name
,
1088 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1090 /* workaround: if hInstance=NULL you expect to get the system classes
1091 but this classes (as example from comctl32.dll SysListView) won't be
1092 registred with hInstance=NULL in WINE because of the late loading
1093 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1095 if (!(atom
=GlobalFindAtom32A(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1098 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1100 if (hInstance
) return FALSE
;
1102 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1105 wc
->style
= classPtr
->style
;
1106 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1108 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1109 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1110 wc
->hInstance
= classPtr
->hInstance
;
1111 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1112 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1113 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1114 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1115 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1120 /***********************************************************************
1121 * GetClassInfo32W (USER32.214)
1123 BOOL32 WINAPI
GetClassInfo32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1129 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1131 if (!(atom
= GlobalFindAtom32W( name
)) ||
1132 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1133 (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)))
1136 wc
->style
= classPtr
->style
;
1137 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1139 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1140 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1141 wc
->hInstance
= classPtr
->hInstance
;
1142 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1143 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1144 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1145 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1146 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1151 /***********************************************************************
1152 * GetClassInfoEx16 (USER.398)
1154 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1155 * same in Win16 as in Win32. --AJ
1157 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
,
1163 TRACE(class,"%x %p %p\n",hInstance
,PTR_SEG_TO_LIN( name
), wc
);
1165 hInstance
= GetExePtr( hInstance
);
1166 if (!(atom
= GlobalFindAtom16( name
)) ||
1167 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1168 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1169 wc
->style
= classPtr
->style
;
1170 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1171 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1172 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1173 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1174 wc
->hIcon
= classPtr
->hIcon
;
1175 wc
->hIconSm
= classPtr
->hIconSm
;
1176 wc
->hCursor
= classPtr
->hCursor
;
1177 wc
->hbrBackground
= classPtr
->hbrBackground
;
1178 wc
->lpszClassName
= (SEGPTR
)0;
1179 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1180 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1181 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1182 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1183 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1184 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1189 /***********************************************************************
1190 * GetClassInfoEx32A (USER32.212)
1192 BOOL32 WINAPI
GetClassInfoEx32A( HINSTANCE32 hInstance
, LPCSTR name
,
1198 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1200 if (!(atom
= GlobalFindAtom32A( name
)) ||
1201 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1202 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1203 wc
->style
= classPtr
->style
;
1204 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1206 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1207 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1208 wc
->hInstance
= classPtr
->hInstance
;
1209 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1210 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1211 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1212 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1213 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1214 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1219 /***********************************************************************
1220 * GetClassInfoEx32W (USER32.213)
1222 BOOL32 WINAPI
GetClassInfoEx32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1228 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1230 if (!(atom
= GlobalFindAtom32W( name
)) ||
1231 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1232 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1233 wc
->style
= classPtr
->style
;
1234 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1236 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1237 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1238 wc
->hInstance
= classPtr
->hInstance
;
1239 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1240 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1241 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1242 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1243 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1244 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1249 /***********************************************************************
1250 * ClassFirst (TOOLHELP.69)
1252 BOOL16 WINAPI
ClassFirst( CLASSENTRY
*pClassEntry
)
1254 TRACE(class,"%p\n",pClassEntry
);
1255 pClassEntry
->wNext
= 1;
1256 return ClassNext( pClassEntry
);
1260 /***********************************************************************
1261 * ClassNext (TOOLHELP.70)
1263 BOOL16 WINAPI
ClassNext( CLASSENTRY
*pClassEntry
)
1266 CLASS
*class = firstClass
;
1268 TRACE(class,"%p\n",pClassEntry
);
1270 if (!pClassEntry
->wNext
) return FALSE
;
1271 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1274 pClassEntry
->wNext
= 0;
1277 pClassEntry
->hInst
= class->hInstance
;
1278 pClassEntry
->wNext
++;
1279 GlobalGetAtomName32A( class->atomName
, pClassEntry
->szClassName
,
1280 sizeof(pClassEntry
->szClassName
) );