Authors: Adrian Thurston <adriant@corel.ca>, Zygo Blaxell <zblaxell@corel.ca>
[wine/multimedia.git] / windows / class.c
blobddd8efe2c4546f67a9b8dc62d1553098839a39e1
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"
26 #include "wine/winuser16.h"
29 static CLASS *firstClass = NULL;
32 /***********************************************************************
33 * CLASS_DumpClass
35 * Dump the content of a class structure to stderr.
37 void CLASS_DumpClass( CLASS *ptr )
39 char className[MAX_CLASSNAME+1];
40 int i;
42 if (ptr->magic != CLASS_MAGIC)
44 DUMP("%p is not a class\n", ptr );
45 return;
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 );
58 if (ptr->cbClsExtra)
60 DUMP( "extra bytes:" );
61 for (i = 0; i < ptr->cbClsExtra; i++)
62 DUMP( " %02x", *((BYTE *)ptr->wExtra+i) );
63 DUMP( "\n" );
65 DUMP( "\n" );
69 /***********************************************************************
70 * CLASS_WalkClasses
72 * Walk the class list and print each class on stderr.
74 void CLASS_WalkClasses(void)
76 CLASS *ptr;
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 );
86 DUMP( "\n" );
90 /***********************************************************************
91 * CLASS_GetMenuNameA
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 /***********************************************************************
107 * CLASS_GetMenuNameW
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 /***********************************************************************
126 * CLASS_SetMenuNameA
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 /***********************************************************************
140 * CLASS_SetMenuNameW
142 * Set the menu name in a class structure by copying the string.
144 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
146 if (!HIWORD(name))
148 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
149 return;
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 )
215 if (!HIWORD(name))
217 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
218 return;
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 /***********************************************************************
230 * CLASS_FreeClass
232 * Free a class structure.
234 static BOOL32 CLASS_FreeClass( CLASS *classPtr )
236 CLASS **ppClass;
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;
247 if (!*ppClass)
249 ERR( class, "Class list corrupted\n" );
250 return FALSE;
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 );
263 return TRUE;
267 /***********************************************************************
268 * CLASS_FreeModuleClasses
270 void CLASS_FreeModuleClasses( HMODULE16 hModule )
272 CLASS *ptr, *next;
274 TRACE(class,"0x%08x \n", hModule);
276 for (ptr = firstClass; ptr; ptr = next)
278 next = 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.
290 * NOTES
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);
309 return 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);
323 return class;
327 /* Then check if there was a local class with hInst=0*/
328 if ( tclass )
330 WARN(class,"-- found local Class registred with hInst=0\n");
331 return tclass;
334 TRACE(class,"-- not found\n");
335 return 0;
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 )
349 CLASS *classPtr;
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 );
356 if (classPtr)
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;
401 return classPtr;
405 /***********************************************************************
406 * RegisterClass16 (USER.57)
408 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
410 ATOM atom;
411 CLASS *classPtr;
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 );
420 return 0;
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 );
441 return atom;
445 /***********************************************************************
446 * RegisterClass32A (USER32.427)
447 * RETURNS
448 * >0: Unique identifier
449 * 0: Failure
451 ATOM WINAPI RegisterClass32A(
452 const WNDCLASS32A* wc /* Address of structure with class data */
454 ATOM atom;
455 CLASS *classPtr;
457 if (!(atom = GlobalAddAtom32A( wc->lpszClassName )))
459 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
460 return FALSE;
462 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
463 wc->cbClsExtra, wc->cbWndExtra,
464 (WNDPROC16)wc->lpfnWndProc,
465 WIN_PROC_32A )))
466 { GlobalDeleteAtom( atom );
467 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
468 return FALSE;
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 );
484 return atom;
488 /***********************************************************************
489 * RegisterClass32W (USER32.430)
491 ATOM WINAPI RegisterClass32W( const WNDCLASS32W* wc )
493 ATOM atom;
494 CLASS *classPtr;
496 if (!(atom = GlobalAddAtom32W( wc->lpszClassName )))
498 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
499 return FALSE;
501 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
502 wc->cbClsExtra, wc->cbWndExtra,
503 (WNDPROC16)wc->lpfnWndProc,
504 WIN_PROC_32W )))
506 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
507 GlobalDeleteAtom( atom );
508 return 0;
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 );
523 return atom;
527 /***********************************************************************
528 * RegisterClassEx16 (USER.397)
530 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
532 ATOM atom;
533 CLASS *classPtr;
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 );
542 return 0;
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 );
559 return atom;
563 /***********************************************************************
564 * RegisterClassEx32A (USER32.428)
566 ATOM WINAPI RegisterClassEx32A( const WNDCLASSEX32A* wc )
568 ATOM atom;
569 CLASS *classPtr;
571 if (!(atom = GlobalAddAtom32A( wc->lpszClassName )))
573 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
574 return FALSE;
576 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
577 wc->cbClsExtra, wc->cbWndExtra,
578 (WNDPROC16)wc->lpfnWndProc,
579 WIN_PROC_32A )))
581 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
582 GlobalDeleteAtom( atom );
583 return FALSE;
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 );
597 return atom;
601 /***********************************************************************
602 * RegisterClassEx32W (USER32.429)
604 ATOM WINAPI RegisterClassEx32W( const WNDCLASSEX32W* wc )
606 ATOM atom;
607 CLASS *classPtr;
609 if (!(atom = GlobalAddAtom32W( wc->lpszClassName )))
611 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
612 return 0;
614 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
615 wc->cbClsExtra, wc->cbWndExtra,
616 (WNDPROC16)wc->lpfnWndProc,
617 WIN_PROC_32W )))
619 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
620 GlobalDeleteAtom( atom );
621 return 0;
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 );
635 return atom;
639 /***********************************************************************
640 * UnregisterClass16 (USER.403)
642 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
644 CLASS *classPtr;
645 ATOM atom;
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 )
660 { CLASS *classPtr;
661 ATOM atom;
662 BOOL32 ret;
664 TRACE(class,"%s %x\n",className, hInstance);
666 if (!(atom = GlobalFindAtom32A( className )))
668 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
669 return FALSE;
671 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
672 (classPtr->hInstance != hInstance))
674 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
675 return FALSE;
677 if (!(ret = CLASS_FreeClass( classPtr )))
678 SetLastError(ERROR_CLASS_HAS_WINDOWS);
679 return ret;
682 /***********************************************************************
683 * UnregisterClass32W (USER32.564)
685 BOOL32 WINAPI UnregisterClass32W( LPCWSTR className, HINSTANCE32 hInstance )
686 { CLASS *classPtr;
687 ATOM atom;
688 BOOL32 ret;
690 TRACE(class,"%s %x\n",debugstr_w(className), hInstance);
692 if (!(atom = GlobalFindAtom32W( className )))
694 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
695 return FALSE;
697 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
698 (classPtr->hInstance != hInstance))
700 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
701 return FALSE;
703 if (!(ret = CLASS_FreeClass( classPtr )))
704 SetLastError(ERROR_CLASS_HAS_WINDOWS);
705 return ret;
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 )
722 WND * wndPtr;
724 TRACE(class,"%x %x\n",hwnd, offset);
726 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
727 if (offset >= 0)
729 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
730 return GET_WORD(((char *)wndPtr->class->wExtra) + offset);
732 else switch(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;
739 case GCW_STYLE:
740 case GCW_CBWNDEXTRA:
741 case GCW_CBCLSEXTRA:
742 case GCW_HMODULE:
743 return (WORD)GetClassLong32A( hwnd, offset );
746 WARN(class, "Invalid offset %d\n", offset);
747 return 0;
751 /***********************************************************************
752 * GetClassLong16 (USER.131)
754 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
756 WND *wndPtr;
757 LONG ret;
759 TRACE(class,"%x %x\n",hwnd, offset);
761 switch( offset )
763 case GCL_WNDPROC:
764 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
765 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
766 case GCL_MENUNAME:
767 ret = GetClassLong32A( hwnd, offset );
768 return (LONG)SEGPTR_GET( (void *)ret );
769 default:
770 return GetClassLong32A( hwnd, offset );
775 /***********************************************************************
776 * GetClassLong32A (USER32.215)
778 LONG WINAPI GetClassLong32A( HWND32 hwnd, INT32 offset )
780 WND * wndPtr;
782 TRACE(class,"%x %x\n",hwnd, offset);
784 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
785 if (offset >= 0)
787 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
788 return GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
790 switch(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;
796 case GCL_WNDPROC:
797 return (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
798 case GCL_MENUNAME:
799 return (LONG)CLASS_GetMenuNameA( wndPtr->class );
800 case GCW_ATOM:
801 case GCL_HBRBACKGROUND:
802 case GCL_HCURSOR:
803 case GCL_HICON:
804 case GCL_HICONSM:
805 return GetClassWord32( hwnd, offset );
807 WARN(class, "Invalid offset %d\n", offset);
808 return 0;
812 /***********************************************************************
813 * GetClassLong32W (USER32.216)
815 LONG WINAPI GetClassLong32W( HWND32 hwnd, INT32 offset )
817 WND * wndPtr;
819 TRACE(class,"%x %x\n",hwnd, offset);
821 switch(offset)
823 case GCL_WNDPROC:
824 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
825 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
826 case GCL_MENUNAME:
827 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
828 return (LONG)CLASS_GetMenuNameW( wndPtr->class );
829 default:
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 )
849 WND * wndPtr;
850 WORD retval = 0;
851 void *ptr;
853 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
855 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
856 if (offset >= 0)
858 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
859 ptr = ((char *)wndPtr->class->wExtra) + offset;
860 else
862 WARN( class, "Invalid offset %d\n", offset );
863 return 0;
866 else switch(offset)
868 case GCW_STYLE:
869 case GCW_CBWNDEXTRA:
870 case GCW_CBCLSEXTRA:
871 case GCW_HMODULE:
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;
878 default:
879 WARN( class, "Invalid offset %d\n", offset);
880 return 0;
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");
894 return retval;
898 /***********************************************************************
899 * SetClassLong16 (USER.132)
901 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
903 WND *wndPtr;
904 LONG retval;
906 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
908 switch(offset)
910 case GCL_WNDPROC:
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 );
915 return retval;
916 case GCL_MENUNAME:
917 return SetClassLong32A( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
918 default:
919 return SetClassLong32A( hwnd, offset, newval );
924 /***********************************************************************
925 * SetClassLong32A (USER32.467)
927 LONG WINAPI SetClassLong32A( HWND32 hwnd, INT32 offset, LONG newval )
929 WND * wndPtr;
930 LONG retval = 0;
931 void *ptr;
933 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
935 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
936 if (offset >= 0)
938 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
939 ptr = ((char *)wndPtr->class->wExtra) + offset;
940 else
942 WARN( class, "Invalid offset %d\n", offset );
943 return 0;
946 else switch(offset)
948 case GCL_MENUNAME:
949 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
950 return 0; /* Old value is now meaningless anyway */
951 case GCL_WNDPROC:
952 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
953 WIN_PROC_32A );
954 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
955 WIN_PROC_32A, WIN_PROC_CLASS );
956 return retval;
957 case GCL_HBRBACKGROUND:
958 case GCL_HCURSOR:
959 case GCL_HICON:
960 case GCL_HICONSM:
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;
966 default:
967 WARN( class, "Invalid offset %d\n", offset );
968 return 0;
970 retval = GET_DWORD(ptr);
971 PUT_DWORD( ptr, newval );
972 return retval;
976 /***********************************************************************
977 * SetClassLong32W (USER32.468)
979 LONG WINAPI SetClassLong32W( HWND32 hwnd, INT32 offset, LONG newval )
981 WND *wndPtr;
982 LONG retval;
984 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
986 switch(offset)
988 case GCL_WNDPROC:
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 );
993 return retval;
994 case GCL_MENUNAME:
995 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
996 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
997 return 0; /* Old value is now meaningless anyway */
998 default:
999 return SetClassLong32A( hwnd, offset, newval );
1004 /***********************************************************************
1005 * GetClassName16 (USER.58)
1007 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1009 WND *wndPtr;
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 )
1019 { INT32 ret;
1020 WND *wndPtr;
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);
1026 return ret;
1030 /***********************************************************************
1031 * GetClassName32W (USER32.218)
1033 INT32 WINAPI GetClassName32W( HWND32 hwnd, LPWSTR buffer, INT32 count )
1034 { INT32 ret;
1035 WND *wndPtr;
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);
1042 return ret;
1046 /***********************************************************************
1047 * GetClassInfo16 (USER.404)
1049 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1050 WNDCLASS16 *wc )
1052 ATOM atom;
1053 CLASS *classPtr;
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 )))
1060 return FALSE;
1061 if ((hInstance != classPtr->hInstance) &&
1062 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1063 return FALSE;
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 );
1078 return TRUE;
1082 /***********************************************************************
1083 * GetClassInfo32A (USER32.211)
1085 BOOL32 WINAPI GetClassInfo32A( HINSTANCE32 hInstance, LPCSTR name,
1086 WNDCLASS32A *wc )
1088 ATOM atom;
1089 CLASS *classPtr;
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)))
1099 return FALSE;
1101 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1103 if (hInstance) return FALSE;
1104 else
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,
1110 WIN_PROC_32A );
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 );
1119 return TRUE;
1123 /***********************************************************************
1124 * GetClassInfo32W (USER32.214)
1126 BOOL32 WINAPI GetClassInfo32W( HINSTANCE32 hInstance, LPCWSTR name,
1127 WNDCLASS32W *wc )
1129 ATOM atom;
1130 CLASS *classPtr;
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)))
1137 return FALSE;
1139 wc->style = classPtr->style;
1140 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1141 WIN_PROC_32W );
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 );
1150 return TRUE;
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,
1161 WNDCLASSEX16 *wc )
1163 ATOM atom;
1164 CLASS *classPtr;
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 );
1188 return TRUE;
1192 /***********************************************************************
1193 * GetClassInfoEx32A (USER32.212)
1195 BOOL32 WINAPI GetClassInfoEx32A( HINSTANCE32 hInstance, LPCSTR name,
1196 WNDCLASSEX32A *wc )
1198 ATOM atom;
1199 CLASS *classPtr;
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,
1208 WIN_PROC_32A );
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 );
1218 return TRUE;
1222 /***********************************************************************
1223 * GetClassInfoEx32W (USER32.213)
1225 BOOL32 WINAPI GetClassInfoEx32W( HINSTANCE32 hInstance, LPCWSTR name,
1226 WNDCLASSEX32W *wc )
1228 ATOM atom;
1229 CLASS *classPtr;
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,
1238 WIN_PROC_32W );
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 );;
1248 return TRUE;
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 )
1268 int i;
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;
1275 if (!class)
1277 pClassEntry->wNext = 0;
1278 return FALSE;
1280 pClassEntry->hInst = class->hInstance;
1281 pClassEntry->wNext++;
1282 GlobalGetAtomName32A( class->atomName, pClassEntry->szClassName,
1283 sizeof(pClassEntry->szClassName) );
1284 return TRUE;