/*
* Window classes functions
*
- * Copyright 1993 Alexandre Julliard
+ * Copyright 1993, 1996 Alexandre Julliard
+ * 1998 Juergen Schmied (jsch)
+ *
+ * FIXME: In win32 all classes are local. They are registered at
+ * program start. Processes CANNOT share classes. (Source: some
+ * win31->NT migration book)
+ *
+ * FIXME: There seems to be a general problem with hInstance in WINE
+ * classes are getting registred with wrong hInstance.
*/
-static char Copyright[] = "Copyright Alexandre Julliard, 1993";
-
#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
+#include "wine/winbase16.h"
+#include "winerror.h"
+#include "windef.h"
+#include "wingdi.h"
+#include "wine/winuser16.h"
+#include "wine/unicode.h"
#include "class.h"
-#include "user.h"
+#include "heap.h"
#include "win.h"
#include "dce.h"
-#include "stddebug.h"
-/* #define DEBUG_CLASS /* */
-/* #undef DEBUG_CLASS /* */
-#include "debug.h"
+#include "ldt.h"
+#include "toolhelp.h"
+#include "winproc.h"
+#include "debugtools.h"
+
+DEFAULT_DEBUG_CHANNEL(class);
-static HCLASS firstClass = 0;
+static CLASS *firstClass = NULL;
/***********************************************************************
- * CLASS_FindClassByName
+ * CLASS_DumpClass
*
- * Return a handle and a pointer to the class.
- * 'ptr' can be NULL if the pointer is not needed.
+ * Dump the content of a class structure to stderr.
*/
-HCLASS CLASS_FindClassByName( char * name, CLASS **ptr )
+void CLASS_DumpClass( CLASS *ptr )
{
- ATOM atom;
- HCLASS class;
- CLASS * classPtr;
+ char className[MAX_CLASSNAME+1];
+ int i;
+
+ if (ptr->magic != CLASS_MAGIC)
+ {
+ DPRINTF("%p is not a class\n", ptr );
+ return;
+ }
+
+ GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
+
+ DPRINTF( "Class %p:\n", ptr );
+ DPRINTF( "next=%p name=%04x '%s' style=%08x wndProc=%08x\n"
+ "inst=%04x dce=%08x icon=%04x cursor=%04x bkgnd=%04x\n"
+ "clsExtra=%d winExtra=%d #windows=%d\n",
+ ptr->next, ptr->atomName, className, ptr->style,
+ (UINT)ptr->winproc, ptr->hInstance, (UINT)ptr->dce,
+ ptr->hIcon, ptr->hCursor, ptr->hbrBackground,
+ ptr->cbClsExtra, ptr->cbWndExtra, ptr->cWindows );
+ if (ptr->cbClsExtra)
+ {
+ DPRINTF( "extra bytes:" );
+ for (i = 0; i < ptr->cbClsExtra; i++)
+ DPRINTF( " %02x", *((BYTE *)ptr->wExtra+i) );
+ DPRINTF( "\n" );
+ }
+ DPRINTF( "\n" );
+}
+
+
+/***********************************************************************
+ * CLASS_WalkClasses
+ *
+ * Walk the class list and print each class on stderr.
+ */
+void CLASS_WalkClasses(void)
+{
+ CLASS *ptr;
+ char className[MAX_CLASSNAME+1];
+
+ DPRINTF( " Class Name Style WndProc\n" );
+ for (ptr = firstClass; ptr; ptr = ptr->next)
+ {
+ GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
+ DPRINTF( "%08x %-20.20s %08x %08x\n", (UINT)ptr, className,
+ ptr->style, (UINT)ptr->winproc );
+ }
+ DPRINTF( "\n" );
+}
+
+
+/***********************************************************************
+ * CLASS_GetMenuNameA
+ *
+ * Get the menu name as a ASCII string.
+ */
+static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
+{
+ if (!classPtr->menuNameA && classPtr->menuNameW)
+ {
+ /* We need to copy the Unicode string */
+ classPtr->menuNameA = SEGPTR_STRDUP_WtoA( classPtr->menuNameW );
+ }
+ return classPtr->menuNameA;
+}
+
+
+/***********************************************************************
+ * CLASS_GetMenuNameW
+ *
+ * Get the menu name as a Unicode string.
+ */
+static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
+{
+ if (!classPtr->menuNameW && classPtr->menuNameA)
+ {
+ if (!HIWORD(classPtr->menuNameA))
+ return (LPWSTR)classPtr->menuNameA;
+ /* Now we need to copy the ASCII string */
+ classPtr->menuNameW = HEAP_strdupAtoW( SystemHeap, 0,
+ classPtr->menuNameA );
+ }
+ return classPtr->menuNameW;
+}
+
+
+/***********************************************************************
+ * CLASS_SetMenuNameA
+ *
+ * Set the menu name in a class structure by copying the string.
+ */
+static void CLASS_SetMenuNameA( CLASS *classPtr, LPCSTR name )
+{
+ if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
+ if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
+ classPtr->menuNameA = SEGPTR_STRDUP( name );
+ classPtr->menuNameW = 0;
+}
+
+
+/***********************************************************************
+ * CLASS_SetMenuNameW
+ *
+ * Set the menu name in a class structure by copying the string.
+ */
+static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
+{
+ if (!HIWORD(name))
+ {
+ CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
+ return;
+ }
+ if (HIWORD(classPtr->menuNameA)) SEGPTR_FREE( classPtr->menuNameA );
+ if (classPtr->menuNameW) HeapFree( SystemHeap, 0, classPtr->menuNameW );
+ if ((classPtr->menuNameW = HeapAlloc( SystemHeap, 0,
+ (strlenW(name)+1)*sizeof(WCHAR) )))
+ strcpyW( classPtr->menuNameW, name );
+ classPtr->menuNameA = 0;
+}
+
+
+/***********************************************************************
+ * CLASS_GetClassNameA
+ *
+ * Get the clas name as a ASCII string.
+ */
+static LPSTR CLASS_GetClassNameA( CLASS *classPtr )
+{
+ if (!classPtr->classNameA && classPtr->classNameW)
+ {
+ /* We need to copy the Unicode string */
+ classPtr->classNameA = SEGPTR_STRDUP_WtoA( classPtr->classNameW );
+ }
+ return classPtr->classNameA;
+}
- /* First search task-specific classes */
- if ((atom = FindAtom( name )) != 0)
+/***********************************************************************
+ * CLASS_GetClassNameW
+ *
+ * Get the class name as a Unicode string.
+ */
+static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
+{
+ if (!classPtr->classNameW && classPtr->classNameA)
{
- for (class = firstClass; (class); class = classPtr->hNext)
- {
- classPtr = (CLASS *) USER_HEAP_ADDR(class);
- if (classPtr->wc.style & CS_GLOBALCLASS) continue;
- if (classPtr->atomName == atom)
- {
- if (ptr) *ptr = classPtr;
- return class;
- }
- }
+ if (!HIWORD(classPtr->classNameA))
+ return (LPWSTR)classPtr->classNameA;
+ /* Now we need to copy the ASCII string */
+ classPtr->classNameW = HEAP_strdupAtoW( SystemHeap, 0,
+ classPtr->classNameA );
+ }
+ return classPtr->classNameW;
+}
+
+/***********************************************************************
+ * CLASS_SetClassNameA
+ *
+ * Set the class name in a class structure by copying the string.
+ */
+static void CLASS_SetClassNameA( CLASS *classPtr, LPCSTR name )
+{
+ if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
+ if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
+ classPtr->classNameA = SEGPTR_STRDUP( name );
+ classPtr->classNameW = 0;
+}
+
+
+/***********************************************************************
+ * CLASS_SetClassNameW
+ *
+ * Set the class name in a class structure by copying the string.
+ */
+static void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name )
+{
+ if (!HIWORD(name))
+ {
+ CLASS_SetClassNameA( classPtr, (LPCSTR)name );
+ return;
+ }
+ if (HIWORD(classPtr->classNameA)) SEGPTR_FREE( classPtr->classNameA );
+ if (classPtr->classNameW) HeapFree( SystemHeap, 0, classPtr->classNameW );
+ if ((classPtr->classNameW = HeapAlloc( SystemHeap, 0,
+ (strlenW(name)+1)*sizeof(WCHAR) )))
+ strcpyW( classPtr->classNameW, name );
+ classPtr->classNameA = 0;
+}
+
+
+/***********************************************************************
+ * CLASS_FreeClass
+ *
+ * Free a class structure.
+ */
+static BOOL CLASS_FreeClass( CLASS *classPtr )
+{
+ CLASS **ppClass;
+ TRACE("%p \n", classPtr);
+
+ /* Check if we can remove this class */
+
+ if (classPtr->cWindows > 0) return FALSE;
+
+ /* Remove the class from the linked list */
+
+ for (ppClass = &firstClass; *ppClass; ppClass = &(*ppClass)->next)
+ if (*ppClass == classPtr) break;
+ if (!*ppClass)
+ {
+ ERR("Class list corrupted\n" );
+ return FALSE;
+ }
+ *ppClass = classPtr->next;
+
+ /* Delete the class */
+
+ if (classPtr->dce) DCE_FreeDCE( classPtr->dce );
+ if (classPtr->hbrBackground) DeleteObject( classPtr->hbrBackground );
+ GlobalDeleteAtom( classPtr->atomName );
+ CLASS_SetMenuNameA( classPtr, NULL );
+ CLASS_SetClassNameA( classPtr, NULL );
+ WINPROC_FreeProc( classPtr->winproc, WIN_PROC_CLASS );
+ HeapFree( SystemHeap, 0, classPtr );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * CLASS_FreeModuleClasses
+ */
+void CLASS_FreeModuleClasses( HMODULE16 hModule )
+{
+ CLASS *ptr, *next;
+
+ TRACE("0x%08x \n", hModule);
+
+ for (ptr = firstClass; ptr; ptr = next)
+ {
+ next = ptr->next;
+ if (ptr->hInstance == hModule) CLASS_FreeClass( ptr );
+ }
+}
+
+
+/***********************************************************************
+ * CLASS_FindClassByAtom
+ *
+ * Return a pointer to the class.
+ * hinstance has been normalized by the caller.
+ *
+ * NOTES
+ * 980805 a local class will be found now if registred with hInst=0
+ * and looed up with a hInst!=0. msmoney does it (jsch)
+ */
+CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
+{ CLASS * class, *tclass=0;
+
+ TRACE("0x%08x 0x%08x\n", atom, hinstance);
+
+ /* First search task-specific classes */
+
+ for (class = firstClass; (class); class = class->next)
+ {
+ if (class->style & CS_GLOBALCLASS) continue;
+ if (class->atomName == atom)
+ {
+ if (hinstance==class->hInstance || hinstance==0xffff )
+ {
+ TRACE("-- found local %p\n", class);
+ return class;
+ }
+ if (class->hInstance==0) tclass = class;
+ }
}
/* Then search global classes */
- if ((atom = GlobalFindAtom( name )) != 0)
+ for (class = firstClass; (class); class = class->next)
{
- for (class = firstClass; (class); class = classPtr->hNext)
- {
- classPtr = (CLASS *) USER_HEAP_ADDR(class);
- if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
- if (classPtr->atomName == atom)
- {
- if (ptr) *ptr = classPtr;
- return class;
- }
- }
+ if (!(class->style & CS_GLOBALCLASS)) continue;
+ if (class->atomName == atom)
+ {
+ TRACE("-- found global %p\n", class);
+ return class;
+ }
}
+ /* Then check if there was a local class with hInst=0*/
+ if ( tclass )
+ {
+ WARN("-- found local Class registred with hInst=0\n");
+ return tclass;
+ }
+
+ TRACE("-- not found\n");
return 0;
}
/***********************************************************************
- * CLASS_FindClassPtr
+ * CLASS_RegisterClass
*
- * Return a pointer to the CLASS structure corresponding to a HCLASS.
+ * The real RegisterClass() functionality.
*/
-CLASS * CLASS_FindClassPtr( HCLASS hclass )
+static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
+ DWORD style, INT classExtra,
+ INT winExtra, WNDPROC16 wndProc,
+ WINDOWPROCTYPE wndProcType )
{
- CLASS * ptr;
+ CLASS *classPtr;
+
+ TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x wndProc=0x%p ProcType=0x%x\n",
+ atom, hInstance, style, classExtra, winExtra, wndProc, wndProcType);
+
+ /* Check if a class with this name already exists */
+ classPtr = CLASS_FindClassByAtom( atom, hInstance );
+ if (classPtr)
+ {
+ /* Class can be created only if it is local and */
+ /* if the class with the same name is global. */
+
+ if (style & CS_GLOBALCLASS) return NULL;
+ if (!(classPtr->style & CS_GLOBALCLASS)) return NULL;
+ }
+
+ /* Fix the extra bytes value */
+
+ if (classExtra < 0) classExtra = 0;
+ else if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
+ WARN("Class extra bytes %d is > 40\n", classExtra);
+ if (winExtra < 0) winExtra = 0;
+ else if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
+ WARN("Win extra bytes %d is > 40\n", winExtra );
+
+ /* Create the class */
+
+ classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
+ classExtra - sizeof(classPtr->wExtra) );
+ if (!classPtr) return NULL;
+ classPtr->next = firstClass;
+ classPtr->magic = CLASS_MAGIC;
+ classPtr->cWindows = 0;
+ classPtr->style = style;
+ classPtr->winproc = (HWINDOWPROC)0;
+ classPtr->cbWndExtra = winExtra;
+ classPtr->cbClsExtra = classExtra;
+ classPtr->hInstance = hInstance;
+ classPtr->atomName = atom;
+ classPtr->menuNameA = 0;
+ classPtr->menuNameW = 0;
+ classPtr->classNameA = 0;
+ classPtr->classNameW = 0;
+ classPtr->dce = (style & CS_CLASSDC) ?
+ DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
+
+ WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
+
+ /* Other values must be set by caller */
+
+ if (classExtra) memset( classPtr->wExtra, 0, classExtra );
+ firstClass = classPtr;
+ return classPtr;
+}
+
+
+/***********************************************************************
+ * RegisterClass16 (USER.57)
+ */
+ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+ int iSmIconWidth, iSmIconHeight;
+ HINSTANCE16 hInstance=GetExePtr(wc->hInstance);
+
+ if (!(atom = GlobalAddAtomA( PTR_SEG_TO_LIN(wc->lpszClassName) ))) return 0;
+ if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
+ wc->cbClsExtra, wc->cbWndExtra,
+ wc->lpfnWndProc, WIN_PROC_16 )))
+ {
+ GlobalDeleteAtom( atom );
+ return 0;
+ }
+
+ TRACE("atom=%04x wndproc=%08lx hinst=%04x "
+ "bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
+ atom, (DWORD)wc->lpfnWndProc, hInstance,
+ wc->hbrBackground, wc->style, wc->cbClsExtra,
+ wc->cbWndExtra, classPtr,
+ HIWORD(wc->lpszClassName) ?
+ (char *)PTR_SEG_TO_LIN(wc->lpszClassName) : "" );
+
+ iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
+ iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
+
+ classPtr->hIcon = wc->hIcon;
+ classPtr->hIconSm = CopyImage(wc->hIcon, IMAGE_ICON,
+ iSmIconWidth, iSmIconHeight,
+ LR_COPYFROMRESOURCE);
+ classPtr->hCursor = wc->hCursor;
+ classPtr->hbrBackground = wc->hbrBackground;
+
+ CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
+ PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
+ CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
+ PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
+
+ return atom;
+}
+
+
+/***********************************************************************
+ * RegisterClassA (USER32.427)
+ * RETURNS
+ * >0: Unique identifier
+ * 0: Failure
+ */
+ATOM WINAPI RegisterClassA( const WNDCLASSA* wc ) /* Address of structure with class data */
+{
+ ATOM atom;
+ int iSmIconWidth, iSmIconHeight;
+ CLASS *classPtr;
+
+ if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
+
+ if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
+ wc->cbClsExtra, wc->cbWndExtra,
+ (WNDPROC16)wc->lpfnWndProc,
+ WIN_PROC_32A )))
+ { GlobalDeleteAtom( atom );
+ SetLastError(ERROR_CLASS_ALREADY_EXISTS);
+ return FALSE;
+ }
+
+ TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
+ atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
+ wc->hbrBackground, wc->style, wc->cbClsExtra,
+ wc->cbWndExtra, classPtr,
+ HIWORD(wc->lpszClassName) ? wc->lpszClassName : "" );
+
+ iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
+ iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
+
+ classPtr->hIcon = wc->hIcon;
+ classPtr->hIconSm = CopyImage(wc->hIcon, IMAGE_ICON,
+ iSmIconWidth, iSmIconHeight,
+ LR_COPYFROMRESOURCE);
+ classPtr->hCursor = (HCURSOR16)wc->hCursor;
+ classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
+
+ CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
+ CLASS_SetClassNameA( classPtr, wc->lpszClassName );
+ return atom;
+}
+
+
+/***********************************************************************
+ * RegisterClassW (USER32.430)
+ */
+ATOM WINAPI RegisterClassW( const WNDCLASSW* wc )
+{
+ ATOM atom;
+ int iSmIconWidth, iSmIconHeight;
+ CLASS *classPtr;
+
+ if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
+
+ if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
+ wc->cbClsExtra, wc->cbWndExtra,
+ (WNDPROC16)wc->lpfnWndProc,
+ WIN_PROC_32W )))
+ {
+ SetLastError(ERROR_CLASS_ALREADY_EXISTS);
+ GlobalDeleteAtom( atom );
+ return 0;
+ }
+
+ TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
+ atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
+ wc->hbrBackground, wc->style, wc->cbClsExtra,
+ wc->cbWndExtra, classPtr );
- if (!hclass) return NULL;
- ptr = (CLASS *) USER_HEAP_ADDR( hclass );
- if (ptr->wMagic != CLASS_MAGIC) return NULL;
- return ptr;
+ iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
+ iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
+
+ classPtr->hIcon = wc->hIcon;
+ classPtr->hIconSm = CopyImage(wc->hIcon, IMAGE_ICON,
+ iSmIconWidth, iSmIconHeight,
+ LR_COPYFROMRESOURCE);
+ classPtr->hCursor = (HCURSOR16)wc->hCursor;
+ classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
+
+ CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
+ CLASS_SetClassNameW( classPtr, wc->lpszClassName );
+ return atom;
}
/***********************************************************************
- * RegisterClass (USER.57)
+ * RegisterClassEx16 (USER.397)
*/
-ATOM RegisterClass( LPWNDCLASS class )
+ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc )
{
- CLASS * newClass, * prevClassPtr;
- HCLASS handle, prevClass;
- int classExtra;
+ ATOM atom;
+ CLASS *classPtr;
+ HINSTANCE16 hInstance = GetExePtr( wc->hInstance );
+
+ if (!(atom = GlobalAddAtomA( PTR_SEG_TO_LIN(wc->lpszClassName) ))) return 0;
+ if (!(classPtr = CLASS_RegisterClass( atom, hInstance, wc->style,
+ wc->cbClsExtra, wc->cbWndExtra,
+ wc->lpfnWndProc, WIN_PROC_16 )))
+ {
+ GlobalDeleteAtom( atom );
+ return 0;
+ }
- dprintf_class(stddeb, "RegisterClass: wndproc=%08x hinst=%d name='%s' background %x\n",
- class->lpfnWndProc, class->hInstance, class->lpszClassName,
- class->hbrBackground );
+ TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
+ atom, (DWORD)wc->lpfnWndProc, hInstance,
+ wc->hbrBackground, wc->style, wc->cbClsExtra,
+ wc->cbWndExtra, classPtr );
+
+ classPtr->hIcon = wc->hIcon;
+ classPtr->hIconSm = wc->hIconSm;
+ classPtr->hCursor = wc->hCursor;
+ classPtr->hbrBackground = wc->hbrBackground;
- /* Check if a class with this name already exists */
+ CLASS_SetMenuNameA( classPtr, HIWORD(wc->lpszMenuName) ?
+ PTR_SEG_TO_LIN(wc->lpszMenuName) : (LPCSTR)wc->lpszMenuName );
+ CLASS_SetClassNameA( classPtr, HIWORD(wc->lpszClassName) ?
+ PTR_SEG_TO_LIN(wc->lpszClassName) : (LPCSTR)wc->lpszClassName );
+ return atom;
+}
- prevClass = CLASS_FindClassByName( class->lpszClassName, &prevClassPtr );
- if (prevClass)
+
+/***********************************************************************
+ * RegisterClassExA (USER32.428)
+ */
+ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ if (!(atom = GlobalAddAtomA( wc->lpszClassName ))) return 0;
+
+ if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
+ wc->cbClsExtra, wc->cbWndExtra,
+ (WNDPROC16)wc->lpfnWndProc,
+ WIN_PROC_32A )))
{
- /* Class can be created only if it is local and */
- /* if the class with the same name is global. */
+ SetLastError(ERROR_CLASS_ALREADY_EXISTS);
+ GlobalDeleteAtom( atom );
+ return FALSE;
+ }
+
+ TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
+ atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
+ wc->hbrBackground, wc->style, wc->cbClsExtra,
+ wc->cbWndExtra, classPtr );
+
+ classPtr->hIcon = (HICON16)wc->hIcon;
+ classPtr->hIconSm = (HICON16)wc->hIconSm;
+ classPtr->hCursor = (HCURSOR16)wc->hCursor;
+ classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
+ CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
+ CLASS_SetClassNameA( classPtr, wc->lpszClassName );
+ return atom;
+}
- if (class->style & CS_GLOBALCLASS) return 0;
- if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0;
+
+/***********************************************************************
+ * RegisterClassExW (USER32.429)
+ */
+ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ if (!(atom = GlobalAddAtomW( wc->lpszClassName ))) return 0;
+
+ if (!(classPtr = CLASS_RegisterClass( atom, wc->hInstance, wc->style,
+ wc->cbClsExtra, wc->cbWndExtra,
+ (WNDPROC16)wc->lpfnWndProc,
+ WIN_PROC_32W )))
+ {
+ SetLastError(ERROR_CLASS_ALREADY_EXISTS);
+ GlobalDeleteAtom( atom );
+ return 0;
}
- /* Create class */
+ TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
+ atom, (DWORD)wc->lpfnWndProc, wc->hInstance,
+ wc->hbrBackground, wc->style, wc->cbClsExtra,
+ wc->cbWndExtra, classPtr );
+
+ classPtr->hIcon = (HICON16)wc->hIcon;
+ classPtr->hIconSm = (HICON16)wc->hIconSm;
+ classPtr->hCursor = (HCURSOR16)wc->hCursor;
+ classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
+ CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
+ CLASS_SetClassNameW( classPtr, wc->lpszClassName );
+ return atom;
+}
+
- classExtra = (class->cbClsExtra < 0) ? 0 : class->cbClsExtra;
- handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS) + classExtra );
- if (!handle) return 0;
- newClass = (CLASS *) USER_HEAP_ADDR( handle );
- newClass->hNext = firstClass;
- newClass->wMagic = CLASS_MAGIC;
- newClass->cWindows = 0;
- newClass->wc = *class;
- newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
- newClass->wc.cbClsExtra = classExtra;
+/***********************************************************************
+ * UnregisterClass16 (USER.403)
+ */
+BOOL16 WINAPI UnregisterClass16( LPCSTR className, HINSTANCE16 hInstance )
+{
+ return UnregisterClassA( className, GetExePtr( hInstance ) );
+}
- if (newClass->wc.style & CS_GLOBALCLASS)
- newClass->atomName = GlobalAddAtom( class->lpszClassName );
- else newClass->atomName = AddAtom( class->lpszClassName );
- newClass->wc.lpszClassName = NULL;
- if (newClass->wc.style & CS_CLASSDC)
- newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
- else newClass->hdce = 0;
+/***********************************************************************
+ * UnregisterClassA (USER32.563)
+ *
+ */
+BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
+{ CLASS *classPtr;
+ ATOM atom;
+ BOOL ret;
- /* Make a copy of the menu name (only if it is a string) */
+ TRACE("%s %x\n",debugres_a(className), hInstance);
- if ((int)class->lpszMenuName & 0xffff0000)
+ if (!(atom = GlobalFindAtomA( className )))
{
- HANDLE hname;
- hname = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(class->lpszMenuName)+1);
- if (hname)
- {
- newClass->wc.lpszMenuName = (char *)USER_HEAP_ADDR( hname );
- strcpy( newClass->wc.lpszMenuName, class->lpszMenuName );
- }
+ SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
+ return FALSE;
}
+ if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
+ (classPtr->hInstance != hInstance))
+ {
+ SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
+ return FALSE;
+ }
+ if (!(ret = CLASS_FreeClass( classPtr )))
+ SetLastError(ERROR_CLASS_HAS_WINDOWS);
+ return ret;
+}
- if (classExtra) memset( newClass->wExtra, 0, classExtra );
- firstClass = handle;
- return newClass->atomName;
+/***********************************************************************
+ * UnregisterClassW (USER32.564)
+ */
+BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
+{ CLASS *classPtr;
+ ATOM atom;
+ BOOL ret;
+
+ TRACE("%s %x\n",debugres_w(className), hInstance);
+
+ if (!(atom = GlobalFindAtomW( className )))
+ {
+ SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
+ return FALSE;
+ }
+ if (!(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
+ (classPtr->hInstance != hInstance))
+ {
+ SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
+ return FALSE;
+ }
+ if (!(ret = CLASS_FreeClass( classPtr )))
+ SetLastError(ERROR_CLASS_HAS_WINDOWS);
+ return ret;
+}
+
+/***********************************************************************
+ * GetClassWord16 (USER.129)
+ */
+WORD WINAPI GetClassWord16( HWND16 hwnd, INT16 offset )
+{
+ return GetClassWord( hwnd, offset );
}
/***********************************************************************
- * UnregisterClass (USER.403)
+ * GetClassWord (USER32.219)
*/
-BOOL UnregisterClass( LPSTR className, HANDLE instance )
+WORD WINAPI GetClassWord( HWND hwnd, INT offset )
{
- HANDLE class, prevClass;
- CLASS * classPtr, * prevClassPtr;
+ WND * wndPtr;
+ WORD retvalue = 0;
- /* Check if we can remove this class */
- class = CLASS_FindClassByName( className, &classPtr );
- if (!class) return FALSE;
- if ((classPtr->wc.hInstance != instance) || (classPtr->cWindows > 0))
- return FALSE;
+ TRACE("%x %x\n",hwnd, offset);
- /* Remove the class from the linked list */
- if (firstClass == class) firstClass = classPtr->hNext;
- else
- {
- for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
- {
- prevClassPtr = (CLASS *) USER_HEAP_ADDR(prevClass);
- if (prevClassPtr->hNext == class) break;
- }
- if (!prevClass)
- {
- fprintf(stderr, "ERROR: Class list corrupted\n" );
- return FALSE;
- }
- prevClassPtr->hNext = classPtr->hNext;
- }
-
- /* Delete the class */
- if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
- if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
- if (classPtr->wc.style & CS_GLOBALCLASS) GlobalDeleteAtom( classPtr->atomName );
- else DeleteAtom( classPtr->atomName );
- if ((int)classPtr->wc.lpszMenuName & 0xffff0000)
- USER_HEAP_FREE( (int)classPtr->wc.lpszMenuName & 0xffff );
- USER_HEAP_FREE( class );
- return TRUE;
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ if (offset >= 0)
+ {
+ if (offset <= wndPtr->class->cbClsExtra - sizeof(WORD))
+ {
+ retvalue = GET_WORD(((char *)wndPtr->class->wExtra) + offset);
+ goto END;
+ }
+ }
+ else switch(offset)
+ {
+ case GCW_HBRBACKGROUND: retvalue = wndPtr->class->hbrBackground;
+ goto END;
+ case GCW_HCURSOR: retvalue = wndPtr->class->hCursor;
+ goto END;
+ case GCW_HICON: retvalue = wndPtr->class->hIcon;
+ goto END;
+ case GCW_HICONSM: retvalue = wndPtr->class->hIconSm;
+ goto END;
+ case GCW_ATOM: retvalue = wndPtr->class->atomName;
+ goto END;
+ case GCW_STYLE:
+ case GCW_CBWNDEXTRA:
+ case GCW_CBCLSEXTRA:
+ case GCW_HMODULE:
+ retvalue = (WORD)GetClassLongA( hwnd, offset );
+ goto END;
+ }
+
+ WARN("Invalid offset %d\n", offset);
+ END:
+ WIN_ReleaseWndPtr(wndPtr);
+ return retvalue;
}
/***********************************************************************
- * GetClassWord (USER.129)
+ * GetClassLong16 (USER.131)
*/
-WORD GetClassWord( HWND hwnd, short offset )
+LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset )
{
- return (WORD)GetClassLong( hwnd, offset );
+ WND *wndPtr;
+ LONG ret;
+
+ TRACE("%x %x\n",hwnd, offset);
+
+ switch( offset )
+ {
+ case GCL_WNDPROC:
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
+ WIN_ReleaseWndPtr(wndPtr);
+ return ret;
+ case GCL_MENUNAME:
+ ret = GetClassLongA( hwnd, offset );
+ return (LONG)SEGPTR_GET( (void *)ret );
+ default:
+ return GetClassLongA( hwnd, offset );
+ }
}
/***********************************************************************
- * SetClassWord (USER.130)
+ * GetClassLongA (USER32.215)
*/
-WORD SetClassWord( HWND hwnd, short offset, WORD newval )
+LONG WINAPI GetClassLongA( HWND hwnd, INT offset )
{
- CLASS * classPtr;
WND * wndPtr;
- WORD *ptr, retval = 0;
+ LONG retvalue;
+
+ TRACE("%x %x\n",hwnd, offset);
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
- retval = *ptr;
- *ptr = newval;
- return retval;
+ if (offset >= 0)
+ {
+ if (offset <= wndPtr->class->cbClsExtra - sizeof(LONG))
+ {
+ retvalue = GET_DWORD(((char *)wndPtr->class->wExtra) + offset);
+ goto END;
+ }
+ }
+
+ switch(offset)
+ {
+ case GCL_STYLE: retvalue = (LONG)wndPtr->class->style;
+ goto END;
+ case GCL_CBWNDEXTRA: retvalue = (LONG)wndPtr->class->cbWndExtra;
+ goto END;
+ case GCL_CBCLSEXTRA: retvalue = (LONG)wndPtr->class->cbClsExtra;
+ goto END;
+ case GCL_HMODULE: retvalue = (LONG)wndPtr->class->hInstance;
+ goto END;
+ case GCL_WNDPROC:
+ retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
+ goto END;
+ case GCL_MENUNAME:
+ retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
+ goto END;
+ case GCW_ATOM:
+ case GCL_HBRBACKGROUND:
+ case GCL_HCURSOR:
+ case GCL_HICON:
+ case GCL_HICONSM:
+ retvalue = GetClassWord( hwnd, offset );
+ goto END;
+ }
+ WARN("Invalid offset %d\n", offset);
+ retvalue = 0;
+END:
+ WIN_ReleaseWndPtr(wndPtr);
+ return retvalue;
+}
+
+
+/***********************************************************************
+ * GetClassLongW (USER32.216)
+ */
+LONG WINAPI GetClassLongW( HWND hwnd, INT offset )
+{
+ WND * wndPtr;
+ LONG retvalue;
+
+ TRACE("%x %x\n",hwnd, offset);
+
+ switch(offset)
+ {
+ case GCL_WNDPROC:
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
+ WIN_ReleaseWndPtr(wndPtr);
+ return retvalue;
+ case GCL_MENUNAME:
+ if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
+ retvalue = (LONG)CLASS_GetMenuNameW( wndPtr->class );
+ WIN_ReleaseWndPtr(wndPtr);
+ return retvalue;
+ default:
+ return GetClassLongA( hwnd, offset );
+ }
}
/***********************************************************************
- * GetClassLong (USER.131)
+ * SetClassWord16 (USER.130)
*/
-LONG GetClassLong( HWND hwnd, short offset )
+WORD WINAPI SetClassWord16( HWND16 hwnd, INT16 offset, WORD newval )
+{
+ return SetClassWord( hwnd, offset, newval );
+}
+
+
+/***********************************************************************
+ * SetClassWord (USER32.469)
+ */
+WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval )
{
- CLASS * classPtr;
WND * wndPtr;
+ WORD retval = 0;
+ void *ptr;
+
+ TRACE("%x %x %x\n",hwnd, offset, newval);
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- return *(LONG *)(((char *)classPtr->wExtra) + offset);
+ if (offset >= 0)
+ {
+ if (offset + sizeof(WORD) <= wndPtr->class->cbClsExtra)
+ ptr = ((char *)wndPtr->class->wExtra) + offset;
+ else
+ {
+ WARN("Invalid offset %d\n", offset );
+ WIN_ReleaseWndPtr(wndPtr);
+ return 0;
+ }
+ }
+ else switch(offset)
+ {
+ case GCW_STYLE:
+ case GCW_CBWNDEXTRA:
+ case GCW_CBCLSEXTRA:
+ case GCW_HMODULE:
+ WIN_ReleaseWndPtr(wndPtr);
+ return (WORD)SetClassLongA( hwnd, offset, (LONG)newval );
+ case GCW_HBRBACKGROUND: ptr = &wndPtr->class->hbrBackground; break;
+ case GCW_HCURSOR: ptr = &wndPtr->class->hCursor; break;
+ case GCW_HICON: ptr = &wndPtr->class->hIcon; break;
+ case GCW_HICONSM: ptr = &wndPtr->class->hIconSm; break;
+ case GCW_ATOM: ptr = &wndPtr->class->atomName; break;
+ default:
+ WARN("Invalid offset %d\n", offset);
+ WIN_ReleaseWndPtr(wndPtr);
+ return 0;
+ }
+ retval = GET_WORD(ptr);
+ PUT_WORD( ptr, newval );
+
+ /* Note: If the GCW_ATOM was changed, this means that the WNDCLASS className fields
+ need to be updated as well. Problem is that we can't tell whether the atom is
+ using wide or narrow characters. For now, we'll just NULL out the className
+ fields, and emit a FIXME. */
+ if (offset == GCW_ATOM)
+ {
+ CLASS_SetClassNameA( wndPtr->class, NULL );
+ FIXME("GCW_ATOM changed for a class. Not updating className, so GetClassInfoEx may not return correct className!\n");
+ }
+ WIN_ReleaseWndPtr(wndPtr);
+ return retval;
}
/***********************************************************************
- * SetClassLong (USER.132)
+ * SetClassLong16 (USER.132)
*/
-LONG SetClassLong( HWND hwnd, short offset, LONG newval )
+LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval )
+{
+ WND *wndPtr;
+ LONG retval;
+
+ TRACE("%x %x %lx\n",hwnd, offset, newval);
+
+ switch(offset)
+ {
+ case GCL_WNDPROC:
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+ retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
+ WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
+ WIN_PROC_16, WIN_PROC_CLASS );
+ WIN_ReleaseWndPtr(wndPtr);
+ return retval;
+ case GCL_MENUNAME:
+ return SetClassLongA( hwnd, offset, (LONG)PTR_SEG_TO_LIN(newval) );
+ default:
+ return SetClassLongA( hwnd, offset, newval );
+ }
+}
+
+
+/***********************************************************************
+ * SetClassLongA (USER32.467)
+ */
+LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG newval )
{
- CLASS * classPtr;
WND * wndPtr;
- LONG *ptr, retval = 0;
+ LONG retval = 0;
+ void *ptr;
+ TRACE("%x %x %lx\n",hwnd, offset, newval);
+
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
- ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
- retval = *ptr;
- *ptr = newval;
+ if (offset >= 0)
+ {
+ if (offset + sizeof(LONG) <= wndPtr->class->cbClsExtra)
+ ptr = ((char *)wndPtr->class->wExtra) + offset;
+ else
+ {
+ WARN("Invalid offset %d\n", offset );
+ retval = 0;
+ goto END;
+ }
+ }
+ else switch(offset)
+ {
+ case GCL_MENUNAME:
+ CLASS_SetMenuNameA( wndPtr->class, (LPCSTR)newval );
+ retval = 0; /* Old value is now meaningless anyway */
+ goto END;
+ case GCL_WNDPROC:
+ retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc,
+ WIN_PROC_32A );
+ WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
+ WIN_PROC_32A, WIN_PROC_CLASS );
+ goto END;
+ case GCL_HBRBACKGROUND:
+ case GCL_HCURSOR:
+ case GCL_HICON:
+ case GCL_HICONSM:
+ retval = SetClassWord( hwnd, offset, (WORD)newval );
+ goto END;
+ case GCL_STYLE: ptr = &wndPtr->class->style; break;
+ case GCL_CBWNDEXTRA: ptr = &wndPtr->class->cbWndExtra; break;
+ case GCL_CBCLSEXTRA: ptr = &wndPtr->class->cbClsExtra; break;
+ case GCL_HMODULE: ptr = &wndPtr->class->hInstance; break;
+ default:
+ WARN("Invalid offset %d\n", offset );
+ retval = 0;
+ goto END;
+ }
+ retval = GET_DWORD(ptr);
+ PUT_DWORD( ptr, newval );
+END:
+ WIN_ReleaseWndPtr(wndPtr);
return retval;
}
/***********************************************************************
- * GetClassName (USER.58)
+ * SetClassLongW (USER32.468)
*/
-int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount)
+LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval )
{
WND *wndPtr;
- CLASS *classPtr;
+ LONG retval;
+ TRACE("%x %x %lx\n",hwnd, offset, newval);
+
+ switch(offset)
+ {
+ case GCL_WNDPROC:
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+ retval = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
+ WINPROC_SetProc( &wndPtr->class->winproc, (WNDPROC16)newval,
+ WIN_PROC_32W, WIN_PROC_CLASS );
+ WIN_ReleaseWndPtr(wndPtr);
+ return retval;
+ case GCL_MENUNAME:
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+ CLASS_SetMenuNameW( wndPtr->class, (LPCWSTR)newval );
+ WIN_ReleaseWndPtr(wndPtr);
+ return 0; /* Old value is now meaningless anyway */
+ default:
+ return SetClassLongA( hwnd, offset, newval );
+ }
+}
+
+
+/***********************************************************************
+ * GetClassName16 (USER.58)
+ */
+INT16 WINAPI GetClassName16( HWND16 hwnd, LPSTR buffer, INT16 count )
+{
+ return GetClassNameA( hwnd, buffer, count );
+}
+
+
+/***********************************************************************
+ * GetClassNameA (USER32.217)
+ */
+INT WINAPI GetClassNameA( HWND hwnd, LPSTR buffer, INT count )
+{ INT ret;
+ WND *wndPtr;
+
if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
- if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
+ ret = GlobalGetAtomNameA( wndPtr->class->atomName, buffer, count );
+
+ WIN_ReleaseWndPtr(wndPtr);
+ TRACE("%x %s %x\n",hwnd, buffer, count);
+ return ret;
+}
- return (GetAtomName(classPtr->atomName, lpClassName, maxCount));
+
+/***********************************************************************
+ * GetClassNameW (USER32.218)
+ */
+INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count )
+{ INT ret;
+ WND *wndPtr;
+
+ if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
+ ret = GlobalGetAtomNameW( wndPtr->class->atomName, buffer, count );
+ WIN_ReleaseWndPtr(wndPtr);
+ TRACE("%x %s %x\n",hwnd, debugstr_w(buffer), count);
+
+ return ret;
}
/***********************************************************************
- * GetClassInfo (USER.404)
+ * GetClassInfo16 (USER.404)
*/
-BOOL GetClassInfo(HANDLE hInstance, LPSTR lpClassName,
- LPWNDCLASS lpWndClass)
+BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, LPCSTR name, WNDCLASS16 *wc )
{
+ ATOM atom;
CLASS *classPtr;
- if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE;
- if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
+ TRACE("%x %s %p\n",hInstance, debugres_a(name), wc);
+
+ hInstance = GetExePtr( hInstance );
+ if (!(atom = GlobalFindAtomA( name )) ||
+ !(classPtr = CLASS_FindClassByAtom( atom, hInstance )))
+ return FALSE;
+ if ((hInstance != classPtr->hInstance) &&
+ !(classPtr->style & CS_GLOBALCLASS)) /*BWCC likes to pass hInstance=0*/
+ return FALSE;
+ wc->style = (UINT16)classPtr->style;
+ wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
+ wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
+ wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
+ wc->hInstance = (HINSTANCE16)classPtr->hInstance;
+ wc->hIcon = classPtr->hIcon;
+ wc->hCursor = classPtr->hCursor;
+ wc->hbrBackground = classPtr->hbrBackground;
+ wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );;
+ if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
+ wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
+ wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
+ if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
+ wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
+ return TRUE;
+}
+
- memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
+/***********************************************************************
+ * GetClassInfoA (USER32.211)
+ */
+BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name,
+ WNDCLASSA *wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ TRACE("%x %p %p\n",hInstance, name, wc);
+
+ /* workaround: if hInstance=NULL you expect to get the system classes
+ but this classes (as example from comctl32.dll SysListView) won't be
+ registered with hInstance=NULL in WINE because of the late loading
+ of this dll. fixes file dialogs in WinWord95 (jsch)*/
+
+ if (!(atom=GlobalFindAtomA(name)) || !(classPtr=CLASS_FindClassByAtom(atom,hInstance)))
+ return FALSE;
+
+ if (!(classPtr->style & CS_GLOBALCLASS) &&
+ classPtr->hInstance &&
+ (hInstance != classPtr->hInstance))
+ {
+ if (hInstance) return FALSE;
+ WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",name);
+ }
+
+ wc->style = classPtr->style;
+ wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
+ WIN_PROC_32A );
+ wc->cbClsExtra = classPtr->cbClsExtra;
+ wc->cbWndExtra = classPtr->cbWndExtra;
+ wc->hInstance = hInstance;
+ wc->hIcon = (HICON)classPtr->hIcon;
+ wc->hCursor = (HCURSOR)classPtr->hCursor;
+ wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
+ wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
+ wc->lpszClassName = CLASS_GetClassNameA( classPtr );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * GetClassInfoW (USER32.214)
+ */
+BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name,
+ WNDCLASSW *wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ TRACE("%x %p %p\n",hInstance, name, wc);
+
+ if ( !(atom=GlobalFindAtomW(name)) ||
+ !(classPtr=CLASS_FindClassByAtom(atom,hInstance))
+ )
+ return FALSE;
+
+ if (!(classPtr->style & CS_GLOBALCLASS) &&
+ classPtr->hInstance &&
+ (hInstance != classPtr->hInstance))
+ {
+ if (hInstance) return FALSE;
+ WARN("systemclass %s (hInst=0) demanded but only class with hInst!=0 found\n",debugstr_w(name));
+ }
+ wc->style = classPtr->style;
+ wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
+ WIN_PROC_32W );
+ wc->cbClsExtra = classPtr->cbClsExtra;
+ wc->cbWndExtra = classPtr->cbWndExtra;
+ wc->hInstance = hInstance;
+ wc->hIcon = (HICON)classPtr->hIcon;
+ wc->hCursor = (HCURSOR)classPtr->hCursor;
+ wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
+ wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
+ wc->lpszClassName = CLASS_GetClassNameW( classPtr );
+ return TRUE;
+}
+
+
+/***********************************************************************
+ * GetClassInfoEx16 (USER.398)
+ *
+ * FIXME: this is just a guess, I have no idea if GetClassInfoEx() is the
+ * same in Win16 as in Win32. --AJ
+ */
+BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, LPCSTR name, WNDCLASSEX16 *wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ TRACE("%x %s %p\n",hInstance,debugres_a( name ), wc);
+
+ hInstance = GetExePtr( hInstance );
+ if (!(atom = GlobalFindAtomA( name )) ||
+ !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
+ (hInstance != classPtr->hInstance)) return FALSE;
+ wc->style = classPtr->style;
+ wc->lpfnWndProc = WINPROC_GetProc( classPtr->winproc, WIN_PROC_16 );
+ wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
+ wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
+ wc->hInstance = (HINSTANCE16)classPtr->hInstance;
+ wc->hIcon = classPtr->hIcon;
+ wc->hIconSm = classPtr->hIconSm;
+ wc->hCursor = classPtr->hCursor;
+ wc->hbrBackground = classPtr->hbrBackground;
+ wc->lpszClassName = (SEGPTR)0;
+ wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
+ if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
+ wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
+ wc->lpszClassName = (SEGPTR)CLASS_GetClassNameA( classPtr );
+ if (HIWORD(wc->lpszClassName)) /* Make it a SEGPTR */
+ wc->lpszClassName = SEGPTR_GET( (LPSTR)wc->lpszClassName );
+
+ /* We must return the atom of the class here instead of just TRUE. */
+ return atom;
+}
+
+
+/***********************************************************************
+ * GetClassInfoExA (USER32.212)
+ */
+BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name,
+ WNDCLASSEXA *wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ TRACE("%x %p %p\n",hInstance, name, wc);
+
+ if (!(atom = GlobalFindAtomA( name )) ||
+ !(classPtr = CLASS_FindClassByAtom( atom, hInstance ))
+ /*|| (hInstance != classPtr->hInstance) */ ) return FALSE;
+ wc->style = classPtr->style;
+ wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
+ WIN_PROC_32A );
+ wc->cbClsExtra = classPtr->cbClsExtra;
+ wc->cbWndExtra = classPtr->cbWndExtra;
+ wc->hInstance = classPtr->hInstance;
+ wc->hIcon = (HICON)classPtr->hIcon;
+ wc->hIconSm = (HICON)classPtr->hIconSm;
+ wc->hCursor = (HCURSOR)classPtr->hCursor;
+ wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
+ wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
+ wc->lpszClassName = CLASS_GetClassNameA( classPtr );
+
+ /* We must return the atom of the class here instead of just TRUE. */
+ return atom;
+}
+
+
+/***********************************************************************
+ * GetClassInfoExW (USER32.213)
+ */
+BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name,
+ WNDCLASSEXW *wc )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ TRACE("%x %p %p\n",hInstance, name, wc);
+
+ if (!(atom = GlobalFindAtomW( name )) ||
+ !(classPtr = CLASS_FindClassByAtom( atom, hInstance )) ||
+ (hInstance != classPtr->hInstance)) return FALSE;
+ wc->style = classPtr->style;
+ wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
+ WIN_PROC_32W );
+ wc->cbClsExtra = classPtr->cbClsExtra;
+ wc->cbWndExtra = classPtr->cbWndExtra;
+ wc->hInstance = classPtr->hInstance;
+ wc->hIcon = (HICON)classPtr->hIcon;
+ wc->hIconSm = (HICON)classPtr->hIconSm;
+ wc->hCursor = (HCURSOR)classPtr->hCursor;
+ wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
+ wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
+ wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
+
+ /* We must return the atom of the class here instead of just TRUE. */
+ return atom;
+}
+
+
+/***********************************************************************
+ * ClassFirst (TOOLHELP.69)
+ */
+BOOL16 WINAPI ClassFirst16( CLASSENTRY *pClassEntry )
+{
+ TRACE("%p\n",pClassEntry);
+ pClassEntry->wNext = 1;
+ return ClassNext16( pClassEntry );
+}
+
+
+/***********************************************************************
+ * ClassNext (TOOLHELP.70)
+ */
+BOOL16 WINAPI ClassNext16( CLASSENTRY *pClassEntry )
+{
+ int i;
+ CLASS *class = firstClass;
+
+ TRACE("%p\n",pClassEntry);
+
+ if (!pClassEntry->wNext) return FALSE;
+ for (i = 1; (i < pClassEntry->wNext) && class; i++) class = class->next;
+ if (!class)
+ {
+ pClassEntry->wNext = 0;
+ return FALSE;
+ }
+ pClassEntry->hInst = class->hInstance;
+ pClassEntry->wNext++;
+ GlobalGetAtomNameA( class->atomName, pClassEntry->szClassName,
+ sizeof(pClassEntry->szClassName) );
return TRUE;
}