2 * Window classes functions
4 * Copyright 1993, 1996 Alexandre Julliard
5 * 1998 Juergen Schmied (jsch)
7 * FIXME: In win32 all classes are local. They are registered at
8 * program start. Processes CANNOT share classes. (Source: some
9 * win31->NT migration book)
11 * FIXME: There seems to be a general problem with hInstance in WINE
12 * classes are getting registred with wrong hInstance.
17 #include "wine/winbase16.h"
25 #include "debugtools.h"
27 #include "wine/winuser16.h"
29 DEFAULT_DEBUG_CHANNEL(class)
32 static CLASS
*firstClass
= NULL
;
35 /***********************************************************************
38 * Dump the content of a class structure to stderr.
40 void CLASS_DumpClass( CLASS
*ptr
)
42 char className
[MAX_CLASSNAME
+1];
45 if (ptr
->magic
!= CLASS_MAGIC
)
47 DPRINTF("%p is not a class\n", ptr
);
51 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
53 DPRINTF( "Class %p:\n", ptr
);
54 DPRINTF( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
55 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
56 "clsExtra=%d winExtra=%d #windows=%d\n",
57 ptr
->next
, ptr
->atomName
, className
, ptr
->style
,
58 (UINT
)ptr
->winproc
, ptr
->hInstance
, (UINT
)ptr
->dce
,
59 ptr
->hIcon
, ptr
->hCursor
, ptr
->hbrBackground
,
60 ptr
->cbClsExtra
, ptr
->cbWndExtra
, ptr
->cWindows
);
63 DPRINTF( "extra bytes:" );
64 for (i
= 0; i
< ptr
->cbClsExtra
; i
++)
65 DPRINTF( " %02x", *((BYTE
*)ptr
->wExtra
+i
) );
72 /***********************************************************************
75 * Walk the class list and print each class on stderr.
77 void CLASS_WalkClasses(void)
80 char className
[MAX_CLASSNAME
+1];
82 DPRINTF( " Class Name Style WndProc\n" );
83 for (ptr
= firstClass
; ptr
; ptr
= ptr
->next
)
85 GlobalGetAtomNameA( ptr
->atomName
, className
, sizeof(className
) );
86 DPRINTF( "%08x %-20.20s %08x %08x\n", (UINT
)ptr
, className
,
87 ptr
->style
, (UINT
)ptr
->winproc
);
93 /***********************************************************************
96 * Get the menu name as a ASCII string.
98 static LPSTR
CLASS_GetMenuNameA( CLASS
*classPtr
)
100 if (!classPtr
->menuNameA
&& classPtr
->menuNameW
)
102 /* We need to copy the Unicode string */
103 classPtr
->menuNameA
= SEGPTR_STRDUP_WtoA( classPtr
->menuNameW
);
105 return classPtr
->menuNameA
;
109 /***********************************************************************
112 * Get the menu name as a Unicode string.
114 static LPWSTR
CLASS_GetMenuNameW( CLASS
*classPtr
)
116 if (!classPtr
->menuNameW
&& classPtr
->menuNameA
)
118 if (!HIWORD(classPtr
->menuNameA
))
119 return (LPWSTR
)classPtr
->menuNameA
;
120 /* Now we need to copy the ASCII string */
121 classPtr
->menuNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
122 classPtr
->menuNameA
);
124 return classPtr
->menuNameW
;
128 /***********************************************************************
131 * Set the menu name in a class structure by copying the string.
133 static void CLASS_SetMenuNameA( CLASS
*classPtr
, LPCSTR name
)
135 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
136 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
137 classPtr
->menuNameA
= SEGPTR_STRDUP( name
);
138 classPtr
->menuNameW
= 0;
142 /***********************************************************************
145 * Set the menu name in a class structure by copying the string.
147 static void CLASS_SetMenuNameW( CLASS
*classPtr
, LPCWSTR name
)
151 CLASS_SetMenuNameA( classPtr
, (LPCSTR
)name
);
154 if (HIWORD(classPtr
->menuNameA
)) SEGPTR_FREE( classPtr
->menuNameA
);
155 if (classPtr
->menuNameW
) HeapFree( SystemHeap
, 0, classPtr
->menuNameW
);
156 if ((classPtr
->menuNameW
= HeapAlloc( SystemHeap
, 0,
157 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
158 lstrcpyW( classPtr
->menuNameW
, name
);
159 classPtr
->menuNameA
= 0;
163 /***********************************************************************
164 * CLASS_GetClassNameA
166 * Get the clas name as a ASCII string.
168 static LPSTR
CLASS_GetClassNameA( CLASS
*classPtr
)
170 if (!classPtr
->classNameA
&& classPtr
->classNameW
)
172 /* We need to copy the Unicode string */
173 classPtr
->classNameA
= SEGPTR_STRDUP_WtoA( classPtr
->classNameW
);
175 return classPtr
->classNameA
;
179 /***********************************************************************
180 * CLASS_GetClassNameW
182 * Get the class name as a Unicode string.
184 static LPWSTR
CLASS_GetClassNameW( CLASS
*classPtr
)
186 if (!classPtr
->classNameW
&& classPtr
->classNameA
)
188 if (!HIWORD(classPtr
->classNameA
))
189 return (LPWSTR
)classPtr
->classNameA
;
190 /* Now we need to copy the ASCII string */
191 classPtr
->classNameW
= HEAP_strdupAtoW( SystemHeap
, 0,
192 classPtr
->classNameA
);
194 return classPtr
->classNameW
;
197 /***********************************************************************
198 * CLASS_SetClassNameA
200 * Set the class name in a class structure by copying the string.
202 static void CLASS_SetClassNameA( CLASS
*classPtr
, LPCSTR name
)
204 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
205 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
206 classPtr
->classNameA
= SEGPTR_STRDUP( name
);
207 classPtr
->classNameW
= 0;
211 /***********************************************************************
212 * CLASS_SetClassNameW
214 * Set the class name in a class structure by copying the string.
216 static void CLASS_SetClassNameW( CLASS
*classPtr
, LPCWSTR name
)
220 CLASS_SetClassNameA( classPtr
, (LPCSTR
)name
);
223 if (HIWORD(classPtr
->classNameA
)) SEGPTR_FREE( classPtr
->classNameA
);
224 if (classPtr
->classNameW
) HeapFree( SystemHeap
, 0, classPtr
->classNameW
);
225 if ((classPtr
->classNameW
= HeapAlloc( SystemHeap
, 0,
226 (lstrlenW(name
)+1)*sizeof(WCHAR
) )))
227 lstrcpyW( classPtr
->classNameW
, name
);
228 classPtr
->classNameA
= 0;
232 /***********************************************************************
235 * Free a class structure.
237 static BOOL
CLASS_FreeClass( CLASS
*classPtr
)
240 TRACE("%p \n", classPtr
);
242 /* Check if we can remove this class */
244 if (classPtr
->cWindows
> 0) return FALSE
;
246 /* Remove the class from the linked list */
248 for (ppClass
= &firstClass
; *ppClass
; ppClass
= &(*ppClass
)->next
)
249 if (*ppClass
== classPtr
) break;
252 ERR("Class list corrupted\n" );
255 *ppClass
= classPtr
->next
;
257 /* Delete the class */
259 if (classPtr
->dce
) DCE_FreeDCE( classPtr
->dce
);
260 if (classPtr
->hbrBackground
) DeleteObject( classPtr
->hbrBackground
);
261 GlobalDeleteAtom( classPtr
->atomName
);
262 CLASS_SetMenuNameA( classPtr
, NULL
);
263 CLASS_SetClassNameA( classPtr
, NULL
);
264 WINPROC_FreeProc( classPtr
->winproc
, WIN_PROC_CLASS
);
265 HeapFree( SystemHeap
, 0, classPtr
);
270 /***********************************************************************
271 * CLASS_FreeModuleClasses
273 void CLASS_FreeModuleClasses( HMODULE16 hModule
)
277 TRACE("0x%08x \n", hModule
);
279 for (ptr
= firstClass
; ptr
; ptr
= next
)
282 if (ptr
->hInstance
== hModule
) CLASS_FreeClass( ptr
);
287 /***********************************************************************
288 * CLASS_FindClassByAtom
290 * Return a pointer to the class.
291 * hinstance has been normalized by the caller.
294 * 980805 a local class will be found now if registred with hInst=0
295 * and looed up with a hInst!=0. msmoney does it (jsch)
297 CLASS
*CLASS_FindClassByAtom( ATOM atom
, HINSTANCE hinstance
)
298 { CLASS
* class, *tclass
=0;
300 TRACE("0x%08x 0x%08x\n", atom
, hinstance
);
302 /* First search task-specific classes */
304 for (class = firstClass
; (class); class = class->next
)
306 if (class->style
& CS_GLOBALCLASS
) continue;
307 if (class->atomName
== atom
)
309 if (hinstance
==class->hInstance
|| hinstance
==0xffff )
311 TRACE("-- found local %p\n", class);
314 if (class->hInstance
==0) tclass
= class;
318 /* Then search global classes */
320 for (class = firstClass
; (class); class = class->next
)
322 if (!(class->style
& CS_GLOBALCLASS
)) continue;
323 if (class->atomName
== atom
)
325 TRACE("-- found global %p\n", class);
330 /* Then check if there was a local class with hInst=0*/
333 WARN("-- found local Class registred with hInst=0\n");
337 TRACE("-- not found\n");
342 /***********************************************************************
343 * CLASS_RegisterClass
345 * The real RegisterClass() functionality.
347 static CLASS
*CLASS_RegisterClass( ATOM atom
, HINSTANCE hInstance
,
348 DWORD style
, INT classExtra
,
349 INT winExtra
, WNDPROC16 wndProc
,
350 WINDOWPROCTYPE wndProcType
)
354 TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
355 atom
, hInstance
, style
, classExtra
, winExtra
, wndProc
, wndProcType
);
357 /* Check if a class with this name already exists */
358 classPtr
= CLASS_FindClassByAtom( atom
, hInstance
);
361 /* Class can be created only if it is local and */
362 /* if the class with the same name is global. */
364 if (style
& CS_GLOBALCLASS
) return NULL
;
365 if (!(classPtr
->style
& CS_GLOBALCLASS
)) return NULL
;
368 /* Fix the extra bytes value */
370 if (classExtra
< 0) classExtra
= 0;
371 else if (classExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
372 WARN("Class extra bytes %d is > 40\n", classExtra
);
373 if (winExtra
< 0) winExtra
= 0;
374 else if (winExtra
> 40) /* Extra bytes are limited to 40 in Win32 */
375 WARN("Win extra bytes %d is > 40\n", winExtra
);
377 /* Create the class */
379 classPtr
= (CLASS
*)HeapAlloc( SystemHeap
, 0, sizeof(CLASS
) +
380 classExtra
- sizeof(classPtr
->wExtra
) );
381 if (!classPtr
) return NULL
;
382 classPtr
->next
= firstClass
;
383 classPtr
->magic
= CLASS_MAGIC
;
384 classPtr
->cWindows
= 0;
385 classPtr
->style
= style
;
386 classPtr
->winproc
= (HWINDOWPROC
)0;
387 classPtr
->cbWndExtra
= winExtra
;
388 classPtr
->cbClsExtra
= classExtra
;
389 classPtr
->hInstance
= hInstance
;
390 classPtr
->atomName
= atom
;
391 classPtr
->menuNameA
= 0;
392 classPtr
->menuNameW
= 0;
393 classPtr
->classNameA
= 0;
394 classPtr
->classNameW
= 0;
395 classPtr
->dce
= (style
& CS_CLASSDC
) ?
396 DCE_AllocDCE( 0, DCE_CLASS_DC
) : NULL
;
398 WINPROC_SetProc( &classPtr
->winproc
, wndProc
, wndProcType
, WIN_PROC_CLASS
);
400 /* Other values must be set by caller */
402 if (classExtra
) memset( classPtr
->wExtra
, 0, classExtra
);
403 firstClass
= classPtr
;
408 /***********************************************************************
409 * RegisterClass16 (USER.57)
411 ATOM WINAPI
RegisterClass16( const WNDCLASS16
*wc
)
415 HINSTANCE16 hInstance
=GetExePtr(wc
->hInstance
);
417 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
418 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
419 wc
->cbClsExtra
, wc
->cbWndExtra
,
420 wc
->lpfnWndProc
, WIN_PROC_16
)))
422 GlobalDeleteAtom( atom
);
426 TRACE("atom=%04x wndproc=%08lx hinst=%04x "
427 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
428 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
429 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
430 wc
->cbWndExtra
, classPtr
,
431 HIWORD(wc
->lpszClassName
) ?
432 (char *)PTR_SEG_TO_LIN(wc
->lpszClassName
) : "" );
434 classPtr
->hIcon
= wc
->hIcon
;
435 classPtr
->hIconSm
= 0;
436 classPtr
->hCursor
= wc
->hCursor
;
437 classPtr
->hbrBackground
= wc
->hbrBackground
;
439 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
440 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
441 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
442 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
448 /***********************************************************************
449 * RegisterClass32A (USER32.427)
451 * >0: Unique identifier
454 ATOM WINAPI
RegisterClassA(
455 const WNDCLASSA
* wc
/* Address of structure with class data */
460 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
462 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
465 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
466 wc
->cbClsExtra
, wc
->cbWndExtra
,
467 (WNDPROC16
)wc
->lpfnWndProc
,
469 { GlobalDeleteAtom( atom
);
470 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
474 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
475 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
476 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
477 wc
->cbWndExtra
, classPtr
,
478 HIWORD(wc
->lpszClassName
) ? wc
->lpszClassName
: "" );
480 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
481 classPtr
->hIconSm
= 0;
482 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
483 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
485 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
486 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
491 /***********************************************************************
492 * RegisterClass32W (USER32.430)
494 ATOM WINAPI
RegisterClassW( const WNDCLASSW
* wc
)
499 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
501 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
504 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
505 wc
->cbClsExtra
, wc
->cbWndExtra
,
506 (WNDPROC16
)wc
->lpfnWndProc
,
509 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
510 GlobalDeleteAtom( atom
);
514 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
515 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
516 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
517 wc
->cbWndExtra
, classPtr
);
519 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
520 classPtr
->hIconSm
= 0;
521 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
522 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
524 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
525 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
530 /***********************************************************************
531 * RegisterClassEx16 (USER.397)
533 ATOM WINAPI
RegisterClassEx16( const WNDCLASSEX16
*wc
)
537 HINSTANCE16 hInstance
= GetExePtr( wc
->hInstance
);
539 if (!(atom
= GlobalAddAtom16( wc
->lpszClassName
))) return 0;
540 if (!(classPtr
= CLASS_RegisterClass( atom
, hInstance
, wc
->style
,
541 wc
->cbClsExtra
, wc
->cbWndExtra
,
542 wc
->lpfnWndProc
, WIN_PROC_16
)))
544 GlobalDeleteAtom( atom
);
548 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
549 atom
, (DWORD
)wc
->lpfnWndProc
, hInstance
,
550 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
551 wc
->cbWndExtra
, classPtr
);
553 classPtr
->hIcon
= wc
->hIcon
;
554 classPtr
->hIconSm
= wc
->hIconSm
;
555 classPtr
->hCursor
= wc
->hCursor
;
556 classPtr
->hbrBackground
= wc
->hbrBackground
;
558 CLASS_SetMenuNameA( classPtr
, HIWORD(wc
->lpszMenuName
) ?
559 PTR_SEG_TO_LIN(wc
->lpszMenuName
) : (LPCSTR
)wc
->lpszMenuName
);
560 CLASS_SetClassNameA( classPtr
, HIWORD(wc
->lpszClassName
) ?
561 PTR_SEG_TO_LIN(wc
->lpszClassName
) : (LPCSTR
)wc
->lpszClassName
);
566 /***********************************************************************
567 * RegisterClassEx32A (USER32.428)
569 ATOM WINAPI
RegisterClassExA( const WNDCLASSEXA
* wc
)
574 if (!(atom
= GlobalAddAtomA( wc
->lpszClassName
)))
576 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
579 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
580 wc
->cbClsExtra
, wc
->cbWndExtra
,
581 (WNDPROC16
)wc
->lpfnWndProc
,
584 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
585 GlobalDeleteAtom( atom
);
589 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
590 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
591 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
592 wc
->cbWndExtra
, classPtr
);
594 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
595 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
596 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
597 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
598 CLASS_SetMenuNameA( classPtr
, wc
->lpszMenuName
);
599 CLASS_SetClassNameA( classPtr
, wc
->lpszClassName
);
604 /***********************************************************************
605 * RegisterClassEx32W (USER32.429)
607 ATOM WINAPI
RegisterClassExW( const WNDCLASSEXW
* wc
)
612 if (!(atom
= GlobalAddAtomW( wc
->lpszClassName
)))
614 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
617 if (!(classPtr
= CLASS_RegisterClass( atom
, wc
->hInstance
, wc
->style
,
618 wc
->cbClsExtra
, wc
->cbWndExtra
,
619 (WNDPROC16
)wc
->lpfnWndProc
,
622 SetLastError(ERROR_CLASS_ALREADY_EXISTS
);
623 GlobalDeleteAtom( atom
);
627 TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
628 atom
, (DWORD
)wc
->lpfnWndProc
, wc
->hInstance
,
629 wc
->hbrBackground
, wc
->style
, wc
->cbClsExtra
,
630 wc
->cbWndExtra
, classPtr
);
632 classPtr
->hIcon
= (HICON16
)wc
->hIcon
;
633 classPtr
->hIconSm
= (HICON16
)wc
->hIconSm
;
634 classPtr
->hCursor
= (HCURSOR16
)wc
->hCursor
;
635 classPtr
->hbrBackground
= (HBRUSH16
)wc
->hbrBackground
;
636 CLASS_SetMenuNameW( classPtr
, wc
->lpszMenuName
);
637 CLASS_SetClassNameW( classPtr
, wc
->lpszClassName
);
642 /***********************************************************************
643 * UnregisterClass16 (USER.403)
645 BOOL16 WINAPI
UnregisterClass16( SEGPTR className
, HINSTANCE16 hInstance
)
650 hInstance
= GetExePtr( hInstance
);
651 if (!(atom
= GlobalFindAtom16( className
))) return FALSE
;
652 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
653 (classPtr
->hInstance
!= hInstance
)) return FALSE
;
654 return CLASS_FreeClass( classPtr
);
658 /***********************************************************************
659 * UnregisterClass32A (USER32.563)
662 BOOL WINAPI
UnregisterClassA( LPCSTR className
, HINSTANCE hInstance
)
667 TRACE("%s %x\n",debugres_a(className
), hInstance
);
669 if (!(atom
= GlobalFindAtomA( className
)))
671 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
674 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
675 (classPtr
->hInstance
!= hInstance
))
677 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
680 if (!(ret
= CLASS_FreeClass( classPtr
)))
681 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
685 /***********************************************************************
686 * UnregisterClass32W (USER32.564)
688 BOOL WINAPI
UnregisterClassW( LPCWSTR className
, HINSTANCE hInstance
)
693 TRACE("%s %x\n",debugres_w(className
), hInstance
);
695 if (!(atom
= GlobalFindAtomW( className
)))
697 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
700 if (!(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
701 (classPtr
->hInstance
!= hInstance
))
703 SetLastError(ERROR_CLASS_DOES_NOT_EXIST
);
706 if (!(ret
= CLASS_FreeClass( classPtr
)))
707 SetLastError(ERROR_CLASS_HAS_WINDOWS
);
711 /***********************************************************************
712 * GetClassWord16 (USER.129)
714 WORD WINAPI
GetClassWord16( HWND16 hwnd
, INT16 offset
)
716 return GetClassWord( hwnd
, offset
);
720 /***********************************************************************
721 * GetClassWord32 (USER32.219)
723 WORD WINAPI
GetClassWord( HWND hwnd
, INT offset
)
728 TRACE("%x %x\n",hwnd
, offset
);
730 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
733 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(WORD
))
735 retvalue
= GET_WORD(((char *)wndPtr
->class->wExtra
) + offset
);
741 case GCW_HBRBACKGROUND
: retvalue
= wndPtr
->class->hbrBackground
;
743 case GCW_HCURSOR
: retvalue
= wndPtr
->class->hCursor
;
745 case GCW_HICON
: retvalue
= wndPtr
->class->hIcon
;
747 case GCW_HICONSM
: retvalue
= wndPtr
->class->hIconSm
;
749 case GCW_ATOM
: retvalue
= wndPtr
->class->atomName
;
755 retvalue
= (WORD
)GetClassLongA( hwnd
, offset
);
758 WARN("Invalid offset %d\n", offset
);
760 WIN_ReleaseWndPtr(wndPtr
);
765 /***********************************************************************
766 * GetClassLong16 (USER.131)
768 LONG WINAPI
GetClassLong16( HWND16 hwnd
, INT16 offset
)
773 TRACE("%x %x\n",hwnd
, offset
);
778 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
779 ret
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
780 WIN_ReleaseWndPtr(wndPtr
);
783 ret
= GetClassLongA( hwnd
, offset
);
784 return (LONG
)SEGPTR_GET( (void *)ret
);
786 return GetClassLongA( hwnd
, offset
);
791 /***********************************************************************
792 * GetClassLong32A (USER32.215)
794 LONG WINAPI
GetClassLongA( HWND hwnd
, INT offset
)
799 TRACE("%x %x\n",hwnd
, offset
);
801 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
804 if (offset
<= wndPtr
->class->cbClsExtra
- sizeof(LONG
))
806 retvalue
= GET_DWORD(((char *)wndPtr
->class->wExtra
) + offset
);
813 case GCL_STYLE
: retvalue
= (LONG
)wndPtr
->class->style
;
815 case GCL_CBWNDEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbWndExtra
;
817 case GCL_CBCLSEXTRA
: retvalue
= (LONG
)wndPtr
->class->cbClsExtra
;
819 case GCL_HMODULE
: retvalue
= (LONG
)wndPtr
->class->hInstance
;
822 retvalue
= (LONG
)WINPROC_GetProc(wndPtr
->class->winproc
, WIN_PROC_32A
);
825 retvalue
= (LONG
)CLASS_GetMenuNameA( wndPtr
->class );
828 case GCL_HBRBACKGROUND
:
832 retvalue
= GetClassWord( hwnd
, offset
);
835 WARN("Invalid offset %d\n", offset
);
838 WIN_ReleaseWndPtr(wndPtr
);
843 /***********************************************************************
844 * GetClassLong32W (USER32.216)
846 LONG WINAPI
GetClassLongW( HWND hwnd
, INT offset
)
851 TRACE("%x %x\n",hwnd
, offset
);
856 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
857 retvalue
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
858 WIN_ReleaseWndPtr(wndPtr
);
861 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
862 retvalue
= (LONG
)CLASS_GetMenuNameW( wndPtr
->class );
863 WIN_ReleaseWndPtr(wndPtr
);
866 return GetClassLongA( hwnd
, offset
);
871 /***********************************************************************
872 * SetClassWord16 (USER.130)
874 WORD WINAPI
SetClassWord16( HWND16 hwnd
, INT16 offset
, WORD newval
)
876 return SetClassWord( hwnd
, offset
, newval
);
880 /***********************************************************************
881 * SetClassWord32 (USER32.469)
883 WORD WINAPI
SetClassWord( HWND hwnd
, INT offset
, WORD newval
)
889 TRACE("%x %x %x\n",hwnd
, offset
, newval
);
891 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
894 if (offset
+ sizeof(WORD
) <= wndPtr
->class->cbClsExtra
)
895 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
898 WARN("Invalid offset %d\n", offset
);
899 WIN_ReleaseWndPtr(wndPtr
);
909 WIN_ReleaseWndPtr(wndPtr
);
910 return (WORD
)SetClassLongA( hwnd
, offset
, (LONG
)newval
);
911 case GCW_HBRBACKGROUND
: ptr
= &wndPtr
->class->hbrBackground
; break;
912 case GCW_HCURSOR
: ptr
= &wndPtr
->class->hCursor
; break;
913 case GCW_HICON
: ptr
= &wndPtr
->class->hIcon
; break;
914 case GCW_HICONSM
: ptr
= &wndPtr
->class->hIconSm
; break;
915 case GCW_ATOM
: ptr
= &wndPtr
->class->atomName
; break;
917 WARN("Invalid offset %d\n", offset
);
918 WIN_ReleaseWndPtr(wndPtr
);
921 retval
= GET_WORD(ptr
);
922 PUT_WORD( ptr
, newval
);
924 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
925 need to be updated as well. Problem is that we can't tell whether the atom is
926 using wide or narrow characters. For now, we'll just NULL out the className
927 fields, and emit a FIXME. */
928 if (offset
== GCW_ATOM
)
930 CLASS_SetClassNameA( wndPtr
->class, NULL
);
931 FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
933 WIN_ReleaseWndPtr(wndPtr
);
938 /***********************************************************************
939 * SetClassLong16 (USER.132)
941 LONG WINAPI
SetClassLong16( HWND16 hwnd
, INT16 offset
, LONG newval
)
946 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
951 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
952 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_16
);
953 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
954 WIN_PROC_16
, WIN_PROC_CLASS
);
955 WIN_ReleaseWndPtr(wndPtr
);
958 return SetClassLongA( hwnd
, offset
, (LONG
)PTR_SEG_TO_LIN(newval
) );
960 return SetClassLongA( hwnd
, offset
, newval
);
965 /***********************************************************************
966 * SetClassLong32A (USER32.467)
968 LONG WINAPI
SetClassLongA( HWND hwnd
, INT offset
, LONG newval
)
974 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
976 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
979 if (offset
+ sizeof(LONG
) <= wndPtr
->class->cbClsExtra
)
980 ptr
= ((char *)wndPtr
->class->wExtra
) + offset
;
983 WARN("Invalid offset %d\n", offset
);
991 CLASS_SetMenuNameA( wndPtr
->class, (LPCSTR
)newval
);
992 retval
= 0; /* Old value is now meaningless anyway */
995 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
,
997 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
998 WIN_PROC_32A
, WIN_PROC_CLASS
);
1000 case GCL_HBRBACKGROUND
:
1004 retval
= SetClassWord( hwnd
, offset
, (WORD
)newval
);
1006 case GCL_STYLE
: ptr
= &wndPtr
->class->style
; break;
1007 case GCL_CBWNDEXTRA
: ptr
= &wndPtr
->class->cbWndExtra
; break;
1008 case GCL_CBCLSEXTRA
: ptr
= &wndPtr
->class->cbClsExtra
; break;
1009 case GCL_HMODULE
: ptr
= &wndPtr
->class->hInstance
; break;
1011 WARN("Invalid offset %d\n", offset
);
1015 retval
= GET_DWORD(ptr
);
1016 PUT_DWORD( ptr
, newval
);
1018 WIN_ReleaseWndPtr(wndPtr
);
1023 /***********************************************************************
1024 * SetClassLong32W (USER32.468)
1026 LONG WINAPI
SetClassLongW( HWND hwnd
, INT offset
, LONG newval
)
1031 TRACE("%x %x %lx\n",hwnd
, offset
, newval
);
1036 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1037 retval
= (LONG
)WINPROC_GetProc( wndPtr
->class->winproc
, WIN_PROC_32W
);
1038 WINPROC_SetProc( &wndPtr
->class->winproc
, (WNDPROC16
)newval
,
1039 WIN_PROC_32W
, WIN_PROC_CLASS
);
1040 WIN_ReleaseWndPtr(wndPtr
);
1043 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1044 CLASS_SetMenuNameW( wndPtr
->class, (LPCWSTR
)newval
);
1045 WIN_ReleaseWndPtr(wndPtr
);
1046 return 0; /* Old value is now meaningless anyway */
1048 return SetClassLongA( hwnd
, offset
, newval
);
1053 /***********************************************************************
1054 * GetClassName16 (USER.58)
1056 INT16 WINAPI
GetClassName16( HWND16 hwnd
, LPSTR buffer
, INT16 count
)
1060 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1061 retvalue
= GlobalGetAtomName16( wndPtr
->class->atomName
, buffer
, count
);
1062 WIN_ReleaseWndPtr(wndPtr
);
1067 /***********************************************************************
1068 * GetClassName32A (USER32.217)
1070 INT WINAPI
GetClassNameA( HWND hwnd
, LPSTR buffer
, INT count
)
1074 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1075 ret
= GlobalGetAtomNameA( wndPtr
->class->atomName
, buffer
, count
);
1077 WIN_ReleaseWndPtr(wndPtr
);
1078 TRACE("%x %s %x\n",hwnd
, buffer
, count
);
1083 /***********************************************************************
1084 * GetClassName32W (USER32.218)
1086 INT WINAPI
GetClassNameW( HWND hwnd
, LPWSTR buffer
, INT count
)
1090 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
1091 ret
= GlobalGetAtomNameW( wndPtr
->class->atomName
, buffer
, count
);
1092 WIN_ReleaseWndPtr(wndPtr
);
1093 TRACE("%x %s %x\n",hwnd
, debugstr_w(buffer
), count
);
1099 /***********************************************************************
1100 * GetClassInfo16 (USER.404)
1102 BOOL16 WINAPI
GetClassInfo16( HINSTANCE16 hInstance
, SEGPTR name
,
1108 TRACE("%x %p %p\n",hInstance
, PTR_SEG_TO_LIN (name
), wc
);
1110 hInstance
= GetExePtr( hInstance
);
1111 if (!(atom
= GlobalFindAtom16( name
)) ||
1112 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)))
1114 if ((hInstance
!= classPtr
->hInstance
) &&
1115 !(classPtr
->style
& CS_GLOBALCLASS
)) /*BWCC likes to pass hInstance=0*/
1117 wc
->style
= (UINT16
)classPtr
->style
;
1118 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1119 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1120 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1121 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1122 wc
->hIcon
= classPtr
->hIcon
;
1123 wc
->hCursor
= classPtr
->hCursor
;
1124 wc
->hbrBackground
= classPtr
->hbrBackground
;
1125 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);;
1126 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1127 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1128 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1129 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1130 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1135 /***********************************************************************
1136 * GetClassInfo32A (USER32.211)
1138 BOOL WINAPI
GetClassInfoA( HINSTANCE hInstance
, LPCSTR name
,
1144 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1146 /* workaround: if hInstance=NULL you expect to get the system classes
1147 but this classes (as example from comctl32.dll SysListView) won't be
1148 registred with hInstance=NULL in WINE because of the late loading
1149 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1151 if (!(atom
=GlobalFindAtomA(name
)) || !(classPtr
=CLASS_FindClassByAtom(atom
,hInstance
)))
1154 if (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
))
1156 if (hInstance
) return FALSE
;
1158 WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name
);
1161 wc
->style
= classPtr
->style
;
1162 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1164 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1165 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1166 wc
->hInstance
= classPtr
->hInstance
;
1167 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1168 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1169 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1170 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1171 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1176 /***********************************************************************
1177 * GetClassInfo32W (USER32.214)
1179 BOOL WINAPI
GetClassInfoW( HINSTANCE hInstance
, LPCWSTR name
,
1185 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1187 if (!(atom
= GlobalFindAtomW( name
)) ||
1188 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1189 (classPtr
->hInstance
&& (hInstance
!= classPtr
->hInstance
)))
1192 wc
->style
= classPtr
->style
;
1193 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1195 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1196 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1197 wc
->hInstance
= classPtr
->hInstance
;
1198 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1199 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1200 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1201 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1202 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);
1207 /***********************************************************************
1208 * GetClassInfoEx16 (USER.398)
1210 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1211 * same in Win16 as in Win32. --AJ
1213 BOOL16 WINAPI
GetClassInfoEx16( HINSTANCE16 hInstance
, SEGPTR name
,
1219 TRACE("%x %p %p\n",hInstance
,PTR_SEG_TO_LIN( name
), wc
);
1221 hInstance
= GetExePtr( hInstance
);
1222 if (!(atom
= GlobalFindAtom16( name
)) ||
1223 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1224 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1225 wc
->style
= classPtr
->style
;
1226 wc
->lpfnWndProc
= WINPROC_GetProc( classPtr
->winproc
, WIN_PROC_16
);
1227 wc
->cbClsExtra
= (INT16
)classPtr
->cbClsExtra
;
1228 wc
->cbWndExtra
= (INT16
)classPtr
->cbWndExtra
;
1229 wc
->hInstance
= (HINSTANCE16
)classPtr
->hInstance
;
1230 wc
->hIcon
= classPtr
->hIcon
;
1231 wc
->hIconSm
= classPtr
->hIconSm
;
1232 wc
->hCursor
= classPtr
->hCursor
;
1233 wc
->hbrBackground
= classPtr
->hbrBackground
;
1234 wc
->lpszClassName
= (SEGPTR
)0;
1235 wc
->lpszMenuName
= (SEGPTR
)CLASS_GetMenuNameA( classPtr
);
1236 if (HIWORD(wc
->lpszMenuName
)) /* Make it a SEGPTR */
1237 wc
->lpszMenuName
= SEGPTR_GET( (LPSTR
)wc
->lpszMenuName
);
1238 wc
->lpszClassName
= (SEGPTR
)CLASS_GetClassNameA( classPtr
);
1239 if (HIWORD(wc
->lpszClassName
)) /* Make it a SEGPTR */
1240 wc
->lpszClassName
= SEGPTR_GET( (LPSTR
)wc
->lpszClassName
);
1245 /***********************************************************************
1246 * GetClassInfoEx32A (USER32.212)
1248 BOOL WINAPI
GetClassInfoExA( HINSTANCE hInstance
, LPCSTR name
,
1254 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1256 if (!(atom
= GlobalFindAtomA( name
)) ||
1257 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
))
1258 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE
;
1259 wc
->style
= classPtr
->style
;
1260 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1262 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1263 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1264 wc
->hInstance
= classPtr
->hInstance
;
1265 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1266 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1267 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1268 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1269 wc
->lpszMenuName
= CLASS_GetMenuNameA( classPtr
);
1270 wc
->lpszClassName
= CLASS_GetClassNameA( classPtr
);
1275 /***********************************************************************
1276 * GetClassInfoEx32W (USER32.213)
1278 BOOL WINAPI
GetClassInfoExW( HINSTANCE hInstance
, LPCWSTR name
,
1284 TRACE("%x %p %p\n",hInstance
, name
, wc
);
1286 if (!(atom
= GlobalFindAtomW( name
)) ||
1287 !(classPtr
= CLASS_FindClassByAtom( atom
, hInstance
)) ||
1288 (hInstance
!= classPtr
->hInstance
)) return FALSE
;
1289 wc
->style
= classPtr
->style
;
1290 wc
->lpfnWndProc
= (WNDPROC
)WINPROC_GetProc( classPtr
->winproc
,
1292 wc
->cbClsExtra
= classPtr
->cbClsExtra
;
1293 wc
->cbWndExtra
= classPtr
->cbWndExtra
;
1294 wc
->hInstance
= classPtr
->hInstance
;
1295 wc
->hIcon
= (HICON
)classPtr
->hIcon
;
1296 wc
->hIconSm
= (HICON
)classPtr
->hIconSm
;
1297 wc
->hCursor
= (HCURSOR
)classPtr
->hCursor
;
1298 wc
->hbrBackground
= (HBRUSH
)classPtr
->hbrBackground
;
1299 wc
->lpszMenuName
= CLASS_GetMenuNameW( classPtr
);
1300 wc
->lpszClassName
= CLASS_GetClassNameW( classPtr
);;
1305 /***********************************************************************
1306 * ClassFirst (TOOLHELP.69)
1308 BOOL16 WINAPI
ClassFirst16( CLASSENTRY
*pClassEntry
)
1310 TRACE("%p\n",pClassEntry
);
1311 pClassEntry
->wNext
= 1;
1312 return ClassNext16( pClassEntry
);
1316 /***********************************************************************
1317 * ClassNext (TOOLHELP.70)
1319 BOOL16 WINAPI
ClassNext16( CLASSENTRY
*pClassEntry
)
1322 CLASS
*class = firstClass
;
1324 TRACE("%p\n",pClassEntry
);
1326 if (!pClassEntry
->wNext
) return FALSE
;
1327 for (i
= 1; (i
< pClassEntry
->wNext
) && class; i
++) class = class->next
;
1330 pClassEntry
->wNext
= 0;
1333 pClassEntry
->hInst
= class->hInstance
;
1334 pClassEntry
->wNext
++;
1335 GlobalGetAtomNameA( class->atomName
, pClassEntry
->szClassName
,
1336 sizeof(pClassEntry
->szClassName
) );