Handling for listviewstyles, view mode buttons in filedialogs
[wine/multimedia.git] / windows / class.c
bloba69d7a77bfc01f75efeebbae990877393b83ff09
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 "atom.h"
22 #include "ldt.h"
23 #include "toolhelp.h"
24 #include "winproc.h"
25 #include "debug.h"
26 #include "winerror.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->classNameA = 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 GCL_HBRBACKGROUND:
801 case GCL_HCURSOR:
802 case GCL_HICON:
803 case GCL_HICONSM:
804 return GetClassWord32( hwnd, offset );
806 WARN(class, "Invalid offset %d\n", offset);
807 return 0;
811 /***********************************************************************
812 * GetClassLong32W (USER32.216)
814 LONG WINAPI GetClassLong32W( HWND32 hwnd, INT32 offset )
816 WND * wndPtr;
818 TRACE(class,"%x %x\n",hwnd, offset);
820 switch(offset)
822 case GCL_WNDPROC:
823 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
824 return (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
825 case GCL_MENUNAME:
826 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
827 return (LONG)CLASS_GetMenuNameW( wndPtr->class );
828 default:
829 return GetClassLong32A( hwnd, offset );
834 /***********************************************************************
835 * SetClassWord16 (USER.130)
837 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
839 return SetClassWord32( hwnd, offset, newval );
843 /***********************************************************************
844 * SetClassWord32 (USER32.469)
846 WORD WINAPI SetClassWord32( HWND32 hwnd, INT32 offset, WORD newval )
848 WND * wndPtr;
849 WORD retval = 0;
850 void *ptr;
852 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
854 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
855 if (offset >= 0)
857 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
858 ptr = ((char *)wndPtr->class->wExtra) + offset;
859 else
861 WARN( class, "Invalid offset %d\n", offset );
862 return 0;
865 else switch(offset)
867 case GCW_STYLE:
868 case GCW_CBWNDEXTRA:
869 case GCW_CBCLSEXTRA:
870 case GCW_HMODULE:
871 return (WORD)SetClassLong32A( hwnd, offset, (LONG)newval );
872 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
873 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
874 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
875 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
876 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
877 default:
878 WARN( class, "Invalid offset %d\n", offset);
879 return 0;
881 retval = GET_WORD(ptr);
882 PUT_WORD( ptr, newval );
884 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
885 need to be updated as well. Problem is that we can't tell whether the atom is
886 using wide or narrow characters. For now, we'll just NULL out the className
887 fields, and emit a FIXME. */
888 if (offset == GCW_ATOM)
890 CLASS_SetClassNameA( wndPtr->class, NULL );
891 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
893 return retval;
897 /***********************************************************************
898 * SetClassLong16 (USER.132)
900 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
902 WND *wndPtr;
903 LONG retval;
905 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
907 switch(offset)
909 case GCL_WNDPROC:
910 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
911 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
912 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
913 WIN_PROC_16, WIN_PROC_CLASS );
914 return retval;
915 case GCL_MENUNAME:
916 return SetClassLong32A( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
917 default:
918 return SetClassLong32A( hwnd, offset, newval );
923 /***********************************************************************
924 * SetClassLong32A (USER32.467)
926 LONG WINAPI SetClassLong32A( HWND32 hwnd, INT32 offset, LONG newval )
928 WND * wndPtr;
929 LONG retval = 0;
930 void *ptr;
932 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
934 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
935 if (offset >= 0)
937 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
938 ptr = ((char *)wndPtr->class->wExtra) + offset;
939 else
941 WARN( class, "Invalid offset %d\n", offset );
942 return 0;
945 else switch(offset)
947 case GCL_MENUNAME:
948 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
949 return 0; /* Old value is now meaningless anyway */
950 case GCL_WNDPROC:
951 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
952 WIN_PROC_32A );
953 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
954 WIN_PROC_32A, WIN_PROC_CLASS );
955 return retval;
956 case GCL_HBRBACKGROUND:
957 case GCL_HCURSOR:
958 case GCL_HICON:
959 case GCL_HICONSM:
960 return SetClassWord32( hwnd, offset, (WORD)newval );
961 case GCL_STYLE: ptr = &wndPtr->class->style; break;
962 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
963 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
964 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
965 default:
966 WARN( class, "Invalid offset %d\n", offset );
967 return 0;
969 retval = GET_DWORD(ptr);
970 PUT_DWORD( ptr, newval );
971 return retval;
975 /***********************************************************************
976 * SetClassLong32W (USER32.468)
978 LONG WINAPI SetClassLong32W( HWND32 hwnd, INT32 offset, LONG newval )
980 WND *wndPtr;
981 LONG retval;
983 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
985 switch(offset)
987 case GCL_WNDPROC:
988 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
989 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
990 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
991 WIN_PROC_32W, WIN_PROC_CLASS );
992 return retval;
993 case GCL_MENUNAME:
994 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
995 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
996 return 0; /* Old value is now meaningless anyway */
997 default:
998 return SetClassLong32A( hwnd, offset, newval );
1003 /***********************************************************************
1004 * GetClassName16 (USER.58)
1006 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1008 WND *wndPtr;
1009 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1010 return GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1014 /***********************************************************************
1015 * GetClassName32A (USER32.217)
1017 INT32 WINAPI GetClassName32A( HWND32 hwnd, LPSTR buffer, INT32 count )
1018 { INT32 ret;
1019 WND *wndPtr;
1021 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1022 ret = GlobalGetAtomName32A( wndPtr->class->atomName, buffer, count );
1024 TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1025 return ret;
1029 /***********************************************************************
1030 * GetClassName32W (USER32.218)
1032 INT32 WINAPI GetClassName32W( HWND32 hwnd, LPWSTR buffer, INT32 count )
1033 { INT32 ret;
1034 WND *wndPtr;
1036 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1037 ret = GlobalGetAtomName32W( wndPtr->class->atomName, buffer, count );
1039 TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1041 return ret;
1045 /***********************************************************************
1046 * GetClassInfo16 (USER.404)
1048 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1049 WNDCLASS16 *wc )
1051 ATOM atom;
1052 CLASS *classPtr;
1054 TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1056 hInstance = GetExePtr( hInstance );
1057 if (!(atom = GlobalFindAtom16( name )) ||
1058 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1059 return FALSE;
1060 if ((hInstance != classPtr->hInstance) &&
1061 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1062 return FALSE;
1063 wc->style = (UINT16)classPtr->style;
1064 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1065 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1066 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1067 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1068 wc->hIcon = classPtr->hIcon;
1069 wc->hCursor = classPtr->hCursor;
1070 wc->hbrBackground = classPtr->hbrBackground;
1071 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1072 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1073 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1074 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1075 return TRUE;
1079 /***********************************************************************
1080 * GetClassInfo32A (USER32.211)
1082 BOOL32 WINAPI GetClassInfo32A( HINSTANCE32 hInstance, LPCSTR name,
1083 WNDCLASS32A *wc )
1085 ATOM atom;
1086 CLASS *classPtr;
1088 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1090 /* workaround: if hInstance=NULL you expect to get the system classes
1091 but this classes (as example from comctl32.dll SysListView) won't be
1092 registred with hInstance=NULL in WINE because of the late loading
1093 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1095 if (!(atom=GlobalFindAtom32A(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1096 return FALSE;
1098 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1100 if (hInstance) return FALSE;
1101 else
1102 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1105 wc->style = classPtr->style;
1106 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1107 WIN_PROC_32A );
1108 wc->cbClsExtra = classPtr->cbClsExtra;
1109 wc->cbWndExtra = classPtr->cbWndExtra;
1110 wc->hInstance = classPtr->hInstance;
1111 wc->hIcon = (HICON32)classPtr->hIcon;
1112 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1113 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1114 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1115 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1116 return TRUE;
1120 /***********************************************************************
1121 * GetClassInfo32W (USER32.214)
1123 BOOL32 WINAPI GetClassInfo32W( HINSTANCE32 hInstance, LPCWSTR name,
1124 WNDCLASS32W *wc )
1126 ATOM atom;
1127 CLASS *classPtr;
1129 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1131 if (!(atom = GlobalFindAtom32W( name )) ||
1132 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1133 (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1134 return FALSE;
1136 wc->style = classPtr->style;
1137 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1138 WIN_PROC_32W );
1139 wc->cbClsExtra = classPtr->cbClsExtra;
1140 wc->cbWndExtra = classPtr->cbWndExtra;
1141 wc->hInstance = classPtr->hInstance;
1142 wc->hIcon = (HICON32)classPtr->hIcon;
1143 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1144 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1145 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1146 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1147 return TRUE;
1151 /***********************************************************************
1152 * GetClassInfoEx16 (USER.398)
1154 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1155 * same in Win16 as in Win32. --AJ
1157 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1158 WNDCLASSEX16 *wc )
1160 ATOM atom;
1161 CLASS *classPtr;
1163 TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1165 hInstance = GetExePtr( hInstance );
1166 if (!(atom = GlobalFindAtom16( name )) ||
1167 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1168 (hInstance != classPtr->hInstance)) return FALSE;
1169 wc->style = classPtr->style;
1170 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1171 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1172 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1173 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1174 wc->hIcon = classPtr->hIcon;
1175 wc->hIconSm = classPtr->hIconSm;
1176 wc->hCursor = classPtr->hCursor;
1177 wc->hbrBackground = classPtr->hbrBackground;
1178 wc->lpszClassName = (SEGPTR)0;
1179 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1180 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1181 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1182 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1183 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1184 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1185 return TRUE;
1189 /***********************************************************************
1190 * GetClassInfoEx32A (USER32.212)
1192 BOOL32 WINAPI GetClassInfoEx32A( HINSTANCE32 hInstance, LPCSTR name,
1193 WNDCLASSEX32A *wc )
1195 ATOM atom;
1196 CLASS *classPtr;
1198 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1200 if (!(atom = GlobalFindAtom32A( name )) ||
1201 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1202 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1203 wc->style = classPtr->style;
1204 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1205 WIN_PROC_32A );
1206 wc->cbClsExtra = classPtr->cbClsExtra;
1207 wc->cbWndExtra = classPtr->cbWndExtra;
1208 wc->hInstance = classPtr->hInstance;
1209 wc->hIcon = (HICON32)classPtr->hIcon;
1210 wc->hIconSm = (HICON32)classPtr->hIconSm;
1211 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1212 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1213 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1214 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1215 return TRUE;
1219 /***********************************************************************
1220 * GetClassInfoEx32W (USER32.213)
1222 BOOL32 WINAPI GetClassInfoEx32W( HINSTANCE32 hInstance, LPCWSTR name,
1223 WNDCLASSEX32W *wc )
1225 ATOM atom;
1226 CLASS *classPtr;
1228 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1230 if (!(atom = GlobalFindAtom32W( name )) ||
1231 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1232 (hInstance != classPtr->hInstance)) return FALSE;
1233 wc->style = classPtr->style;
1234 wc->lpfnWndProc = (WNDPROC32)WINPROC_GetProc( classPtr->winproc,
1235 WIN_PROC_32W );
1236 wc->cbClsExtra = classPtr->cbClsExtra;
1237 wc->cbWndExtra = classPtr->cbWndExtra;
1238 wc->hInstance = classPtr->hInstance;
1239 wc->hIcon = (HICON32)classPtr->hIcon;
1240 wc->hIconSm = (HICON32)classPtr->hIconSm;
1241 wc->hCursor = (HCURSOR32)classPtr->hCursor;
1242 wc->hbrBackground = (HBRUSH32)classPtr->hbrBackground;
1243 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1244 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1245 return TRUE;
1249 /***********************************************************************
1250 * ClassFirst (TOOLHELP.69)
1252 BOOL16 WINAPI ClassFirst( CLASSENTRY *pClassEntry )
1254 TRACE(class,"%p\n",pClassEntry);
1255 pClassEntry->wNext = 1;
1256 return ClassNext( pClassEntry );
1260 /***********************************************************************
1261 * ClassNext (TOOLHELP.70)
1263 BOOL16 WINAPI ClassNext( CLASSENTRY *pClassEntry )
1265 int i;
1266 CLASS *class = firstClass;
1268 TRACE(class,"%p\n",pClassEntry);
1270 if (!pClassEntry->wNext) return FALSE;
1271 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1272 if (!class)
1274 pClassEntry->wNext = 0;
1275 return FALSE;
1277 pClassEntry->hInst = class->hInstance;
1278 pClassEntry->wNext++;
1279 GlobalGetAtomName32A( class->atomName, pClassEntry->szClassName,
1280 sizeof(pClassEntry->szClassName) );
1281 return TRUE;