Implementation of ChildWindowFromPointEx functions.
[wine/multimedia.git] / windows / class.c
blob362ce25101ea6ed9ef648fbd522151daeb00478e
1 /*
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.
15 #include <stdlib.h>
16 #include <string.h>
17 #include "class.h"
18 #include "heap.h"
19 #include "win.h"
20 #include "dce.h"
21 #include "ldt.h"
22 #include "toolhelp.h"
23 #include "winproc.h"
24 #include "debug.h"
25 #include "winerror.h"
28 static CLASS *firstClass = NULL;
31 /***********************************************************************
32 * CLASS_DumpClass
34 * Dump the content of a class structure to stderr.
36 void CLASS_DumpClass( CLASS *ptr )
38 char className[MAX_CLASSNAME+1];
39 int i;
41 if (ptr->magic != CLASS_MAGIC)
43 DUMP("%p is not a class\n", ptr );
44 return;
47 GlobalGetAtomName32A( ptr->atomName, className, sizeof(className) );
49 DUMP( "Class %p:\n", ptr );
50 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
51 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
52 "clsExtra=%d winExtra=%d #windows=%d\n",
53 ptr->next, ptr->atomName, className, ptr->style,
54 (UINT32)ptr->winproc, ptr->hInstance, (UINT32)ptr->dce,
55 ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
56 ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
57 if (ptr->cbClsExtra)
59 DUMP( "extra bytes:" );
60 for (i = 0; i < ptr->cbClsExtra; i++)
61 DUMP( " %02x", *((BYTE *)ptr->wExtra+i) );
62 DUMP( "\n" );
64 DUMP( "\n" );
68 /***********************************************************************
69 * CLASS_WalkClasses
71 * Walk the class list and print each class on stderr.
73 void CLASS_WalkClasses(void)
75 CLASS *ptr;
76 char className[MAX_CLASSNAME+1];
78 DUMP( " Class Name Style WndProc\n" );
79 for (ptr = firstClass; ptr; ptr = ptr->next)
81 GlobalGetAtomName32A( ptr->atomName, className, sizeof(className) );
82 DUMP( "%08x %-20.20s %08x %08x\n", (UINT32)ptr, className,
83 ptr->style, (UINT32)ptr->winproc );
85 DUMP( "\n" );
89 /***********************************************************************
90 * CLASS_GetMenuNameA
92 * Get the menu name as a ASCII string.
94 static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
96 if (!classPtr->menuNameA && classPtr->menuNameW)
98 /* We need to copy the Unicode string */
99 classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
101 return classPtr->menuNameA;
105 /***********************************************************************
106 * CLASS_GetMenuNameW
108 * Get the menu name as a Unicode string.
110 static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
112 if (!classPtr->menuNameW && classPtr->menuNameA)
114 if (!HIWORD(classPtr->menuNameA))
115 return (LPWSTR)classPtr->menuNameA;
116 /* Now we need to copy the ASCII string */
117 classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
118 classPtr->menuNameA );
120 return classPtr->menuNameW;
124 /***********************************************************************
125 * CLASS_SetMenuNameA
127 * Set the menu name in a class structure by copying the string.
129 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
131 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
132 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
133 classPtr->menuNameA = SEGPTR_STRDUP( name );
134 classPtr->menuNameW = 0;
138 /***********************************************************************
139 * CLASS_SetMenuNameW
141 * Set the menu name in a class structure by copying the string.
143 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
145 if (!HIWORD(name))
147 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
148 return;
150 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
151 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
152 if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
153 (lstrlen32W(name)+1)*sizeof(WCHAR) )))
154 lstrcpy32W( classPtr->menuNameW, name );
155 classPtr->menuNameA = 0;
159 /***********************************************************************
160 * CLASS_GetClassNameA
162 * Get the clas name as a ASCII string.
164 static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
166 if (!classPtr->classNameA && classPtr->classNameW)
168 /* We need to copy the Unicode string */
169 classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
171 return classPtr->classNameA;
175 /***********************************************************************
176 * CLASS_GetClassNameW
178 * Get the class name as a Unicode string.
180 static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
182 if (!classPtr->classNameW && classPtr->classNameA)
184 if (!HIWORD(classPtr->classNameA))
185 return (LPWSTR)classPtr->classNameA;
186 /* Now we need to copy the ASCII string */
187 classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
188 classPtr->classNameA );
190 return classPtr->classNameW;
193 /***********************************************************************
194 * CLASS_SetClassNameA
196 * Set the class name in a class structure by copying the string.
198 static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
200 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
201 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
202 classPtr->classNameA = SEGPTR_STRDUP( name );
203 classPtr->classNameW = 0;
207 /***********************************************************************
208 * CLASS_SetClassNameW
210 * Set the class name in a class structure by copying the string.
212 static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
214 if (!HIWORD(name))
216 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
217 return;
219 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
220 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
221 if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
222 (lstrlen32W(name)+1)*sizeof(WCHAR) )))
223 lstrcpy32W( classPtr->classNameW, name );
224 classPtr->classNameA = 0;
228 /***********************************************************************
229 * CLASS_FreeClass
231 * Free a class structure.
233 static BOOL32 CLASS_FreeClass( CLASS *classPtr )
235 CLASS **ppClass;
236 TRACE(class,"%p \n", classPtr);
238 /* Check if we can remove this class */
240 if (classPtr->cWindows > 0) return FALSE;
242 /* Remove the class from the linked list */
244 for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
245 if (*ppClass == classPtr) break;
246 if (!*ppClass)
248 ERR( class, "Class list corrupted\n" );
249 return FALSE;
251 *ppClass = classPtr->next;
253 /* Delete the class */
255 if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
256 if (classPtr->hbrBackground) DeleteObject32( classPtr->hbrBackground );
257 GlobalDeleteAtom( classPtr->atomName );
258 CLASS_SetMenuNameA( classPtr, NULL );
259 CLASS_SetClassNameA( classPtr, NULL );
260 WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
261 HeapFree( SystemHeap, 0, classPtr );
262 return TRUE;
266 /***********************************************************************
267 * CLASS_FreeModuleClasses
269 void CLASS_FreeModuleClasses( HMODULE16 hModule )
271 CLASS *ptr, *next;
273 TRACE(class,"0x%08x \n", hModule);
275 for (ptr = firstClass; ptr; ptr = next)
277 next = ptr->next;
278 if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
283 /***********************************************************************
284 * CLASS_FindClassByAtom
286 * Return a pointer to the class.
287 * hinstance has been normalized by the caller.
289 * NOTES
290 * 980805 a local class will be found now if registred with hInst=0
291 * and looed up with a hInst!=0. msmoney does it (jsch)
293 CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE32 hinstance )
294 { CLASS * class, *tclass=0;
296 TRACE(class,"0x%08x 0x%08x\n", atom, hinstance);
298 /* First search task-specific classes */
300 for (class = firstClass; (class); class = class->next)
302 if (class->style & CS_GLOBALCLASS) continue;
303 if (class->atomName == atom)
305 if (hinstance==class->hInstance || hinstance==0xffff )
307 TRACE(class,"-- found local %p\n", class);
308 return class;
310 if (class->hInstance==0) tclass = class;
314 /* Then search global classes */
316 for (class = firstClass; (class); class = class->next)
318 if (!(class->style & CS_GLOBALCLASS)) continue;
319 if (class->atomName == atom)
321 TRACE(class,"-- found global %p\n", class);
322 return class;
326 /* Then check if there was a local class with hInst=0*/
327 if ( tclass )
329 WARN(class,"-- found local Class registred with hInst=0\n");
330 return tclass;
333 TRACE(class,"-- not found\n");
334 return 0;
338 /***********************************************************************
339 * CLASS_RegisterClass
341 * The real RegisterClass() functionality.
343 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE32 hInstance,
344 DWORD style, INT32 classExtra,
345 INT32 winExtra, WNDPROC16 wndProc,
346 WINDOWPROCTYPE wndProcType )
348 CLASS *classPtr;
350 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
351 atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
353 /* Check if a class with this name already exists */
354 classPtr = CLASS_FindClassByAtom( atom, hInstance );
355 if (classPtr)
357 /* Class can be created only if it is local and */
358 /* if the class with the same name is global. */
360 if (style & CS_GLOBALCLASS) return NULL;
361 if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
364 /* Fix the extra bytes value */
366 if (classExtra < 0) classExtra = 0;
367 else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
368 WARN(class, "Class extra bytes %d is > 40\n", classExtra);
369 if (winExtra < 0) winExtra = 0;
370 else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
371 WARN(class, "Win extra bytes %d is > 40\n", winExtra );
373 /* Create the class */
375 classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
376 classExtra - sizeof(classPtr->wExtra) );
377 if (!classPtr) return NULL;
378 classPtr->next = firstClass;
379 classPtr->magic = CLASS_MAGIC;
380 classPtr->cWindows = 0;
381 classPtr->style = style;
382 classPtr->winproc = (HWINDOWPROC)0;
383 classPtr->cbWndExtra = winExtra;
384 classPtr->cbClsExtra = classExtra;
385 classPtr->hInstance = hInstance;
386 classPtr->atomName = atom;
387 classPtr->menuNameA = 0;
388 classPtr->menuNameW = 0;
389 classPtr->classNameA = 0;
390 classPtr->classNameW = 0;
391 classPtr->dce = (style & CS_CLASSDC) ?
392 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
394 WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
396 /* Other values must be set by caller */
398 if (classExtra) memset( classPtr->wExtra, 0, classExtra );
399 firstClass = classPtr;
400 return classPtr;
404 /***********************************************************************
405 * RegisterClass16 (USER.57)
407 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
409 ATOM atom;
410 CLASS *classPtr;
411 HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
413 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
414 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
415 wc->cbClsExtra, wc->cbWndExtra,
416 wc->lpfnWndProc, WIN_PROC_16 )))
418 GlobalDeleteAtom( atom );
419 return 0;
422 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
423 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
424 atom, (DWORD)wc->lpfnWndProc, hInstance,
425 wc->hbrBackground, wc->style, wc->cbClsExtra,
426 wc->cbWndExtra, classPtr,
427 HIWORD(wc->lpszClassName) ?
428 (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
430 classPtr->hIcon = wc->hIcon;
431 classPtr->hIconSm = 0;
432 classPtr->hCursor = wc->hCursor;
433 classPtr->hbrBackground = wc->hbrBackground;
435 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
436 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
437 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
438 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
440 return atom;
444 /***********************************************************************
445 * RegisterClass32A (USER32.427)
446 * RETURNS
447 * >0: Unique identifier
448 * 0: Failure
450 ATOM WINAPI RegisterClass32A(
451 const WNDCLASS32A* wc /* Address of structure with class data */
453 ATOM atom;
454 CLASS *classPtr;
456 if (!(atom = GlobalAddAtom32A( wc->lpszClassName )))
458 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
459 return FALSE;
461 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
462 wc->cbClsExtra, wc->cbWndExtra,
463 (WNDPROC16)wc->lpfnWndProc,
464 WIN_PROC_32A )))
465 { GlobalDeleteAtom( atom );
466 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
467 return FALSE;
470 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
471 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
472 wc->hbrBackground, wc->style, wc->cbClsExtra,
473 wc->cbWndExtra, classPtr,
474 HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
476 classPtr->hIcon = (HICON16)wc->hIcon;
477 classPtr->hIconSm = 0;
478 classPtr->hCursor = (HCURSOR16)wc->hCursor;
479 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
481 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
482 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
483 return atom;
487 /***********************************************************************
488 * RegisterClass32W (USER32.430)
490 ATOM WINAPI RegisterClass32W( const WNDCLASS32W* wc )
492 ATOM atom;
493 CLASS *classPtr;
495 if (!(atom = GlobalAddAtom32W( wc->lpszClassName )))
497 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
498 return FALSE;
500 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
501 wc->cbClsExtra, wc->cbWndExtra,
502 (WNDPROC16)wc->lpfnWndProc,
503 WIN_PROC_32W )))
505 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
506 GlobalDeleteAtom( atom );
507 return 0;
510 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
511 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
512 wc->hbrBackground, wc->style, wc->cbClsExtra,
513 wc->cbWndExtra, classPtr );
515 classPtr->hIcon = (HICON16)wc->hIcon;
516 classPtr->hIconSm = 0;
517 classPtr->hCursor = (HCURSOR16)wc->hCursor;
518 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
520 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
521 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
522 return atom;
526 /***********************************************************************
527 * RegisterClassEx16 (USER.397)
529 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
531 ATOM atom;
532 CLASS *classPtr;
533 HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
535 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
536 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
537 wc->cbClsExtra, wc->cbWndExtra,
538 wc->lpfnWndProc, WIN_PROC_16 )))
540 GlobalDeleteAtom( atom );
541 return 0;
544 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
545 atom, (DWORD)wc->lpfnWndProc, hInstance,
546 wc->hbrBackground, wc->style, wc->cbClsExtra,
547 wc->cbWndExtra, classPtr );
549 classPtr->hIcon = wc->hIcon;
550 classPtr->hIconSm = wc->hIconSm;
551 classPtr->hCursor = wc->hCursor;
552 classPtr->hbrBackground = wc->hbrBackground;
554 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
555 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
556 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
557 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
558 return atom;
562 /***********************************************************************
563 * RegisterClassEx32A (USER32.428)
565 ATOM WINAPI RegisterClassEx32A( const WNDCLASSEX32A* wc )
567 ATOM atom;
568 CLASS *classPtr;
570 if (!(atom = GlobalAddAtom32A( wc->lpszClassName )))
572 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
573 return FALSE;
575 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
576 wc->cbClsExtra, wc->cbWndExtra,
577 (WNDPROC16)wc->lpfnWndProc,
578 WIN_PROC_32A )))
580 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
581 GlobalDeleteAtom( atom );
582 return FALSE;
585 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
586 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
587 wc->hbrBackground, wc->style, wc->cbClsExtra,
588 wc->cbWndExtra, classPtr );
590 classPtr->hIcon = (HICON16)wc->hIcon;
591 classPtr->hIconSm = (HICON16)wc->hIconSm;
592 classPtr->hCursor = (HCURSOR16)wc->hCursor;
593 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
594 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
595 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
596 return atom;
600 /***********************************************************************
601 * RegisterClassEx32W (USER32.429)
603 ATOM WINAPI RegisterClassEx32W( const WNDCLASSEX32W* wc )
605 ATOM atom;
606 CLASS *classPtr;
608 if (!(atom = GlobalAddAtom32W( wc->lpszClassName )))
610 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
611 return 0;
613 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
614 wc->cbClsExtra, wc->cbWndExtra,
615 (WNDPROC16)wc->lpfnWndProc,
616 WIN_PROC_32W )))
618 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
619 GlobalDeleteAtom( atom );
620 return 0;
623 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
624 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
625 wc->hbrBackground, wc->style, wc->cbClsExtra,
626 wc->cbWndExtra, classPtr );
628 classPtr->hIcon = (HICON16)wc->hIcon;
629 classPtr->hIconSm = (HICON16)wc->hIconSm;
630 classPtr->hCursor = (HCURSOR16)wc->hCursor;
631 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
632 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
633 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
634 return atom;
638 /***********************************************************************
639 * UnregisterClass16 (USER.403)
641 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
643 CLASS *classPtr;
644 ATOM atom;
646 hInstance = GetExePtr( hInstance );
647 if (!(atom = GlobalFindAtom16( className ))) return FALSE;
648 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
649 (classPtr->hInstance != hInstance)) return FALSE;
650 return CLASS_FreeClass( classPtr );
654 /***********************************************************************
655 * UnregisterClass32A (USER32.563)
658 BOOL32 WINAPI UnregisterClass32A( LPCSTR className, HINSTANCE32 hInstance )
659 { CLASS *classPtr;
660 ATOM atom;
661 BOOL32 ret;
663 TRACE(class,"%s %x\n",className, hInstance);
665 if (!(atom = GlobalFindAtom32A( className )))
667 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
668 return FALSE;
670 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
671 (classPtr->hInstance != hInstance))
673 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
674 return FALSE;
676 if (!(ret = CLASS_FreeClass( classPtr )))
677 SetLastError(ERROR_CLASS_HAS_WINDOWS);
678 return ret;
681 /***********************************************************************
682 * UnregisterClass32W (USER32.564)
684 BOOL32 WINAPI UnregisterClass32W( LPCWSTR className, HINSTANCE32 hInstance )
685 { CLASS *classPtr;
686 ATOM atom;
687 BOOL32 ret;
689 TRACE(class,"%s %x\n",debugstr_w(className), hInstance);
691 if (!(atom = GlobalFindAtom32W( className )))
693 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
694 return FALSE;
696 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
697 (classPtr->hInstance != hInstance))
699 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
700 return FALSE;
702 if (!(ret = CLASS_FreeClass( classPtr )))
703 SetLastError(ERROR_CLASS_HAS_WINDOWS);
704 return ret;
707 /***********************************************************************
708 * GetClassWord16 (USER.129)
710 WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
712 return GetClassWord32( hwnd, offset );
716 /***********************************************************************
717 * GetClassWord32 (USER32.219)
719 WORD WINAPI GetClassWord32( HWND32 hwnd, INT32 offset )
721 WND * wndPtr;
723 TRACE(class,"%x %x\n",hwnd, offset);
725 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
726 if (offset >= 0)
728 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
729 return GET_WORD(((char *)wndPtr->class->wExtra) + offset);
731 else switch(offset)
733 case GCW_HBRBACKGROUND: return wndPtr->class->hbrBackground;
734 case GCW_HCURSOR: return wndPtr->class->hCursor;
735 case GCW_HICON: return wndPtr->class->hIcon;
736 case GCW_HICONSM: return wndPtr->class->hIconSm;
737 case GCW_ATOM: return wndPtr->class->atomName;
738 case GCW_STYLE:
739 case GCW_CBWNDEXTRA:
740 case GCW_CBCLSEXTRA:
741 case GCW_HMODULE:
742 return (WORD)GetClassLong32A( hwnd, offset );
745 WARN(class, "Invalid offset %d\n", offset);
746 return 0;
750 /***********************************************************************
751 * GetClassLong16 (USER.131)
753 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
755 WND *wndPtr;
756 LONG ret;
758 TRACE(class,"%x %x\n",hwnd, offset);
760 switch( offset )
762 case GCL_WNDPROC:
763 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
764 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
765 case GCL_MENUNAME:
766 ret = GetClassLong32A( hwnd, offset );
767 return (LONG)SEGPTR_GET( (void *)ret );
768 default:
769 return GetClassLong32A( hwnd, offset );
774 /***********************************************************************
775 * GetClassLong32A (USER32.215)
777 LONG WINAPI GetClassLong32A( HWND32 hwnd, INT32 offset )
779 WND * wndPtr;
781 TRACE(class,"%x %x\n",hwnd, offset);
783 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
784 if (offset >= 0)
786 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
787 return GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
789 switch(offset)
791 case GCL_STYLE: return (LONG)wndPtr->class->style;
792 case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
793 case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
794 case GCL_HMODULE: return (LONG)wndPtr->class->hInstance;
795 case GCL_WNDPROC:
796 return (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
797 case GCL_MENUNAME:
798 return (LONG)CLASS_GetMenuNameA( wndPtr->class );
799 case GCL_HBRBACKGROUND:
800 case GCL_HCURSOR:
801 case GCL_HICON:
802 case GCL_HICONSM:
803 return GetClassWord32( hwnd, offset );
805 WARN(class, "Invalid offset %d\n", offset);
806 return 0;
810 /***********************************************************************
811 * GetClassLong32W (USER32.216)
813 LONG WINAPI GetClassLong32W( HWND32 hwnd, INT32 offset )
815 WND * wndPtr;
817 TRACE(class,"%x %x\n",hwnd, offset);
819 switch(offset)
821 case GCL_WNDPROC:
822 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
823 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
824 case GCL_MENUNAME:
825 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
826 return (LONG)CLASS_GetMenuNameW( wndPtr->class );
827 default:
828 return GetClassLong32A( hwnd, offset );
833 /***********************************************************************
834 * SetClassWord16 (USER.130)
836 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
838 return SetClassWord32( hwnd, offset, newval );
842 /***********************************************************************
843 * SetClassWord32 (USER32.469)
845 WORD WINAPI SetClassWord32( HWND32 hwnd, INT32 offset, WORD newval )
847 WND * wndPtr;
848 WORD retval = 0;
849 void *ptr;
851 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
853 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
854 if (offset >= 0)
856 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
857 ptr = ((char *)wndPtr->class->wExtra) + offset;
858 else
860 WARN( class, "Invalid offset %d\n", offset );
861 return 0;
864 else switch(offset)
866 case GCW_STYLE:
867 case GCW_CBWNDEXTRA:
868 case GCW_CBCLSEXTRA:
869 case GCW_HMODULE:
870 return (WORD)SetClassLong32A( hwnd, offset, (LONG)newval );
871 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
872 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
873 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
874 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
875 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
876 default:
877 WARN( class, "Invalid offset %d\n", offset);
878 return 0;
880 retval = GET_WORD(ptr);
881 PUT_WORD( ptr, newval );
883 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
884 need to be updated as well. Problem is that we can't tell whether the atom is
885 using wide or narrow characters. For now, we'll just NULL out the className
886 fields, and emit a FIXME. */
887 if (offset == GCW_ATOM)
889 CLASS_SetClassNameA( wndPtr->class, NULL );
890 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
892 return retval;
896 /***********************************************************************
897 * SetClassLong16 (USER.132)
899 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
901 WND *wndPtr;
902 LONG retval;
904 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
906 switch(offset)
908 case GCL_WNDPROC:
909 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
910 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
911 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
912 WIN_PROC_16, WIN_PROC_CLASS );
913 return retval;
914 case GCL_MENUNAME:
915 return SetClassLong32A( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
916 default:
917 return SetClassLong32A( hwnd, offset, newval );
922 /***********************************************************************
923 * SetClassLong32A (USER32.467)
925 LONG WINAPI SetClassLong32A( HWND32 hwnd, INT32 offset, LONG newval )
927 WND * wndPtr;
928 LONG retval = 0;
929 void *ptr;
931 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
933 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
934 if (offset >= 0)
936 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
937 ptr = ((char *)wndPtr->class->wExtra) + offset;
938 else
940 WARN( class, "Invalid offset %d\n", offset );
941 return 0;
944 else switch(offset)
946 case GCL_MENUNAME:
947 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
948 return 0; /* Old value is now meaningless anyway */
949 case GCL_WNDPROC:
950 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
951 WIN_PROC_32A );
952 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
953 WIN_PROC_32A, WIN_PROC_CLASS );
954 return retval;
955 case GCL_HBRBACKGROUND:
956 case GCL_HCURSOR:
957 case GCL_HICON:
958 case GCL_HICONSM:
959 return SetClassWord32( hwnd, offset, (WORD)newval );
960 case GCL_STYLE: ptr = &wndPtr->class->style; break;
961 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
962 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
963 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
964 default:
965 WARN( class, "Invalid offset %d\n", offset );
966 return 0;
968 retval = GET_DWORD(ptr);
969 PUT_DWORD( ptr, newval );
970 return retval;
974 /***********************************************************************
975 * SetClassLong32W (USER32.468)
977 LONG WINAPI SetClassLong32W( HWND32 hwnd, INT32 offset, LONG newval )
979 WND *wndPtr;
980 LONG retval;
982 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
984 switch(offset)
986 case GCL_WNDPROC:
987 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
988 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
989 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
990 WIN_PROC_32W, WIN_PROC_CLASS );
991 return retval;
992 case GCL_MENUNAME:
993 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
994 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
995 return 0; /* Old value is now meaningless anyway */
996 default:
997 return SetClassLong32A( hwnd, offset, newval );
1002 /***********************************************************************
1003 * GetClassName16 (USER.58)
1005 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1007 WND *wndPtr;
1008 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1009 return GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1013 /***********************************************************************
1014 * GetClassName32A (USER32.217)
1016 INT32 WINAPI GetClassName32A( HWND32 hwnd, LPSTR buffer, INT32 count )
1017 { INT32 ret;
1018 WND *wndPtr;
1020 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1021 ret = GlobalGetAtomName32A( wndPtr->class->atomName, buffer, count );
1023 TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1024 return ret;
1028 /***********************************************************************
1029 * GetClassName32W (USER32.218)
1031 INT32 WINAPI GetClassName32W( HWND32 hwnd, LPWSTR buffer, INT32 count )
1032 { INT32 ret;
1033 WND *wndPtr;
1035 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1036 ret = GlobalGetAtomName32W( wndPtr->class->atomName, buffer, count );
1038 TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1040 return ret;
1044 /***********************************************************************
1045 * GetClassInfo16 (USER.404)
1047 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1048 WNDCLASS16 *wc )
1050 ATOM atom;
1051 CLASS *classPtr;
1053 TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1055 hInstance = GetExePtr( hInstance );
1056 if (!(atom = GlobalFindAtom16( name )) ||
1057 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1058 return FALSE;
1059 if ((hInstance != classPtr->hInstance) &&
1060 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1061 return FALSE;
1062 wc->style = (UINT16)classPtr->style;
1063 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1064 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1065 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1066 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1067 wc->hIcon = classPtr->hIcon;
1068 wc->hCursor = classPtr->hCursor;
1069 wc->hbrBackground = classPtr->hbrBackground;
1070 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1071 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1072 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1073 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1074 return TRUE;
1078 /***********************************************************************
1079 * GetClassInfo32A (USER32.211)
1081 BOOL32 WINAPI GetClassInfo32A( HINSTANCE32 hInstance, LPCSTR name,
1082 WNDCLASS32A *wc )
1084 ATOM atom;
1085 CLASS *classPtr;
1087 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1089 /* workaround: if hInstance=NULL you expect to get the system classes
1090 but this classes (as example from comctl32.dll SysListView) won't be
1091 registred with hInstance=NULL in WINE because of the late loading
1092 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1094 if (!(atom=GlobalFindAtom32A(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1095 return FALSE;
1097 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1099 if (hInstance) return FALSE;
1100 else
1101 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1104 wc->style = classPtr->style;
1105 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1106 WIN_PROC_32A );
1107 wc->cbClsExtra = classPtr->cbClsExtra;
1108 wc->cbWndExtra = classPtr->cbWndExtra;
1109 wc->hInstance = classPtr->hInstance;
1110 wc->hIcon = (HICON32)classPtr->hIcon;
1111 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1112 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1113 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1114 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1115 return TRUE;
1119 /***********************************************************************
1120 * GetClassInfo32W (USER32.214)
1122 BOOL32 WINAPI GetClassInfo32W( HINSTANCE32 hInstance, LPCWSTR name,
1123 WNDCLASS32W *wc )
1125 ATOM atom;
1126 CLASS *classPtr;
1128 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1130 if (!(atom = GlobalFindAtom32W( name )) ||
1131 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1132 (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1133 return FALSE;
1135 wc->style = classPtr->style;
1136 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1137 WIN_PROC_32W );
1138 wc->cbClsExtra = classPtr->cbClsExtra;
1139 wc->cbWndExtra = classPtr->cbWndExtra;
1140 wc->hInstance = classPtr->hInstance;
1141 wc->hIcon = (HICON32)classPtr->hIcon;
1142 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1143 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1144 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1145 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1146 return TRUE;
1150 /***********************************************************************
1151 * GetClassInfoEx16 (USER.398)
1153 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1154 * same in Win16 as in Win32. --AJ
1156 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1157 WNDCLASSEX16 *wc )
1159 ATOM atom;
1160 CLASS *classPtr;
1162 TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1164 hInstance = GetExePtr( hInstance );
1165 if (!(atom = GlobalFindAtom16( name )) ||
1166 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1167 (hInstance != classPtr->hInstance)) return FALSE;
1168 wc->style = classPtr->style;
1169 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1170 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1171 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1172 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1173 wc->hIcon = classPtr->hIcon;
1174 wc->hIconSm = classPtr->hIconSm;
1175 wc->hCursor = classPtr->hCursor;
1176 wc->hbrBackground = classPtr->hbrBackground;
1177 wc->lpszClassName = (SEGPTR)0;
1178 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1179 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1180 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1181 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1182 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1183 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1184 return TRUE;
1188 /***********************************************************************
1189 * GetClassInfoEx32A (USER32.212)
1191 BOOL32 WINAPI GetClassInfoEx32A( HINSTANCE32 hInstance, LPCSTR name,
1192 WNDCLASSEX32A *wc )
1194 ATOM atom;
1195 CLASS *classPtr;
1197 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1199 if (!(atom = GlobalFindAtom32A( name )) ||
1200 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1201 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1202 wc->style = classPtr->style;
1203 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1204 WIN_PROC_32A );
1205 wc->cbClsExtra = classPtr->cbClsExtra;
1206 wc->cbWndExtra = classPtr->cbWndExtra;
1207 wc->hInstance = classPtr->hInstance;
1208 wc->hIcon = (HICON32)classPtr->hIcon;
1209 wc->hIconSm = (HICON32)classPtr->hIconSm;
1210 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1211 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1212 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1213 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1214 return TRUE;
1218 /***********************************************************************
1219 * GetClassInfoEx32W (USER32.213)
1221 BOOL32 WINAPI GetClassInfoEx32W( HINSTANCE32 hInstance, LPCWSTR name,
1222 WNDCLASSEX32W *wc )
1224 ATOM atom;
1225 CLASS *classPtr;
1227 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1229 if (!(atom = GlobalFindAtom32W( name )) ||
1230 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1231 (hInstance != classPtr->hInstance)) return FALSE;
1232 wc->style = classPtr->style;
1233 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1234 WIN_PROC_32W );
1235 wc->cbClsExtra = classPtr->cbClsExtra;
1236 wc->cbWndExtra = classPtr->cbWndExtra;
1237 wc->hInstance = classPtr->hInstance;
1238 wc->hIcon = (HICON32)classPtr->hIcon;
1239 wc->hIconSm = (HICON32)classPtr->hIconSm;
1240 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1241 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1242 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1243 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1244 return TRUE;
1248 /***********************************************************************
1249 * ClassFirst (TOOLHELP.69)
1251 BOOL16 WINAPI ClassFirst( CLASSENTRY *pClassEntry )
1253 TRACE(class,"%p\n",pClassEntry);
1254 pClassEntry->wNext = 1;
1255 return ClassNext( pClassEntry );
1259 /***********************************************************************
1260 * ClassNext (TOOLHELP.70)
1262 BOOL16 WINAPI ClassNext( CLASSENTRY *pClassEntry )
1264 int i;
1265 CLASS *class = firstClass;
1267 TRACE(class,"%p\n",pClassEntry);
1269 if (!pClassEntry->wNext) return FALSE;
1270 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1271 if (!class)
1273 pClassEntry->wNext = 0;
1274 return FALSE;
1276 pClassEntry->hInst = class->hInstance;
1277 pClassEntry->wNext++;
1278 GlobalGetAtomName32A( class->atomName, pClassEntry->szClassName,
1279 sizeof(pClassEntry->szClassName) );
1280 return TRUE;