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.
26 #include "wine/winuser16.h"
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
->classNameW
= 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 );
801 case GCL_HBRBACKGROUND
:
805 return GetClassWord32( hwnd
, offset
);
807 WARN(class, "Invalid offset %d\n", offset
);
812 /***********************************************************************
813 * GetClassLong32W (USER32.216)
815 LONG WINAPI
GetClassLong32W( HWND32 hwnd
, INT32 offset
)
819 TRACE(class,"%x %x\n",hwnd
, offset
);
824 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
825 return (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
827 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
828 return (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
830 return GetClassLong32A( hwnd
, offset
);
835 /***********************************************************************
836 * SetClassWord16 (USER.130)
838 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
840 return SetClassWord32( hwnd
, offset
, newval
);
844 /***********************************************************************
845 * SetClassWord32 (USER32.469)
847 WORD WINAPI
SetClassWord32( HWND32 hwnd
, INT32 offset
, WORD newval
)
853 TRACE(class,"%x %x %x\n",hwnd
, offset
, newval
);
855 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
858 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
859 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
862 WARN( class, "Invalid offset %d\n", offset
);
872 return (WORD
)SetClassLong32A( hwnd
, offset
, (LONG
)newval
);
873 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
874 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
875 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
876 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
877 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
879 WARN( class, "Invalid offset %d\n", offset
);
882 retval
= GET_WORD(ptr
);
883 PUT_WORD( ptr
, newval
);
885 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
886 need to be updated as well. Problem is that we can't tell whether the atom is
887 using wide or narrow characters. For now, we'll just NULL out the className
888 fields, and emit a FIXME. */
889 if (offset
== GCW_ATOM
)
891 CLASS_SetClassNameA( wndPtr
->class, NULL
);
892 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
898 /***********************************************************************
899 * SetClassLong16 (USER.132)
901 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
906 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
911 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
912 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
913 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
914 WIN_PROC_16
, WIN_PROC_CLASS
);
917 return SetClassLong32A( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
919 return SetClassLong32A( hwnd
, offset
, newval
);
924 /***********************************************************************
925 * SetClassLong32A (USER32.467)
927 LONG WINAPI
SetClassLong32A( HWND32 hwnd
, INT32 offset
, LONG newval
)
933 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
935 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
938 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
939 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
942 WARN( class, "Invalid offset %d\n", offset
);
949 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
950 return 0; /* Old value is now meaningless anyway */
952 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
954 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
955 WIN_PROC_32A
, WIN_PROC_CLASS
);
957 case GCL_HBRBACKGROUND
:
961 return SetClassWord32( hwnd
, offset
, (WORD
)newval
);
962 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
963 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
964 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
965 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
967 WARN( class, "Invalid offset %d\n", offset
);
970 retval
= GET_DWORD(ptr
);
971 PUT_DWORD( ptr
, newval
);
976 /***********************************************************************
977 * SetClassLong32W (USER32.468)
979 LONG WINAPI
SetClassLong32W( HWND32 hwnd
, INT32 offset
, LONG newval
)
984 TRACE(class,"%x %x %lx\n",hwnd
, offset
, newval
);
989 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
990 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
991 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
992 WIN_PROC_32W
, WIN_PROC_CLASS
);
995 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
996 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
997 return 0; /* Old value is now meaningless anyway */
999 return SetClassLong32A( hwnd
, offset
, newval
);
1004 /***********************************************************************
1005 * GetClassName16 (USER.58)
1007 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1010 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1011 return GlobalGetAtomName16( wndPtr
->class->atomName
, buffer
, count
);
1015 /***********************************************************************
1016 * GetClassName32A (USER32.217)
1018 INT32 WINAPI
GetClassName32A( HWND32 hwnd
, LPSTR buffer
, INT32 count
)
1022 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1023 ret
= GlobalGetAtomName32A( wndPtr
->class->atomName
, buffer
, count
);
1025 TRACE(class,"%x %s %x\n",hwnd
, buffer
, count
);
1030 /***********************************************************************
1031 * GetClassName32W (USER32.218)
1033 INT32 WINAPI
GetClassName32W( HWND32 hwnd
, LPWSTR buffer
, INT32 count
)
1037 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1038 ret
= GlobalGetAtomName32W( wndPtr
->class->atomName
, buffer
, count
);
1040 TRACE(class,"%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1046 /***********************************************************************
1047 * GetClassInfo16 (USER.404)
1049 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
,
1055 TRACE(class,"%x %p %p\n",hInstance
, PTR_SEG_TO_LIN (name
), wc
);
1057 hInstance
= GetExePtr( hInstance
);
1058 if (!(atom
= GlobalFindAtom16( name
)) ||
1059 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1061 if ((hInstance
!= classPtr
->hInstance
) &&
1062 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1064 wc
->style
= (UINT16
)classPtr
->style
;
1065 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1066 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1067 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1068 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1069 wc
->hIcon
= classPtr
->hIcon
;
1070 wc
->hCursor
= classPtr
->hCursor
;
1071 wc
->hbrBackground
= classPtr
->hbrBackground
;
1072 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1073 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1074 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1075 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1076 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1077 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1082 /***********************************************************************
1083 * GetClassInfo32A (USER32.211)
1085 BOOL32 WINAPI
GetClassInfo32A( HINSTANCE32 hInstance
, LPCSTR name
,
1091 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1093 /* workaround: if hInstance=NULL you expect to get the system classes
1094 but this classes (as example from comctl32.dll SysListView) won't be
1095 registred with hInstance=NULL in WINE because of the late loading
1096 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1098 if (!(atom
=GlobalFindAtom32A(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1101 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1103 if (hInstance
) return FALSE
;
1105 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1108 wc
->style
= classPtr
->style
;
1109 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1111 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1112 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1113 wc
->hInstance
= classPtr
->hInstance
;
1114 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1115 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1116 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1117 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1118 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1123 /***********************************************************************
1124 * GetClassInfo32W (USER32.214)
1126 BOOL32 WINAPI
GetClassInfo32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1132 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1134 if (!(atom
= GlobalFindAtom32W( name
)) ||
1135 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1136 (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)))
1139 wc
->style
= classPtr
->style
;
1140 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1142 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1143 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1144 wc
->hInstance
= classPtr
->hInstance
;
1145 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1146 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1147 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1148 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1149 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1154 /***********************************************************************
1155 * GetClassInfoEx16 (USER.398)
1157 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1158 * same in Win16 as in Win32. --AJ
1160 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
,
1166 TRACE(class,"%x %p %p\n",hInstance
,PTR_SEG_TO_LIN( name
), wc
);
1168 hInstance
= GetExePtr( hInstance
);
1169 if (!(atom
= GlobalFindAtom16( name
)) ||
1170 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1171 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1172 wc
->style
= classPtr
->style
;
1173 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1174 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1175 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1176 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1177 wc
->hIcon
= classPtr
->hIcon
;
1178 wc
->hIconSm
= classPtr
->hIconSm
;
1179 wc
->hCursor
= classPtr
->hCursor
;
1180 wc
->hbrBackground
= classPtr
->hbrBackground
;
1181 wc
->lpszClassName
= (SEGPTR
)0;
1182 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1183 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1184 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1185 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1186 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1187 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1192 /***********************************************************************
1193 * GetClassInfoEx32A (USER32.212)
1195 BOOL32 WINAPI
GetClassInfoEx32A( HINSTANCE32 hInstance
, LPCSTR name
,
1201 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1203 if (!(atom
= GlobalFindAtom32A( name
)) ||
1204 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1205 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1206 wc
->style
= classPtr
->style
;
1207 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1209 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1210 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1211 wc
->hInstance
= classPtr
->hInstance
;
1212 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1213 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1214 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1215 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1216 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1217 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1222 /***********************************************************************
1223 * GetClassInfoEx32W (USER32.213)
1225 BOOL32 WINAPI
GetClassInfoEx32W( HINSTANCE32 hInstance
, LPCWSTR name
,
1231 TRACE(class,"%x %p %p\n",hInstance
, name
, wc
);
1233 if (!(atom
= GlobalFindAtom32W( name
)) ||
1234 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1235 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1236 wc
->style
= classPtr
->style
;
1237 wc
->lpfnWndProc
= (WNDPROC32
)WINPROC_GetProc( classPtr
->winproc
,
1239 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1240 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1241 wc
->hInstance
= classPtr
->hInstance
;
1242 wc
->hIcon
= (HICON32
)classPtr
->hIcon
;
1243 wc
->hIconSm
= (HICON32
)classPtr
->hIconSm
;
1244 wc
->hCursor
= (HCURSOR32
)classPtr
->hCursor
;
1245 wc
->hbrBackground
= (HBRUSH32
)classPtr
->hbrBackground
;
1246 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1247 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1252 /***********************************************************************
1253 * ClassFirst (TOOLHELP.69)
1255 BOOL16 WINAPI
ClassFirst( CLASSENTRY
*pClassEntry
)
1257 TRACE(class,"%p\n",pClassEntry
);
1258 pClassEntry
->wNext
= 1;
1259 return ClassNext( pClassEntry
);
1263 /***********************************************************************
1264 * ClassNext (TOOLHELP.70)
1266 BOOL16 WINAPI
ClassNext( CLASSENTRY
*pClassEntry
)
1269 CLASS
*class = firstClass
;
1271 TRACE(class,"%p\n",pClassEntry
);
1273 if (!pClassEntry
->wNext
) return FALSE
;
1274 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1277 pClassEntry
->wNext
= 0;
1280 pClassEntry
->hInst
= class->hInstance
;
1281 pClassEntry
->wNext
++;
1282 GlobalGetAtomName32A( class->atomName
, pClassEntry
->szClassName
,
1283 sizeof(pClassEntry
->szClassName
) );