Added COMPOBJ.DllEntryPoint (Acrobat3 16bit needs it).
[wine.git] / windows / class.c
blobef5dc444d0594006f07e4f6585fa54f5e01f117e
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"
29 DEFAULT_DEBUG_CHANNEL(class)
32 static CLASS *firstClass = NULL;
35 /***********************************************************************
36 * CLASS_DumpClass
38 * Dump the content of a class structure to stderr.
40 void CLASS_DumpClass( CLASS *ptr )
42 char className[MAX_CLASSNAME+1];
43 int i;
45 if (ptr->magic != CLASS_MAGIC)
47 DUMP("%p is not a class\n", ptr );
48 return;
51 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
53 DUMP( "Class %p:\n", ptr );
54 DUMP( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
55 "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
56 "clsExtra=%d winExtra=%d #windows=%d\n",
57 ptr->next, ptr->atomName, className, ptr->style,
58 (UINT)ptr->winproc, ptr->hInstance, (UINT)ptr->dce,
59 ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
60 ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
61 if (ptr->cbClsExtra)
63 DUMP( "extra bytes:" );
64 for (i = 0; i < ptr->cbClsExtra; i++)
65 DUMP( " %02x", *((BYTE *)ptr->wExtra+i) );
66 DUMP( "\n" );
68 DUMP( "\n" );
72 /***********************************************************************
73 * CLASS_WalkClasses
75 * Walk the class list and print each class on stderr.
77 void CLASS_WalkClasses(void)
79 CLASS *ptr;
80 char className[MAX_CLASSNAME+1];
82 DUMP( " Class Name Style WndProc\n" );
83 for (ptr = firstClass; ptr; ptr = ptr->next)
85 GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
86 DUMP( "%08x %-20.20s %08x %08x\n", (UINT)ptr, className,
87 ptr->style, (UINT)ptr->winproc );
89 DUMP( "\n" );
93 /***********************************************************************
94 * CLASS_GetMenuNameA
96 * Get the menu name as a ASCII string.
98 static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
100 if (!classPtr->menuNameA && classPtr->menuNameW)
102 /* We need to copy the Unicode string */
103 classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
105 return classPtr->menuNameA;
109 /***********************************************************************
110 * CLASS_GetMenuNameW
112 * Get the menu name as a Unicode string.
114 static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
116 if (!classPtr->menuNameW && classPtr->menuNameA)
118 if (!HIWORD(classPtr->menuNameA))
119 return (LPWSTR)classPtr->menuNameA;
120 /* Now we need to copy the ASCII string */
121 classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
122 classPtr->menuNameA );
124 return classPtr->menuNameW;
128 /***********************************************************************
129 * CLASS_SetMenuNameA
131 * Set the menu name in a class structure by copying the string.
133 static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
135 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
136 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
137 classPtr->menuNameA = SEGPTR_STRDUP( name );
138 classPtr->menuNameW = 0;
142 /***********************************************************************
143 * CLASS_SetMenuNameW
145 * Set the menu name in a class structure by copying the string.
147 static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
149 if (!HIWORD(name))
151 CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
152 return;
154 if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
155 if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
156 if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
157 (lstrlenW(name)+1)*sizeof(WCHAR) )))
158 lstrcpyW( classPtr->menuNameW, name );
159 classPtr->menuNameA = 0;
163 /***********************************************************************
164 * CLASS_GetClassNameA
166 * Get the clas name as a ASCII string.
168 static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
170 if (!classPtr->classNameA && classPtr->classNameW)
172 /* We need to copy the Unicode string */
173 classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
175 return classPtr->classNameA;
179 /***********************************************************************
180 * CLASS_GetClassNameW
182 * Get the class name as a Unicode string.
184 static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
186 if (!classPtr->classNameW && classPtr->classNameA)
188 if (!HIWORD(classPtr->classNameA))
189 return (LPWSTR)classPtr->classNameA;
190 /* Now we need to copy the ASCII string */
191 classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
192 classPtr->classNameA );
194 return classPtr->classNameW;
197 /***********************************************************************
198 * CLASS_SetClassNameA
200 * Set the class name in a class structure by copying the string.
202 static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
204 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
205 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
206 classPtr->classNameA = SEGPTR_STRDUP( name );
207 classPtr->classNameW = 0;
211 /***********************************************************************
212 * CLASS_SetClassNameW
214 * Set the class name in a class structure by copying the string.
216 static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
218 if (!HIWORD(name))
220 CLASS_SetClassNameA( classPtr, (LPCSTR)name );
221 return;
223 if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
224 if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
225 if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
226 (lstrlenW(name)+1)*sizeof(WCHAR) )))
227 lstrcpyW( classPtr->classNameW, name );
228 classPtr->classNameA = 0;
232 /***********************************************************************
233 * CLASS_FreeClass
235 * Free a class structure.
237 static BOOL CLASS_FreeClass( CLASS *classPtr )
239 CLASS **ppClass;
240 TRACE(class,"%p \n", classPtr);
242 /* Check if we can remove this class */
244 if (classPtr->cWindows > 0) return FALSE;
246 /* Remove the class from the linked list */
248 for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
249 if (*ppClass == classPtr) break;
250 if (!*ppClass)
252 ERR( class, "Class list corrupted\n" );
253 return FALSE;
255 *ppClass = classPtr->next;
257 /* Delete the class */
259 if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
260 if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
261 GlobalDeleteAtom( classPtr->atomName );
262 CLASS_SetMenuNameA( classPtr, NULL );
263 CLASS_SetClassNameA( classPtr, NULL );
264 WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
265 HeapFree( SystemHeap, 0, classPtr );
266 return TRUE;
270 /***********************************************************************
271 * CLASS_FreeModuleClasses
273 void CLASS_FreeModuleClasses( HMODULE16 hModule )
275 CLASS *ptr, *next;
277 TRACE(class,"0x%08x \n", hModule);
279 for (ptr = firstClass; ptr; ptr = next)
281 next = ptr->next;
282 if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
287 /***********************************************************************
288 * CLASS_FindClassByAtom
290 * Return a pointer to the class.
291 * hinstance has been normalized by the caller.
293 * NOTES
294 * 980805 a local class will be found now if registred with hInst=0
295 * and looed up with a hInst!=0. msmoney does it (jsch)
297 CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
298 { CLASS * class, *tclass=0;
300 TRACE(class,"0x%08x 0x%08x\n", atom, hinstance);
302 /* First search task-specific classes */
304 for (class = firstClass; (class); class = class->next)
306 if (class->style & CS_GLOBALCLASS) continue;
307 if (class->atomName == atom)
309 if (hinstance==class->hInstance || hinstance==0xffff )
311 TRACE(class,"-- found local %p\n", class);
312 return class;
314 if (class->hInstance==0) tclass = class;
318 /* Then search global classes */
320 for (class = firstClass; (class); class = class->next)
322 if (!(class->style & CS_GLOBALCLASS)) continue;
323 if (class->atomName == atom)
325 TRACE(class,"-- found global %p\n", class);
326 return class;
330 /* Then check if there was a local class with hInst=0*/
331 if ( tclass )
333 WARN(class,"-- found local Class registred with hInst=0\n");
334 return tclass;
337 TRACE(class,"-- not found\n");
338 return 0;
342 /***********************************************************************
343 * CLASS_RegisterClass
345 * The real RegisterClass() functionality.
347 static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
348 DWORD style, INT classExtra,
349 INT winExtra, WNDPROC16 wndProc,
350 WINDOWPROCTYPE wndProcType )
352 CLASS *classPtr;
354 TRACE(class,"atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
355 atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
357 /* Check if a class with this name already exists */
358 classPtr = CLASS_FindClassByAtom( atom, hInstance );
359 if (classPtr)
361 /* Class can be created only if it is local and */
362 /* if the class with the same name is global. */
364 if (style & CS_GLOBALCLASS) return NULL;
365 if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
368 /* Fix the extra bytes value */
370 if (classExtra < 0) classExtra = 0;
371 else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
372 WARN(class, "Class extra bytes %d is > 40\n", classExtra);
373 if (winExtra < 0) winExtra = 0;
374 else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
375 WARN(class, "Win extra bytes %d is > 40\n", winExtra );
377 /* Create the class */
379 classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
380 classExtra - sizeof(classPtr->wExtra) );
381 if (!classPtr) return NULL;
382 classPtr->next = firstClass;
383 classPtr->magic = CLASS_MAGIC;
384 classPtr->cWindows = 0;
385 classPtr->style = style;
386 classPtr->winproc = (HWINDOWPROC)0;
387 classPtr->cbWndExtra = winExtra;
388 classPtr->cbClsExtra = classExtra;
389 classPtr->hInstance = hInstance;
390 classPtr->atomName = atom;
391 classPtr->menuNameA = 0;
392 classPtr->menuNameW = 0;
393 classPtr->classNameA = 0;
394 classPtr->classNameW = 0;
395 classPtr->dce = (style & CS_CLASSDC) ?
396 DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
398 WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
400 /* Other values must be set by caller */
402 if (classExtra) memset( classPtr->wExtra, 0, classExtra );
403 firstClass = classPtr;
404 return classPtr;
408 /***********************************************************************
409 * RegisterClass16 (USER.57)
411 ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
413 ATOM atom;
414 CLASS *classPtr;
415 HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
417 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
418 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
419 wc->cbClsExtra, wc->cbWndExtra,
420 wc->lpfnWndProc, WIN_PROC_16 )))
422 GlobalDeleteAtom( atom );
423 return 0;
426 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x "
427 "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
428 atom, (DWORD)wc->lpfnWndProc, hInstance,
429 wc->hbrBackground, wc->style, wc->cbClsExtra,
430 wc->cbWndExtra, classPtr,
431 HIWORD(wc->lpszClassName) ?
432 (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
434 classPtr->hIcon = wc->hIcon;
435 classPtr->hIconSm = 0;
436 classPtr->hCursor = wc->hCursor;
437 classPtr->hbrBackground = wc->hbrBackground;
439 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
440 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
441 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
442 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
444 return atom;
448 /***********************************************************************
449 * RegisterClass32A (USER32.427)
450 * RETURNS
451 * >0: Unique identifier
452 * 0: Failure
454 ATOM WINAPI RegisterClassA(
455 const WNDCLASSA* wc /* Address of structure with class data */
457 ATOM atom;
458 CLASS *classPtr;
460 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
462 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
463 return FALSE;
465 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
466 wc->cbClsExtra, wc->cbWndExtra,
467 (WNDPROC16)wc->lpfnWndProc,
468 WIN_PROC_32A )))
469 { GlobalDeleteAtom( atom );
470 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
471 return FALSE;
474 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
475 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
476 wc->hbrBackground, wc->style, wc->cbClsExtra,
477 wc->cbWndExtra, classPtr,
478 HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
480 classPtr->hIcon = (HICON16)wc->hIcon;
481 classPtr->hIconSm = 0;
482 classPtr->hCursor = (HCURSOR16)wc->hCursor;
483 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
485 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
486 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
487 return atom;
491 /***********************************************************************
492 * RegisterClass32W (USER32.430)
494 ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
496 ATOM atom;
497 CLASS *classPtr;
499 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
501 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
502 return FALSE;
504 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
505 wc->cbClsExtra, wc->cbWndExtra,
506 (WNDPROC16)wc->lpfnWndProc,
507 WIN_PROC_32W )))
509 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
510 GlobalDeleteAtom( atom );
511 return 0;
514 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
515 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
516 wc->hbrBackground, wc->style, wc->cbClsExtra,
517 wc->cbWndExtra, classPtr );
519 classPtr->hIcon = (HICON16)wc->hIcon;
520 classPtr->hIconSm = 0;
521 classPtr->hCursor = (HCURSOR16)wc->hCursor;
522 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
524 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
525 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
526 return atom;
530 /***********************************************************************
531 * RegisterClassEx16 (USER.397)
533 ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
535 ATOM atom;
536 CLASS *classPtr;
537 HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
539 if (!(atom = GlobalAddAtom16( wc->lpszClassName ))) return 0;
540 if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
541 wc->cbClsExtra, wc->cbWndExtra,
542 wc->lpfnWndProc, WIN_PROC_16 )))
544 GlobalDeleteAtom( atom );
545 return 0;
548 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
549 atom, (DWORD)wc->lpfnWndProc, hInstance,
550 wc->hbrBackground, wc->style, wc->cbClsExtra,
551 wc->cbWndExtra, classPtr );
553 classPtr->hIcon = wc->hIcon;
554 classPtr->hIconSm = wc->hIconSm;
555 classPtr->hCursor = wc->hCursor;
556 classPtr->hbrBackground = wc->hbrBackground;
558 CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
559 PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
560 CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
561 PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
562 return atom;
566 /***********************************************************************
567 * RegisterClassEx32A (USER32.428)
569 ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
571 ATOM atom;
572 CLASS *classPtr;
574 if (!(atom = GlobalAddAtomA( wc->lpszClassName )))
576 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
577 return FALSE;
579 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
580 wc->cbClsExtra, wc->cbWndExtra,
581 (WNDPROC16)wc->lpfnWndProc,
582 WIN_PROC_32A )))
584 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
585 GlobalDeleteAtom( atom );
586 return FALSE;
589 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
590 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
591 wc->hbrBackground, wc->style, wc->cbClsExtra,
592 wc->cbWndExtra, classPtr );
594 classPtr->hIcon = (HICON16)wc->hIcon;
595 classPtr->hIconSm = (HICON16)wc->hIconSm;
596 classPtr->hCursor = (HCURSOR16)wc->hCursor;
597 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
598 CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
599 CLASS_SetClassNameA( classPtr, wc->lpszClassName );
600 return atom;
604 /***********************************************************************
605 * RegisterClassEx32W (USER32.429)
607 ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
609 ATOM atom;
610 CLASS *classPtr;
612 if (!(atom = GlobalAddAtomW( wc->lpszClassName )))
614 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
615 return 0;
617 if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
618 wc->cbClsExtra, wc->cbWndExtra,
619 (WNDPROC16)wc->lpfnWndProc,
620 WIN_PROC_32W )))
622 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
623 GlobalDeleteAtom( atom );
624 return 0;
627 TRACE(class, "atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
628 atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
629 wc->hbrBackground, wc->style, wc->cbClsExtra,
630 wc->cbWndExtra, classPtr );
632 classPtr->hIcon = (HICON16)wc->hIcon;
633 classPtr->hIconSm = (HICON16)wc->hIconSm;
634 classPtr->hCursor = (HCURSOR16)wc->hCursor;
635 classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
636 CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
637 CLASS_SetClassNameW( classPtr, wc->lpszClassName );
638 return atom;
642 /***********************************************************************
643 * UnregisterClass16 (USER.403)
645 BOOL16 WINAPI UnregisterClass16( SEGPTR className, HINSTANCE16 hInstance )
647 CLASS *classPtr;
648 ATOM atom;
650 hInstance = GetExePtr( hInstance );
651 if (!(atom = GlobalFindAtom16( className ))) return FALSE;
652 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
653 (classPtr->hInstance != hInstance)) return FALSE;
654 return CLASS_FreeClass( classPtr );
658 /***********************************************************************
659 * UnregisterClass32A (USER32.563)
662 BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
663 { CLASS *classPtr;
664 ATOM atom;
665 BOOL ret;
667 TRACE(class,"%s %x\n",debugres_a(className), hInstance);
669 if (!(atom = GlobalFindAtomA( className )))
671 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
672 return FALSE;
674 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
675 (classPtr->hInstance != hInstance))
677 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
678 return FALSE;
680 if (!(ret = CLASS_FreeClass( classPtr )))
681 SetLastError(ERROR_CLASS_HAS_WINDOWS);
682 return ret;
685 /***********************************************************************
686 * UnregisterClass32W (USER32.564)
688 BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
689 { CLASS *classPtr;
690 ATOM atom;
691 BOOL ret;
693 TRACE(class,"%s %x\n",debugres_w(className), hInstance);
695 if (!(atom = GlobalFindAtomW( className )))
697 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
698 return FALSE;
700 if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
701 (classPtr->hInstance != hInstance))
703 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
704 return FALSE;
706 if (!(ret = CLASS_FreeClass( classPtr )))
707 SetLastError(ERROR_CLASS_HAS_WINDOWS);
708 return ret;
711 /***********************************************************************
712 * GetClassWord16 (USER.129)
714 WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
716 return GetClassWord( hwnd, offset );
720 /***********************************************************************
721 * GetClassWord32 (USER32.219)
723 WORD WINAPI GetClassWord( HWND hwnd, INT offset )
725 WND * wndPtr;
726 WORD retvalue = 0;
728 TRACE(class,"%x %x\n",hwnd, offset);
730 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
731 if (offset >= 0)
733 if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
735 retvalue = GET_WORD(((char *)wndPtr->class->wExtra) + offset);
736 goto END;
739 else switch(offset)
741 case GCW_HBRBACKGROUND: retvalue = wndPtr->class->hbrBackground;
742 goto END;
743 case GCW_HCURSOR: retvalue = wndPtr->class->hCursor;
744 goto END;
745 case GCW_HICON: retvalue = wndPtr->class->hIcon;
746 goto END;
747 case GCW_HICONSM: retvalue = wndPtr->class->hIconSm;
748 goto END;
749 case GCW_ATOM: retvalue = wndPtr->class->atomName;
750 goto END;
751 case GCW_STYLE:
752 case GCW_CBWNDEXTRA:
753 case GCW_CBCLSEXTRA:
754 case GCW_HMODULE:
755 retvalue = (WORD)GetClassLongA( hwnd, offset );
758 WARN(class, "Invalid offset %d\n", offset);
759 END:
760 WIN_ReleaseWndPtr(wndPtr);
761 return retvalue;
765 /***********************************************************************
766 * GetClassLong16 (USER.131)
768 LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
770 WND *wndPtr;
771 LONG ret;
773 TRACE(class,"%x %x\n",hwnd, offset);
775 switch( offset )
777 case GCL_WNDPROC:
778 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
779 ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
780 WIN_ReleaseWndPtr(wndPtr);
781 return ret;
782 case GCL_MENUNAME:
783 ret = GetClassLongA( hwnd, offset );
784 return (LONG)SEGPTR_GET( (void *)ret );
785 default:
786 return GetClassLongA( hwnd, offset );
791 /***********************************************************************
792 * GetClassLong32A (USER32.215)
794 LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
796 WND * wndPtr;
797 LONG retvalue;
799 TRACE(class,"%x %x\n",hwnd, offset);
801 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
802 if (offset >= 0)
804 if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
806 retvalue = GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
807 goto END;
811 switch(offset)
813 case GCL_STYLE: retvalue = (LONG)wndPtr->class->style;
814 goto END;
815 case GCL_CBWNDEXTRA: retvalue = (LONG)wndPtr->class->cbWndExtra;
816 goto END;
817 case GCL_CBCLSEXTRA: retvalue = (LONG)wndPtr->class->cbClsExtra;
818 goto END;
819 case GCL_HMODULE: retvalue = (LONG)wndPtr->class->hInstance;
820 goto END;
821 case GCL_WNDPROC:
822 retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
823 goto END;
824 case GCL_MENUNAME:
825 retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
826 goto END;
827 case GCW_ATOM:
828 case GCL_HBRBACKGROUND:
829 case GCL_HCURSOR:
830 case GCL_HICON:
831 case GCL_HICONSM:
832 retvalue = GetClassWord( hwnd, offset );
833 goto END;
835 WARN(class, "Invalid offset %d\n", offset);
836 retvalue = 0;
837 END:
838 WIN_ReleaseWndPtr(wndPtr);
839 return retvalue;
843 /***********************************************************************
844 * GetClassLong32W (USER32.216)
846 LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
848 WND * wndPtr;
849 LONG retvalue;
851 TRACE(class,"%x %x\n",hwnd, offset);
853 switch(offset)
855 case GCL_WNDPROC:
856 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
857 retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
858 WIN_ReleaseWndPtr(wndPtr);
859 return retvalue;
860 case GCL_MENUNAME:
861 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
862 retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
863 WIN_ReleaseWndPtr(wndPtr);
864 return retvalue;
865 default:
866 return GetClassLongA( hwnd, offset );
871 /***********************************************************************
872 * SetClassWord16 (USER.130)
874 WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
876 return SetClassWord( hwnd, offset, newval );
880 /***********************************************************************
881 * SetClassWord32 (USER32.469)
883 WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
885 WND * wndPtr;
886 WORD retval = 0;
887 void *ptr;
889 TRACE(class,"%x %x %x\n",hwnd, offset, newval);
891 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
892 if (offset >= 0)
894 if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
895 ptr = ((char *)wndPtr->class->wExtra) + offset;
896 else
898 WARN( class, "Invalid offset %d\n", offset );
899 WIN_ReleaseWndPtr(wndPtr);
900 return 0;
903 else switch(offset)
905 case GCW_STYLE:
906 case GCW_CBWNDEXTRA:
907 case GCW_CBCLSEXTRA:
908 case GCW_HMODULE:
909 WIN_ReleaseWndPtr(wndPtr);
910 return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
911 case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
912 case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
913 case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
914 case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
915 case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
916 default:
917 WARN( class, "Invalid offset %d\n", offset);
918 WIN_ReleaseWndPtr(wndPtr);
919 return 0;
921 retval = GET_WORD(ptr);
922 PUT_WORD( ptr, newval );
924 /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
925 need to be updated as well. Problem is that we can't tell whether the atom is
926 using wide or narrow characters. For now, we'll just NULL out the className
927 fields, and emit a FIXME. */
928 if (offset == GCW_ATOM)
930 CLASS_SetClassNameA( wndPtr->class, NULL );
931 FIXME(class,"GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
933 WIN_ReleaseWndPtr(wndPtr);
934 return retval;
938 /***********************************************************************
939 * SetClassLong16 (USER.132)
941 LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
943 WND *wndPtr;
944 LONG retval;
946 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
948 switch(offset)
950 case GCL_WNDPROC:
951 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
952 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
953 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
954 WIN_PROC_16, WIN_PROC_CLASS );
955 WIN_ReleaseWndPtr(wndPtr);
956 return retval;
957 case GCL_MENUNAME:
958 return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
959 default:
960 return SetClassLongA( hwnd, offset, newval );
965 /***********************************************************************
966 * SetClassLong32A (USER32.467)
968 LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
970 WND * wndPtr;
971 LONG retval = 0;
972 void *ptr;
974 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
976 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
977 if (offset >= 0)
979 if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
980 ptr = ((char *)wndPtr->class->wExtra) + offset;
981 else
983 WARN( class, "Invalid offset %d\n", offset );
984 retval = 0;
985 goto END;
988 else switch(offset)
990 case GCL_MENUNAME:
991 CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
992 retval = 0; /* Old value is now meaningless anyway */
993 goto END;
994 case GCL_WNDPROC:
995 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
996 WIN_PROC_32A );
997 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
998 WIN_PROC_32A, WIN_PROC_CLASS );
999 goto END;
1000 case GCL_HBRBACKGROUND:
1001 case GCL_HCURSOR:
1002 case GCL_HICON:
1003 case GCL_HICONSM:
1004 retval = SetClassWord( hwnd, offset, (WORD)newval );
1005 goto END;
1006 case GCL_STYLE: ptr = &wndPtr->class->style; break;
1007 case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
1008 case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
1009 case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
1010 default:
1011 WARN( class, "Invalid offset %d\n", offset );
1012 retval = 0;
1013 goto END;
1015 retval = GET_DWORD(ptr);
1016 PUT_DWORD( ptr, newval );
1017 END:
1018 WIN_ReleaseWndPtr(wndPtr);
1019 return retval;
1023 /***********************************************************************
1024 * SetClassLong32W (USER32.468)
1026 LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
1028 WND *wndPtr;
1029 LONG retval;
1031 TRACE(class,"%x %x %lx\n",hwnd, offset, newval);
1033 switch(offset)
1035 case GCL_WNDPROC:
1036 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1037 retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
1038 WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
1039 WIN_PROC_32W, WIN_PROC_CLASS );
1040 WIN_ReleaseWndPtr(wndPtr);
1041 return retval;
1042 case GCL_MENUNAME:
1043 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1044 CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
1045 WIN_ReleaseWndPtr(wndPtr);
1046 return 0; /* Old value is now meaningless anyway */
1047 default:
1048 return SetClassLongA( hwnd, offset, newval );
1053 /***********************************************************************
1054 * GetClassName16 (USER.58)
1056 INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
1058 WND *wndPtr;
1059 INT16 retvalue;
1060 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1061 retvalue = GlobalGetAtomName16( wndPtr->class->atomName, buffer, count );
1062 WIN_ReleaseWndPtr(wndPtr);
1063 return retvalue;
1067 /***********************************************************************
1068 * GetClassName32A (USER32.217)
1070 INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
1071 { INT ret;
1072 WND *wndPtr;
1074 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1075 ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
1077 WIN_ReleaseWndPtr(wndPtr);
1078 TRACE(class,"%x %s %x\n",hwnd, buffer, count);
1079 return ret;
1083 /***********************************************************************
1084 * GetClassName32W (USER32.218)
1086 INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
1087 { INT ret;
1088 WND *wndPtr;
1090 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
1091 ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
1092 WIN_ReleaseWndPtr(wndPtr);
1093 TRACE(class,"%x %s %x\n",hwnd, debugstr_w(buffer), count);
1095 return ret;
1099 /***********************************************************************
1100 * GetClassInfo16 (USER.404)
1102 BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name,
1103 WNDCLASS16 *wc )
1105 ATOM atom;
1106 CLASS *classPtr;
1108 TRACE(class,"%x %p %p\n",hInstance, PTR_SEG_TO_LIN (name), wc);
1110 hInstance = GetExePtr( hInstance );
1111 if (!(atom = GlobalFindAtom16( name )) ||
1112 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
1113 return FALSE;
1114 if ((hInstance != classPtr->hInstance) &&
1115 !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
1116 return FALSE;
1117 wc->style = (UINT16)classPtr->style;
1118 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1119 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1120 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1121 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1122 wc->hIcon = classPtr->hIcon;
1123 wc->hCursor = classPtr->hCursor;
1124 wc->hbrBackground = classPtr->hbrBackground;
1125 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
1126 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1127 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1128 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1129 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1130 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1131 return TRUE;
1135 /***********************************************************************
1136 * GetClassInfo32A (USER32.211)
1138 BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
1139 WNDCLASSA *wc )
1141 ATOM atom;
1142 CLASS *classPtr;
1144 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1146 /* workaround: if hInstance=NULL you expect to get the system classes
1147 but this classes (as example from comctl32.dll SysListView) won't be
1148 registred with hInstance=NULL in WINE because of the late loading
1149 of this dll. fixes file dialogs in WinWord95 (jsch)*/
1151 if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
1152 return FALSE;
1154 if (classPtr->hInstance && (hInstance != classPtr->hInstance))
1156 if (hInstance) return FALSE;
1157 else
1158 WARN(class,"systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
1161 wc->style = classPtr->style;
1162 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1163 WIN_PROC_32A );
1164 wc->cbClsExtra = classPtr->cbClsExtra;
1165 wc->cbWndExtra = classPtr->cbWndExtra;
1166 wc->hInstance = classPtr->hInstance;
1167 wc->hIcon = (HICON)classPtr->hIcon;
1168 wc->hCursor = (HCURSOR)classPtr->hCursor;
1169 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1170 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1171 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1172 return TRUE;
1176 /***********************************************************************
1177 * GetClassInfo32W (USER32.214)
1179 BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
1180 WNDCLASSW *wc )
1182 ATOM atom;
1183 CLASS *classPtr;
1185 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1187 if (!(atom = GlobalFindAtomW( name )) ||
1188 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1189 (classPtr->hInstance && (hInstance != classPtr->hInstance)))
1190 return FALSE;
1192 wc->style = classPtr->style;
1193 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1194 WIN_PROC_32W );
1195 wc->cbClsExtra = classPtr->cbClsExtra;
1196 wc->cbWndExtra = classPtr->cbWndExtra;
1197 wc->hInstance = classPtr->hInstance;
1198 wc->hIcon = (HICON)classPtr->hIcon;
1199 wc->hCursor = (HCURSOR)classPtr->hCursor;
1200 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1201 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1202 wc->lpszClassName = CLASS_GetClassNameW( classPtr );
1203 return TRUE;
1207 /***********************************************************************
1208 * GetClassInfoEx16 (USER.398)
1210 * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
1211 * same in Win16 as in Win32. --AJ
1213 BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name,
1214 WNDCLASSEX16 *wc )
1216 ATOM atom;
1217 CLASS *classPtr;
1219 TRACE(class,"%x %p %p\n",hInstance,PTR_SEG_TO_LIN( name ), wc);
1221 hInstance = GetExePtr( hInstance );
1222 if (!(atom = GlobalFindAtom16( name )) ||
1223 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1224 (hInstance != classPtr->hInstance)) return FALSE;
1225 wc->style = classPtr->style;
1226 wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
1227 wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
1228 wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
1229 wc->hInstance = (HINSTANCE16)classPtr->hInstance;
1230 wc->hIcon = classPtr->hIcon;
1231 wc->hIconSm = classPtr->hIconSm;
1232 wc->hCursor = classPtr->hCursor;
1233 wc->hbrBackground = classPtr->hbrBackground;
1234 wc->lpszClassName = (SEGPTR)0;
1235 wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
1236 if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
1237 wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
1238 wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
1239 if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
1240 wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
1241 return TRUE;
1245 /***********************************************************************
1246 * GetClassInfoEx32A (USER32.212)
1248 BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
1249 WNDCLASSEXA *wc )
1251 ATOM atom;
1252 CLASS *classPtr;
1254 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1256 if (!(atom = GlobalFindAtomA( name )) ||
1257 !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
1258 /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
1259 wc->style = classPtr->style;
1260 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1261 WIN_PROC_32A );
1262 wc->cbClsExtra = classPtr->cbClsExtra;
1263 wc->cbWndExtra = classPtr->cbWndExtra;
1264 wc->hInstance = classPtr->hInstance;
1265 wc->hIcon = (HICON)classPtr->hIcon;
1266 wc->hIconSm = (HICON)classPtr->hIconSm;
1267 wc->hCursor = (HCURSOR)classPtr->hCursor;
1268 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1269 wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
1270 wc->lpszClassName = CLASS_GetClassNameA( classPtr );
1271 return TRUE;
1275 /***********************************************************************
1276 * GetClassInfoEx32W (USER32.213)
1278 BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
1279 WNDCLASSEXW *wc )
1281 ATOM atom;
1282 CLASS *classPtr;
1284 TRACE(class,"%x %p %p\n",hInstance, name, wc);
1286 if (!(atom = GlobalFindAtomW( name )) ||
1287 !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
1288 (hInstance != classPtr->hInstance)) return FALSE;
1289 wc->style = classPtr->style;
1290 wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
1291 WIN_PROC_32W );
1292 wc->cbClsExtra = classPtr->cbClsExtra;
1293 wc->cbWndExtra = classPtr->cbWndExtra;
1294 wc->hInstance = classPtr->hInstance;
1295 wc->hIcon = (HICON)classPtr->hIcon;
1296 wc->hIconSm = (HICON)classPtr->hIconSm;
1297 wc->hCursor = (HCURSOR)classPtr->hCursor;
1298 wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
1299 wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
1300 wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
1301 return TRUE;
1305 /***********************************************************************
1306 * ClassFirst (TOOLHELP.69)
1308 BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
1310 TRACE(class,"%p\n",pClassEntry);
1311 pClassEntry->wNext = 1;
1312 return ClassNext16( pClassEntry );
1316 /***********************************************************************
1317 * ClassNext (TOOLHELP.70)
1319 BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
1321 int i;
1322 CLASS *class = firstClass;
1324 TRACE(class,"%p\n",pClassEntry);
1326 if (!pClassEntry->wNext) return FALSE;
1327 for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
1328 if (!class)
1330 pClassEntry->wNext = 0;
1331 return FALSE;
1333 pClassEntry->hInst = class->hInstance;
1334 pClassEntry->wNext++;
1335 GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
1336 sizeof(pClassEntry->szClassName) );
1337 return TRUE;