Release 990226.
[wine/gsoc-2012-control.git] / windows / class.c
blobed39c794f3a41a3ad726b550c5e63dbef1551a5f
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 "wine/winbase16.h"
18 #include "class.h"
19 #include "heap.h"
20 #include "win.h"
21 #include "dce.h"
22 #include "ldt.h"
23 #include "toolhelp.h"
24 #include "winproc.h"
25 #include "debug.h"
26 #include "winerror.h"
27 #include "wine/winuser16.h"
30 static CLASS *firstClass = NULL;
33 /***********************************************************************
34 * CLASS_DumpClass
36 * Dump the content of a class structure to stderr.
38 void CLASS_DumpClass( CLASS *ptr )
40 char className[MAX_CLASSNAME+1];
41 int i;
43 if (ptr->magic != CLASS_MAGIC)
45 DUMP("%p is not a class\n", ptr );
46 return;
49 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
51 DUMP( "Class %p:\n", ptr );
52 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
53 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
54 "clsExtra=%d winExtra=%d #windows=%d\n",
55 ptr->next, ptr->atomName, className, ptr->style,
56 (UINT)ptr->winproc, ptr->hInstance, (UINT)ptr->dce,
57 ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
58 ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
59 if (ptr->cbClsExtra)
61 DUMP( "extra bytes:" );
62 for (i = 0; i < ptr->cbClsExtra; i++)
63 DUMP( " %02x", *((BYTE *)ptr->wExtra+i) );
64 DUMP( "\n" );
66 DUMP( "\n" );
70 /***********************************************************************
71 * CLASS_WalkClasses
73 * Walk the class list and print each class on stderr.
75 void CLASS_WalkClasses(void)
77 CLASS *ptr;
78 char className[MAX_CLASSNAME+1];
80 DUMP( " Class Name Style WndProc\n" );
81 for (ptr = firstClass; ptr; ptr = ptr->next)
83 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
84 DUMP( "%08x %-20.20s %08x %08x\n", (UINT)ptr, className,
85 ptr->style, (UINT)ptr->winproc );
87 DUMP( "\n" );
91 /***********************************************************************
92 * CLASS_GetMenuNameA
94 * Get the menu name as a ASCII string.
96 static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
98 if (!classPtr->menuNameA && classPtr->menuNameW)
100 /* We need to copy the Unicode string */
101 classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
103 return classPtr->menuNameA;
107 /***********************************************************************
108 * CLASS_GetMenuNameW
110 * Get the menu name as a Unicode string.
112 static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
114 if (!classPtr->menuNameW && classPtr->menuNameA)
116 if (!HIWORD(classPtr->menuNameA))
117 return (LPWSTR)classPtr->menuNameA;
118 /* Now we need to copy the ASCII string */
119 classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
120 classPtr->menuNameA );
122 return classPtr->menuNameW;
126 /***********************************************************************
127 * CLASS_SetMenuNameA
129 * Set the menu name in a class structure by copying the string.
131 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
133 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
134 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
135 classPtr->menuNameA = SEGPTR_STRDUP( name );
136 classPtr->menuNameW = 0;
140 /***********************************************************************
141 * CLASS_SetMenuNameW
143 * Set the menu name in a class structure by copying the string.
145 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
147 if (!HIWORD(name))
149 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
150 return;
152 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
153 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
154 if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
155 (lstrlenW(name)+1)*sizeof(WCHAR) )))
156 lstrcpyW( classPtr->menuNameW, name );
157 classPtr->menuNameA = 0;
161 /***********************************************************************
162 * CLASS_GetClassNameA
164 * Get the clas name as a ASCII string.
166 static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
168 if (!classPtr->classNameA && classPtr->classNameW)
170 /* We need to copy the Unicode string */
171 classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
173 return classPtr->classNameA;
177 /***********************************************************************
178 * CLASS_GetClassNameW
180 * Get the class name as a Unicode string.
182 static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
184 if (!classPtr->classNameW && classPtr->classNameA)
186 if (!HIWORD(classPtr->classNameA))
187 return (LPWSTR)classPtr->classNameA;
188 /* Now we need to copy the ASCII string */
189 classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
190 classPtr->classNameA );
192 return classPtr->classNameW;
195 /***********************************************************************
196 * CLASS_SetClassNameA
198 * Set the class name in a class structure by copying the string.
200 static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
202 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
203 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
204 classPtr->classNameA = SEGPTR_STRDUP( name );
205 classPtr->classNameW = 0;
209 /***********************************************************************
210 * CLASS_SetClassNameW
212 * Set the class name in a class structure by copying the string.
214 static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
216 if (!HIWORD(name))
218 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
219 return;
221 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
222 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
223 if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
224 (lstrlenW(name)+1)*sizeof(WCHAR) )))
225 lstrcpyW( classPtr->classNameW, name );
226 classPtr->classNameA = 0;
230 /***********************************************************************
231 * CLASS_FreeClass
233 * Free a class structure.
235 static BOOL CLASS_FreeClass( CLASS *classPtr )
237 CLASS **ppClass;
238 TRACE(class,"%p \n", classPtr);
240 /* Check if we can remove this class */
242 if (classPtr->cWindows > 0) return FALSE;
244 /* Remove the class from the linked list */
246 for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
247 if (*ppClass == classPtr) break;
248 if (!*ppClass)
250 ERR( class, "Class list corrupted\n" );
251 return FALSE;
253 *ppClass = classPtr->next;
255 /* Delete the class */
257 if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
258 if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
259 GlobalDeleteAtom( classPtr->atomName );
260 CLASS_SetMenuNameA( classPtr, NULL );
261 CLASS_SetClassNameA( classPtr, NULL );
262 WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
263 HeapFree( SystemHeap, 0, classPtr );
264 return TRUE;
268 /***********************************************************************
269 * CLASS_FreeModuleClasses
271 void CLASS_FreeModuleClasses( HMODULE16 hModule )
273 CLASS *ptr, *next;
275 TRACE(class,"0x%08x \n", hModule);
277 for (ptr = firstClass; ptr; ptr = next)
279 next = ptr->next;
280 if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
285 /***********************************************************************
286 * CLASS_FindClassByAtom
288 * Return a pointer to the class.
289 * hinstance has been normalized by the caller.
291 * NOTES
292 * 980805 a local class will be found now if registred with hInst=0
293 * and looed up with a hInst!=0. msmoney does it (jsch)
295 CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
296 { CLASS * class, *tclass=0;
298 TRACE(class,"0x%08x 0x%08x\n", atom, hinstance);
300 /* First search task-specific classes */
302 for (class = firstClass; (class); class = class->next)
304 if (class->style & CS_GLOBALCLASS) continue;
305 if (class->atomName == atom)
307 if (hinstance==class->hInstance || hinstance==0xffff )
309 TRACE(class,"-- found local %p\n", class);
310 return class;
312 if (class->hInstance==0) tclass = class;
316 /* Then search global classes */
318 for (class = firstClass; (class); class = class->next)
320 if (!(class->style & CS_GLOBALCLASS)) continue;
321 if (class->atomName == atom)
323 TRACE(class,"-- found global %p\n", class);
324 return class;
328 /* Then check if there was a local class with hInst=0*/
329 if ( tclass )
331 WARN(class,"-- found local Class registred with hInst=0\n");
332 return tclass;
335 TRACE(class,"-- not found\n");
336 return 0;
340 /***********************************************************************
341 * CLASS_RegisterClass
343 * The real RegisterClass() functionality.
345 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
346 DWORD style, INT classExtra,
347 INT winExtra, WNDPROC16 wndProc,
348 WINDOWPROCTYPE wndProcType )
350 CLASS *classPtr;
352 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
353 atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
355 /* Check if a class with this name already exists */
356 classPtr = CLASS_FindClassByAtom( atom, hInstance );
357 if (classPtr)
359 /* Class can be created only if it is local and */
360 /* if the class with the same name is global. */
362 if (style & CS_GLOBALCLASS) return NULL;
363 if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
366 /* Fix the extra bytes value */
368 if (classExtra < 0) classExtra = 0;
369 else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
370 WARN(class, "Class extra bytes %d is > 40\n", classExtra);
371 if (winExtra < 0) winExtra = 0;
372 else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
373 WARN(class, "Win extra bytes %d is > 40\n", winExtra );
375 /* Create the class */
377 classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
378 classExtra - sizeof(classPtr->wExtra) );
379 if (!classPtr) return NULL;
380 classPtr->next = firstClass;
381 classPtr->magic = CLASS_MAGIC;
382 classPtr->cWindows = 0;
383 classPtr->style = style;
384 classPtr->winproc = (HWINDOWPROC)0;
385 classPtr->cbWndExtra = winExtra;
386 classPtr->cbClsExtra = classExtra;
387 classPtr->hInstance = hInstance;
388 classPtr->atomName = atom;
389 classPtr->menuNameA = 0;
390 classPtr->menuNameW = 0;
391 classPtr->classNameA = 0;
392 classPtr->classNameW = 0;
393 classPtr->dce = (style & CS_CLASSDC) ?
394 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
396 WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
398 /* Other values must be set by caller */
400 if (classExtra) memset( classPtr->wExtra, 0, classExtra );
401 firstClass = classPtr;
402 return classPtr;
406 /***********************************************************************
407 * RegisterClass16 (USER.57)
409 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
411 ATOM atom;
412 CLASS *classPtr;
413 HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
415 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
416 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
417 wc->cbClsExtra, wc->cbWndExtra,
418 wc->lpfnWndProc, WIN_PROC_16 )))
420 GlobalDeleteAtom( atom );
421 return 0;
424 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x
425 bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
426 atom, (DWORD)wc->lpfnWndProc, hInstance,
427 wc->hbrBackground, wc->style, wc->cbClsExtra,
428 wc->cbWndExtra, classPtr,
429 HIWORD(wc->lpszClassName) ?
430 (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
432 classPtr->hIcon = wc->hIcon;
433 classPtr->hIconSm = 0;
434 classPtr->hCursor = wc->hCursor;
435 classPtr->hbrBackground = wc->hbrBackground;
437 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
438 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
439 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
440 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
442 return atom;
446 /***********************************************************************
447 * RegisterClass32A (USER32.427)
448 * RETURNS
449 * >0: Unique identifier
450 * 0: Failure
452 ATOM WINAPI RegisterClassA(
453 const WNDCLASSA* wc /* Address of structure with class data */
455 ATOM atom;
456 CLASS *classPtr;
458 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
460 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
461 return FALSE;
463 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
464 wc->cbClsExtra, wc->cbWndExtra,
465 (WNDPROC16)wc->lpfnWndProc,
466 WIN_PROC_32A )))
467 { GlobalDeleteAtom( atom );
468 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
469 return FALSE;
472 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
473 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
474 wc->hbrBackground, wc->style, wc->cbClsExtra,
475 wc->cbWndExtra, classPtr,
476 HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
478 classPtr->hIcon = (HICON16)wc->hIcon;
479 classPtr->hIconSm = 0;
480 classPtr->hCursor = (HCURSOR16)wc->hCursor;
481 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
483 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
484 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
485 return atom;
489 /***********************************************************************
490 * RegisterClass32W (USER32.430)
492 ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
494 ATOM atom;
495 CLASS *classPtr;
497 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
499 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
500 return FALSE;
502 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
503 wc->cbClsExtra, wc->cbWndExtra,
504 (WNDPROC16)wc->lpfnWndProc,
505 WIN_PROC_32W )))
507 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
508 GlobalDeleteAtom( atom );
509 return 0;
512 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
513 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
514 wc->hbrBackground, wc->style, wc->cbClsExtra,
515 wc->cbWndExtra, classPtr );
517 classPtr->hIcon = (HICON16)wc->hIcon;
518 classPtr->hIconSm = 0;
519 classPtr->hCursor = (HCURSOR16)wc->hCursor;
520 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
522 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
523 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
524 return atom;
528 /***********************************************************************
529 * RegisterClassEx16 (USER.397)
531 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
533 ATOM atom;
534 CLASS *classPtr;
535 HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
537 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
538 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
539 wc->cbClsExtra, wc->cbWndExtra,
540 wc->lpfnWndProc, WIN_PROC_16 )))
542 GlobalDeleteAtom( atom );
543 return 0;
546 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
547 atom, (DWORD)wc->lpfnWndProc, hInstance,
548 wc->hbrBackground, wc->style, wc->cbClsExtra,
549 wc->cbWndExtra, classPtr );
551 classPtr->hIcon = wc->hIcon;
552 classPtr->hIconSm = wc->hIconSm;
553 classPtr->hCursor = wc->hCursor;
554 classPtr->hbrBackground = wc->hbrBackground;
556 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
557 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
558 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
559 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
560 return atom;
564 /***********************************************************************
565 * RegisterClassEx32A (USER32.428)
567 ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
569 ATOM atom;
570 CLASS *classPtr;
572 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
574 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
575 return FALSE;
577 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
578 wc->cbClsExtra, wc->cbWndExtra,
579 (WNDPROC16)wc->lpfnWndProc,
580 WIN_PROC_32A )))
582 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
583 GlobalDeleteAtom( atom );
584 return FALSE;
587 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
588 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
589 wc->hbrBackground, wc->style, wc->cbClsExtra,
590 wc->cbWndExtra, classPtr );
592 classPtr->hIcon = (HICON16)wc->hIcon;
593 classPtr->hIconSm = (HICON16)wc->hIconSm;
594 classPtr->hCursor = (HCURSOR16)wc->hCursor;
595 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
596 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
597 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
598 return atom;
602 /***********************************************************************
603 * RegisterClassEx32W (USER32.429)
605 ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
607 ATOM atom;
608 CLASS *classPtr;
610 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
612 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
613 return 0;
615 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
616 wc->cbClsExtra, wc->cbWndExtra,
617 (WNDPROC16)wc->lpfnWndProc,
618 WIN_PROC_32W )))
620 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
621 GlobalDeleteAtom( atom );
622 return 0;
625 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
626 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
627 wc->hbrBackground, wc->style, wc->cbClsExtra,
628 wc->cbWndExtra, classPtr );
630 classPtr->hIcon = (HICON16)wc->hIcon;
631 classPtr->hIconSm = (HICON16)wc->hIconSm;
632 classPtr->hCursor = (HCURSOR16)wc->hCursor;
633 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
634 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
635 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
636 return atom;
640 /***********************************************************************
641 * UnregisterClass16 (USER.403)
643 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
645 CLASS *classPtr;
646 ATOM atom;
648 hInstance = GetExePtr( hInstance );
649 if (!(atom = GlobalFindAtom16( className ))) return FALSE;
650 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
651 (classPtr->hInstance != hInstance)) return FALSE;
652 return CLASS_FreeClass( classPtr );
656 /***********************************************************************
657 * UnregisterClass32A (USER32.563)
660 BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
661 { CLASS *classPtr;
662 ATOM atom;
663 BOOL ret;
665 TRACE(class,"%s %x\n",className, hInstance);
667 if (!(atom = GlobalFindAtomA( className )))
669 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
670 return FALSE;
672 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
673 (classPtr->hInstance != hInstance))
675 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
676 return FALSE;
678 if (!(ret = CLASS_FreeClass( classPtr )))
679 SetLastError(ERROR_CLASS_HAS_WINDOWS);
680 return ret;
683 /***********************************************************************
684 * UnregisterClass32W (USER32.564)
686 BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
687 { CLASS *classPtr;
688 ATOM atom;
689 BOOL ret;
691 TRACE(class,"%s %x\n",debugstr_w(className), hInstance);
693 if (!(atom = GlobalFindAtomW( className )))
695 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
696 return FALSE;
698 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
699 (classPtr->hInstance != hInstance))
701 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
702 return FALSE;
704 if (!(ret = CLASS_FreeClass( classPtr )))
705 SetLastError(ERROR_CLASS_HAS_WINDOWS);
706 return ret;
709 /***********************************************************************
710 * GetClassWord16 (USER.129)
712 WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
714 return GetClassWord( hwnd, offset );
718 /***********************************************************************
719 * GetClassWord32 (USER32.219)
721 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
723 WND * wndPtr;
725 TRACE(class,"%x %x\n",hwnd, offset);
727 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
728 if (offset >= 0)
730 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
731 return GET_WORD(((char *)wndPtr->class->wExtra) + offset);
733 else switch(offset)
735 case GCW_HBRBACKGROUND: return wndPtr->class->hbrBackground;
736 case GCW_HCURSOR: return wndPtr->class->hCursor;
737 case GCW_HICON: return wndPtr->class->hIcon;
738 case GCW_HICONSM: return wndPtr->class->hIconSm;
739 case GCW_ATOM: return wndPtr->class->atomName;
740 case GCW_STYLE:
741 case GCW_CBWNDEXTRA:
742 case GCW_CBCLSEXTRA:
743 case GCW_HMODULE:
744 return (WORD)GetClassLongA( hwnd, offset );
747 WARN(class, "Invalid offset %d\n", offset);
748 return 0;
752 /***********************************************************************
753 * GetClassLong16 (USER.131)
755 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
757 WND *wndPtr;
758 LONG ret;
760 TRACE(class,"%x %x\n",hwnd, offset);
762 switch( offset )
764 case GCL_WNDPROC:
765 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
766 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
767 case GCL_MENUNAME:
768 ret = GetClassLongA( hwnd, offset );
769 return (LONG)SEGPTR_GET( (void *)ret );
770 default:
771 return GetClassLongA( hwnd, offset );
776 /***********************************************************************
777 * GetClassLong32A (USER32.215)
779 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
781 WND * wndPtr;
783 TRACE(class,"%x %x\n",hwnd, offset);
785 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
786 if (offset >= 0)
788 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
789 return GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
791 switch(offset)
793 case GCL_STYLE: return (LONG)wndPtr->class->style;
794 case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
795 case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
796 case GCL_HMODULE: return (LONG)wndPtr->class->hInstance;
797 case GCL_WNDPROC:
798 return (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
799 case GCL_MENUNAME:
800 return (LONG)CLASS_GetMenuNameA( wndPtr->class );
801 case GCW_ATOM:
802 case GCL_HBRBACKGROUND:
803 case GCL_HCURSOR:
804 case GCL_HICON:
805 case GCL_HICONSM:
806 return GetClassWord( hwnd, offset );
808 WARN(class, "Invalid offset %d\n", offset);
809 return 0;
813 /***********************************************************************
814 * GetClassLong32W (USER32.216)
816 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
818 WND * wndPtr;
820 TRACE(class,"%x %x\n",hwnd, offset);
822 switch(offset)
824 case GCL_WNDPROC:
825 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
826 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
827 case GCL_MENUNAME:
828 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
829 return (LONG)CLASS_GetMenuNameW( wndPtr->class );
830 default:
831 return GetClassLongA( hwnd, offset );
836 /***********************************************************************
837 * SetClassWord16 (USER.130)
839 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
841 return SetClassWord( hwnd, offset, newval );
845 /***********************************************************************
846 * SetClassWord32 (USER32.469)
848 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
850 WND * wndPtr;
851 WORD retval = 0;
852 void *ptr;
854 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
856 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
857 if (offset >= 0)
859 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
860 ptr = ((char *)wndPtr->class->wExtra) + offset;
861 else
863 WARN( class, "Invalid offset %d\n", offset );
864 return 0;
867 else switch(offset)
869 case GCW_STYLE:
870 case GCW_CBWNDEXTRA:
871 case GCW_CBCLSEXTRA:
872 case GCW_HMODULE:
873 return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
874 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
875 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
876 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
877 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
878 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
879 default:
880 WARN( class, "Invalid offset %d\n", offset);
881 return 0;
883 retval = GET_WORD(ptr);
884 PUT_WORD( ptr, newval );
886 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
887 need to be updated as well. Problem is that we can't tell whether the atom is
888 using wide or narrow characters. For now, we'll just NULL out the className
889 fields, and emit a FIXME. */
890 if (offset == GCW_ATOM)
892 CLASS_SetClassNameA( wndPtr->class, NULL );
893 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
895 return retval;
899 /***********************************************************************
900 * SetClassLong16 (USER.132)
902 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
904 WND *wndPtr;
905 LONG retval;
907 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
909 switch(offset)
911 case GCL_WNDPROC:
912 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
913 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
914 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
915 WIN_PROC_16, WIN_PROC_CLASS );
916 return retval;
917 case GCL_MENUNAME:
918 return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
919 default:
920 return SetClassLongA( hwnd, offset, newval );
925 /***********************************************************************
926 * SetClassLong32A (USER32.467)
928 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
930 WND * wndPtr;
931 LONG retval = 0;
932 void *ptr;
934 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
936 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
937 if (offset >= 0)
939 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
940 ptr = ((char *)wndPtr->class->wExtra) + offset;
941 else
943 WARN( class, "Invalid offset %d\n", offset );
944 return 0;
947 else switch(offset)
949 case GCL_MENUNAME:
950 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
951 return 0; /* Old value is now meaningless anyway */
952 case GCL_WNDPROC:
953 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
954 WIN_PROC_32A );
955 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
956 WIN_PROC_32A, WIN_PROC_CLASS );
957 return retval;
958 case GCL_HBRBACKGROUND:
959 case GCL_HCURSOR:
960 case GCL_HICON:
961 case GCL_HICONSM:
962 return SetClassWord( hwnd, offset, (WORD)newval );
963 case GCL_STYLE: ptr = &wndPtr->class->style; break;
964 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
965 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
966 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
967 default:
968 WARN( class, "Invalid offset %d\n", offset );
969 return 0;
971 retval = GET_DWORD(ptr);
972 PUT_DWORD( ptr, newval );
973 return retval;
977 /***********************************************************************
978 * SetClassLong32W (USER32.468)
980 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
982 WND *wndPtr;
983 LONG retval;
985 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
987 switch(offset)
989 case GCL_WNDPROC:
990 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
991 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
992 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
993 WIN_PROC_32W, WIN_PROC_CLASS );
994 return retval;
995 case GCL_MENUNAME:
996 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
997 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
998 return 0; /* Old value is now meaningless anyway */
999 default:
1000 return SetClassLongA( hwnd, offset, newval );
1005 /***********************************************************************
1006 * GetClassName16 (USER.58)
1008 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1010 WND *wndPtr;
1011 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1012 return GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1016 /***********************************************************************
1017 * GetClassName32A (USER32.217)
1019 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1020 { INT ret;
1021 WND *wndPtr;
1023 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1024 ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
1026 TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1027 return ret;
1031 /***********************************************************************
1032 * GetClassName32W (USER32.218)
1034 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1035 { INT ret;
1036 WND *wndPtr;
1038 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1039 ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
1041 TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1043 return ret;
1047 /***********************************************************************
1048 * GetClassInfo16 (USER.404)
1050 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1051 WNDCLASS16 *wc )
1053 ATOM atom;
1054 CLASS *classPtr;
1056 TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1058 hInstance = GetExePtr( hInstance );
1059 if (!(atom = GlobalFindAtom16( name )) ||
1060 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1061 return FALSE;
1062 if ((hInstance != classPtr->hInstance) &&
1063 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1064 return FALSE;
1065 wc->style = (UINT16)classPtr->style;
1066 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1067 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1068 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1069 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1070 wc->hIcon = classPtr->hIcon;
1071 wc->hCursor = classPtr->hCursor;
1072 wc->hbrBackground = classPtr->hbrBackground;
1073 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1074 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1075 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1076 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1077 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1078 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1079 return TRUE;
1083 /***********************************************************************
1084 * GetClassInfo32A (USER32.211)
1086 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1087 WNDCLASSA *wc )
1089 ATOM atom;
1090 CLASS *classPtr;
1092 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1094 /* workaround: if hInstance=NULL you expect to get the system classes
1095 but this classes (as example from comctl32.dll SysListView) won't be
1096 registred with hInstance=NULL in WINE because of the late loading
1097 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1099 if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1100 return FALSE;
1102 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1104 if (hInstance) return FALSE;
1105 else
1106 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1109 wc->style = classPtr->style;
1110 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1111 WIN_PROC_32A );
1112 wc->cbClsExtra = classPtr->cbClsExtra;
1113 wc->cbWndExtra = classPtr->cbWndExtra;
1114 wc->hInstance = classPtr->hInstance;
1115 wc->hIcon = (HICON)classPtr->hIcon;
1116 wc->hCursor = (HCURSOR)classPtr->hCursor;
1117 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1118 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1119 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1120 return TRUE;
1124 /***********************************************************************
1125 * GetClassInfo32W (USER32.214)
1127 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1128 WNDCLASSW *wc )
1130 ATOM atom;
1131 CLASS *classPtr;
1133 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1135 if (!(atom = GlobalFindAtomW( name )) ||
1136 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1137 (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1138 return FALSE;
1140 wc->style = classPtr->style;
1141 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1142 WIN_PROC_32W );
1143 wc->cbClsExtra = classPtr->cbClsExtra;
1144 wc->cbWndExtra = classPtr->cbWndExtra;
1145 wc->hInstance = classPtr->hInstance;
1146 wc->hIcon = (HICON)classPtr->hIcon;
1147 wc->hCursor = (HCURSOR)classPtr->hCursor;
1148 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1149 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1150 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1151 return TRUE;
1155 /***********************************************************************
1156 * GetClassInfoEx16 (USER.398)
1158 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1159 * same in Win16 as in Win32. --AJ
1161 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1162 WNDCLASSEX16 *wc )
1164 ATOM atom;
1165 CLASS *classPtr;
1167 TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1169 hInstance = GetExePtr( hInstance );
1170 if (!(atom = GlobalFindAtom16( name )) ||
1171 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1172 (hInstance != classPtr->hInstance)) return FALSE;
1173 wc->style = classPtr->style;
1174 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1175 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1176 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1177 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1178 wc->hIcon = classPtr->hIcon;
1179 wc->hIconSm = classPtr->hIconSm;
1180 wc->hCursor = classPtr->hCursor;
1181 wc->hbrBackground = classPtr->hbrBackground;
1182 wc->lpszClassName = (SEGPTR)0;
1183 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1184 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1185 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1186 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1187 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1188 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1189 return TRUE;
1193 /***********************************************************************
1194 * GetClassInfoEx32A (USER32.212)
1196 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1197 WNDCLASSEXA *wc )
1199 ATOM atom;
1200 CLASS *classPtr;
1202 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1204 if (!(atom = GlobalFindAtomA( name )) ||
1205 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1206 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1207 wc->style = classPtr->style;
1208 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1209 WIN_PROC_32A );
1210 wc->cbClsExtra = classPtr->cbClsExtra;
1211 wc->cbWndExtra = classPtr->cbWndExtra;
1212 wc->hInstance = classPtr->hInstance;
1213 wc->hIcon = (HICON)classPtr->hIcon;
1214 wc->hIconSm = (HICON)classPtr->hIconSm;
1215 wc->hCursor = (HCURSOR)classPtr->hCursor;
1216 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1217 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1218 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1219 return TRUE;
1223 /***********************************************************************
1224 * GetClassInfoEx32W (USER32.213)
1226 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1227 WNDCLASSEXW *wc )
1229 ATOM atom;
1230 CLASS *classPtr;
1232 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1234 if (!(atom = GlobalFindAtomW( name )) ||
1235 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1236 (hInstance != classPtr->hInstance)) return FALSE;
1237 wc->style = classPtr->style;
1238 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1239 WIN_PROC_32W );
1240 wc->cbClsExtra = classPtr->cbClsExtra;
1241 wc->cbWndExtra = classPtr->cbWndExtra;
1242 wc->hInstance = classPtr->hInstance;
1243 wc->hIcon = (HICON)classPtr->hIcon;
1244 wc->hIconSm = (HICON)classPtr->hIconSm;
1245 wc->hCursor = (HCURSOR)classPtr->hCursor;
1246 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1247 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1248 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1249 return TRUE;
1253 /***********************************************************************
1254 * ClassFirst (TOOLHELP.69)
1256 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1258 TRACE(class,"%p\n",pClassEntry);
1259 pClassEntry->wNext = 1;
1260 return ClassNext16( pClassEntry );
1264 /***********************************************************************
1265 * ClassNext (TOOLHELP.70)
1267 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1269 int i;
1270 CLASS *class = firstClass;
1272 TRACE(class,"%p\n",pClassEntry);
1274 if (!pClassEntry->wNext) return FALSE;
1275 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1276 if (!class)
1278 pClassEntry->wNext = 0;
1279 return FALSE;
1281 pClassEntry->hInst = class->hInstance;
1282 pClassEntry->wNext++;
1283 GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1284 sizeof(pClassEntry->szClassName) );
1285 return TRUE;