Removed dependencies on the internals of the CLASS structure.
Added support for having both ASCII and Unicode window procedures for
builtin classes.
diff --git a/windows/class.c b/windows/class.c
index c4c467e..dc6c2d9 100644
--- a/windows/class.c
+++ b/windows/class.c
@@ -20,7 +20,6 @@
#include "wingdi.h"
#include "wine/winuser16.h"
#include "wine/unicode.h"
-#include "class.h"
#include "heap.h"
#include "win.h"
#include "dce.h"
@@ -31,65 +30,85 @@
DEFAULT_DEBUG_CHANNEL(class);
+typedef struct tagCLASS
+{
+ struct tagCLASS *next; /* Next class */
+ struct tagCLASS *prev; /* Prev class */
+ UINT cWindows; /* Count of existing windows */
+ UINT style; /* Class style */
+ HWINDOWPROC winprocA; /* Window procedure (ASCII) */
+ HWINDOWPROC winprocW; /* Window procedure (Unicode) */
+ INT cbClsExtra; /* Class extra bytes */
+ INT cbWndExtra; /* Window extra bytes */
+ LPWSTR menuName; /* Default menu name (Unicode followed by ASCII) */
+ struct tagDCE *dce; /* Class DCE (if CS_CLASSDC) */
+ HINSTANCE hInstance; /* Module that created the task */
+ HICON hIcon; /* Default icon */
+ HICON hIconSm; /* Default small icon */
+ HCURSOR hCursor; /* Default cursor */
+ HBRUSH hbrBackground; /* Default background */
+ ATOM atomName; /* Name of the class */
+ LONG wExtra[1]; /* Class extra bytes */
+} CLASS;
-static CLASS *firstClass = NULL;
+static CLASS *firstClass;
/***********************************************************************
- * CLASS_DumpClass
+ * CLASS_GetProc
*
- * Dump the content of a class structure to stderr.
+ * Get the class winproc for a given proc type
*/
-void CLASS_DumpClass( CLASS *ptr )
+static WNDPROC16 CLASS_GetProc( CLASS *classPtr, WINDOWPROCTYPE type )
{
- char className[MAX_CLASSNAME+1];
- int i;
+ HWINDOWPROC proc = classPtr->winprocA;
- if (ptr->magic != CLASS_MAGIC)
+ if (classPtr->winprocW)
{
- DPRINTF("%p is not a class\n", ptr );
- return;
+ /* if we have a Unicode proc, use it if we have no ASCII proc
+ * or if we have both and Unicode was requested
+ */
+ if (!proc || type == WIN_PROC_32W) proc = classPtr->winprocW;
}
-
- 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" );
+ return WINPROC_GetProc( proc, type );
}
/***********************************************************************
- * CLASS_WalkClasses
+ * CLASS_SetProc
*
- * Walk the class list and print each class on stderr.
+ * Set the class winproc for a given proc type.
+ * Returns the previous window proc.
*/
-void CLASS_WalkClasses(void)
+static WNDPROC16 CLASS_SetProc( CLASS *classPtr, WNDPROC newproc, WINDOWPROCTYPE type )
{
- CLASS *ptr;
- char className[MAX_CLASSNAME+1];
+ HWINDOWPROC *proc = &classPtr->winprocA;
+ WNDPROC16 ret;
- DPRINTF( " Class Name Style WndProc\n" );
- for (ptr = firstClass; ptr; ptr = ptr->next)
+ if (classPtr->winprocW)
{
- GlobalGetAtomNameA( ptr->atomName, className, sizeof(className) );
- DPRINTF( "%08x %-20.20s %08x %08x\n", (UINT)ptr, className,
- ptr->style, (UINT)ptr->winproc );
+ /* if we have a Unicode proc, use it if we have no ASCII proc
+ * or if we have both and Unicode was requested
+ */
+ if (!*proc || type == WIN_PROC_32W) proc = &classPtr->winprocW;
}
- DPRINTF( "\n" );
+ ret = WINPROC_GetProc( *proc, type );
+ WINPROC_SetProc( proc, (HWINDOWPROC)newproc, type, WIN_PROC_CLASS );
+ /* now free the one that we didn't set */
+ if (classPtr->winprocA && classPtr->winprocW)
+ {
+ if (proc == &classPtr->winprocA)
+ {
+ WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS );
+ classPtr->winprocW = 0;
+ }
+ else
+ {
+ WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS );
+ classPtr->winprocA = 0;
+ }
+ }
+ return ret;
}
@@ -98,14 +117,10 @@
*
* Get the menu name as a ASCII string.
*/
-static LPSTR CLASS_GetMenuNameA( CLASS *classPtr )
+inline 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;
+ if (!HIWORD(classPtr->menuName)) return (LPSTR)classPtr->menuName;
+ return (LPSTR)(classPtr->menuName + strlenW(classPtr->menuName) + 1);
}
@@ -114,17 +129,9 @@
*
* Get the menu name as a Unicode string.
*/
-static LPWSTR CLASS_GetMenuNameW( CLASS *classPtr )
+inline 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;
+ return classPtr->menuName;
}
@@ -135,10 +142,16 @@
*/
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;
+ if (HIWORD(classPtr->menuName)) SEGPTR_FREE( classPtr->menuName );
+ if (HIWORD(name))
+ {
+ DWORD lenA = strlen(name) + 1;
+ DWORD lenW = MultiByteToWideChar( CP_ACP, 0, name, lenA, NULL, 0 );
+ classPtr->menuName = SEGPTR_ALLOC( lenA + lenW*sizeof(WCHAR) );
+ MultiByteToWideChar( CP_ACP, 0, name, lenA, classPtr->menuName, lenW );
+ memcpy( classPtr->menuName + lenW, name, lenA );
+ }
+ else classPtr->menuName = (LPWSTR)name;
}
@@ -149,86 +162,17 @@
*/
static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
{
- if (!HIWORD(name))
+ if (HIWORD(classPtr->menuName)) SEGPTR_FREE( classPtr->menuName );
+ if (HIWORD(name))
{
- CLASS_SetMenuNameA( classPtr, (LPCSTR)name );
- return;
+ DWORD lenW = strlenW(name) + 1;
+ DWORD lenA = WideCharToMultiByte( CP_ACP, 0, name, lenW, NULL, 0, NULL, NULL );
+ classPtr->menuName = SEGPTR_ALLOC( lenA + lenW*sizeof(WCHAR) );
+ memcpy( classPtr->menuName, name, lenW*sizeof(WCHAR) );
+ WideCharToMultiByte( CP_ACP, 0, name, lenW,
+ (char *)(classPtr->menuName + lenW), lenA, NULL, NULL );
}
- 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;
-}
-
-
-/***********************************************************************
- * CLASS_GetClassNameW
- *
- * Get the class name as a Unicode string.
- */
-static LPWSTR CLASS_GetClassNameW( CLASS *classPtr )
-{
- if (!classPtr->classNameW && classPtr->classNameA)
- {
- 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;
+ else classPtr->menuName = (LPWSTR)name;
}
@@ -239,23 +183,21 @@
*/
static BOOL CLASS_FreeClass( CLASS *classPtr )
{
- CLASS **ppClass;
- TRACE("%p\n", classPtr);
+ TRACE("%p\n", classPtr);
/* Check if we can remove this class */
- if (classPtr->cWindows > 0) return FALSE;
+ if (classPtr->cWindows > 0)
+ {
+ SetLastError( ERROR_CLASS_HAS_WINDOWS );
+ 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;
+ if (classPtr->next) classPtr->next->prev = classPtr->prev;
+ if (classPtr->prev) classPtr->prev->next = classPtr->next;
+ else firstClass = classPtr->next;
/* Delete the class */
@@ -263,10 +205,10 @@
if (classPtr->hbrBackground > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1))
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 );
+ WINPROC_FreeProc( classPtr->winprocA, WIN_PROC_CLASS );
+ WINPROC_FreeProc( classPtr->winprocW, WIN_PROC_CLASS );
+ HeapFree( GetProcessHeap(), 0, classPtr->menuName );
+ HeapFree( GetProcessHeap(), 0, classPtr );
return TRUE;
}
@@ -298,8 +240,9 @@
* 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;
+static CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance )
+{
+ CLASS * class, *tclass=0;
TRACE("0x%08x 0x%08x\n", atom, hinstance);
@@ -349,14 +292,12 @@
* The real RegisterClass() functionality.
*/
static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance,
- DWORD style, INT classExtra,
- INT winExtra, WNDPROC16 wndProc,
- WINDOWPROCTYPE wndProcType )
+ DWORD style, INT classExtra, INT winExtra )
{
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);
+ TRACE("atom=0x%x hinst=0x%x style=0x%lx clExtr=0x%x winExtr=0x%x\n",
+ atom, hInstance, style, classExtra, winExtra );
/* Check if a class with this name already exists */
classPtr = CLASS_FindClassByAtom( atom, hInstance );
@@ -365,8 +306,11 @@
/* 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;
+ if ((style & CS_GLOBALCLASS) || !(classPtr->style & CS_GLOBALCLASS))
+ {
+ SetLastError( ERROR_CLASS_ALREADY_EXISTS );
+ return NULL;
+ }
}
/* Fix the extra bytes value */
@@ -380,36 +324,97 @@
/* Create the class */
- classPtr = (CLASS *)HeapAlloc( SystemHeap, 0, sizeof(CLASS) +
- classExtra - sizeof(classPtr->wExtra) );
+ classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
+ 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;
+ classPtr->dce = (style & CS_CLASSDC) ? DCE_AllocDCE( 0, DCE_CLASS_DC ) : NULL;
- WINPROC_SetProc( &classPtr->winproc, wndProc, wndProcType, WIN_PROC_CLASS);
+ /* Other non-null values must be set by caller */
- /* Other values must be set by caller */
-
- if (classExtra) memset( classPtr->wExtra, 0, classExtra );
+ if ((classPtr->next = firstClass)) firstClass->prev = classPtr;
firstClass = classPtr;
return classPtr;
}
/***********************************************************************
+ * CLASS_RegisterBuiltinClass
+ *
+ * Register a builtin control class.
+ * This allows having both ASCII and Unicode winprocs for the same class.
+ */
+ATOM CLASS_RegisterBuiltinClass( LPCSTR name, DWORD style, INT winExtra, LPCSTR cursor,
+ HBRUSH brush, WNDPROC wndProcA, WNDPROC wndProcW )
+{
+ ATOM atom;
+ CLASS *classPtr;
+
+ if (!(atom = GlobalAddAtomA( name ))) return 0;
+
+ if (!(classPtr = CLASS_RegisterClass( atom, 0, style, 0, winExtra )))
+ {
+ GlobalDeleteAtom( atom );
+ return 0;
+ }
+
+ classPtr->hCursor = LoadCursorA( 0, cursor );
+ classPtr->hbrBackground = brush;
+
+ if (wndProcA) WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wndProcA,
+ WIN_PROC_32A, WIN_PROC_CLASS );
+ if (wndProcW) WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)wndProcW,
+ WIN_PROC_32W, WIN_PROC_CLASS );
+ return atom;
+}
+
+
+/***********************************************************************
+ * CLASS_AddWindow
+ *
+ * Add a new window using this class, and return the necessary
+ * information for creating the window.
+ */
+CLASS *CLASS_AddWindow( ATOM atom, HINSTANCE inst, WINDOWPROCTYPE type,
+ INT *winExtra, WNDPROC *winproc, DWORD *style, struct tagDCE **dce )
+{
+ CLASS *class;
+ if (type == WIN_PROC_16) inst = GetExePtr(inst);
+
+ if (!(class = CLASS_FindClassByAtom( atom, inst ))) return NULL;
+ class->cWindows++;
+
+ if (type == WIN_PROC_32W)
+ {
+ if (!(*winproc = class->winprocW)) *winproc = class->winprocA;
+ }
+ else
+ {
+ if (!(*winproc = class->winprocA)) *winproc = class->winprocW;
+ }
+ *winExtra = class->cbWndExtra;
+ *style = class->style;
+ *dce = class->dce;
+ return class;
+}
+
+
+/***********************************************************************
+ * CLASS_RemoveWindow
+ *
+ * Remove a window from the class window count.
+ */
+void CLASS_RemoveWindow( CLASS *cls )
+{
+ if (cls && cls->cWindows) cls->cWindows--;
+}
+
+
+/***********************************************************************
* RegisterClass16 (USER.57)
*/
ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc )
@@ -421,8 +426,7 @@
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 )))
+ wc->cbClsExtra, wc->cbWndExtra )))
{
GlobalDeleteAtom( atom );
return 0;
@@ -446,10 +450,9 @@
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 );
+ WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
+ WIN_PROC_16, WIN_PROC_CLASS );
+ CLASS_SetMenuNameA( classPtr, PTR_SEG_TO_LIN(wc->lpszMenuName) );
return atom;
}
@@ -470,12 +473,10 @@
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;
+ wc->cbClsExtra, wc->cbWndExtra )))
+ {
+ GlobalDeleteAtom( atom );
+ return 0;
}
TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p name='%s'\n",
@@ -493,9 +494,10 @@
LR_COPYFROMRESOURCE);
classPtr->hCursor = (HCURSOR16)wc->hCursor;
classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
-
+
+ WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
+ WIN_PROC_32A, WIN_PROC_CLASS );
CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
- CLASS_SetClassNameA( classPtr, wc->lpszClassName );
return atom;
}
@@ -512,11 +514,8 @@
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 )))
+ wc->cbClsExtra, wc->cbWndExtra )))
{
- SetLastError(ERROR_CLASS_ALREADY_EXISTS);
GlobalDeleteAtom( atom );
return 0;
}
@@ -535,9 +534,10 @@
LR_COPYFROMRESOURCE);
classPtr->hCursor = (HCURSOR16)wc->hCursor;
classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
-
+
+ WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)wc->lpfnWndProc,
+ WIN_PROC_32W, WIN_PROC_CLASS );
CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
- CLASS_SetClassNameW( classPtr, wc->lpszClassName );
return atom;
}
@@ -553,8 +553,7 @@
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 )))
+ wc->cbClsExtra, wc->cbWndExtra )))
{
GlobalDeleteAtom( atom );
return 0;
@@ -570,10 +569,9 @@
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 );
+ WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
+ WIN_PROC_16, WIN_PROC_CLASS );
+ CLASS_SetMenuNameA( classPtr, PTR_SEG_TO_LIN(wc->lpszMenuName) );
return atom;
}
@@ -589,13 +587,10 @@
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 )))
+ wc->cbClsExtra, wc->cbWndExtra )))
{
- SetLastError(ERROR_CLASS_ALREADY_EXISTS);
GlobalDeleteAtom( atom );
- return FALSE;
+ return 0;
}
TRACE("atom=%04x wndproc=%08lx hinst=%04x bg=%04x style=%08x clsExt=%d winExt=%d class=%p\n",
@@ -607,8 +602,9 @@
classPtr->hIconSm = (HICON16)wc->hIconSm;
classPtr->hCursor = (HCURSOR16)wc->hCursor;
classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
+ WINPROC_SetProc( &classPtr->winprocA, (HWINDOWPROC)wc->lpfnWndProc,
+ WIN_PROC_32A, WIN_PROC_CLASS );
CLASS_SetMenuNameA( classPtr, wc->lpszMenuName );
- CLASS_SetClassNameA( classPtr, wc->lpszClassName );
return atom;
}
@@ -624,11 +620,8 @@
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 )))
+ wc->cbClsExtra, wc->cbWndExtra )))
{
- SetLastError(ERROR_CLASS_ALREADY_EXISTS);
GlobalDeleteAtom( atom );
return 0;
}
@@ -642,8 +635,9 @@
classPtr->hIconSm = (HICON16)wc->hIconSm;
classPtr->hCursor = (HCURSOR16)wc->hCursor;
classPtr->hbrBackground = (HBRUSH16)wc->hbrBackground;
+ WINPROC_SetProc( &classPtr->winprocW, (HWINDOWPROC)wc->lpfnWndProc,
+ WIN_PROC_32W, WIN_PROC_CLASS );
CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
- CLASS_SetClassNameW( classPtr, wc->lpszClassName );
return atom;
}
@@ -662,9 +656,9 @@
*
*/
BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
-{ CLASS *classPtr;
+{
+ CLASS *classPtr;
ATOM atom;
- BOOL ret;
TRACE("%s %x\n",debugres_a(className), hInstance);
@@ -679,18 +673,16 @@
SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
return FALSE;
}
- if (!(ret = CLASS_FreeClass( classPtr )))
- SetLastError(ERROR_CLASS_HAS_WINDOWS);
- return ret;
+ return CLASS_FreeClass( classPtr );
}
/***********************************************************************
* UnregisterClassW (USER32.564)
*/
BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
-{ CLASS *classPtr;
+{
+ CLASS *classPtr;
ATOM atom;
- BOOL ret;
TRACE("%s %x\n",debugres_w(className), hInstance);
@@ -705,9 +697,7 @@
SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
return FALSE;
}
- if (!(ret = CLASS_FreeClass( classPtr )))
- SetLastError(ERROR_CLASS_HAS_WINDOWS);
- return ret;
+ return CLASS_FreeClass( classPtr );
}
/***********************************************************************
@@ -779,7 +769,7 @@
{
case GCL_WNDPROC:
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- ret = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_16 );
+ ret = (LONG)CLASS_GetProc( wndPtr->class, WIN_PROC_16 );
WIN_ReleaseWndPtr(wndPtr);
return ret;
case GCL_MENUNAME:
@@ -822,7 +812,7 @@
case GCL_HMODULE: retvalue = (LONG)wndPtr->class->hInstance;
goto END;
case GCL_WNDPROC:
- retvalue = (LONG)WINPROC_GetProc(wndPtr->class->winproc, WIN_PROC_32A);
+ retvalue = (LONG)CLASS_GetProc( wndPtr->class, WIN_PROC_32A );
goto END;
case GCL_MENUNAME:
retvalue = (LONG)CLASS_GetMenuNameA( wndPtr->class );
@@ -857,7 +847,7 @@
{
case GCL_WNDPROC:
if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
- retvalue = (LONG)WINPROC_GetProc( wndPtr->class->winproc, WIN_PROC_32W );
+ retvalue = (LONG)CLASS_GetProc( wndPtr->class, WIN_PROC_32W );
WIN_ReleaseWndPtr(wndPtr);
return retvalue;
case GCL_MENUNAME:
@@ -923,16 +913,6 @@
}
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;
}
@@ -952,9 +932,7 @@
{
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 );
+ retval = (LONG)CLASS_SetProc( wndPtr->class, (WNDPROC)newval, WIN_PROC_16 );
WIN_ReleaseWndPtr(wndPtr);
return retval;
case GCL_MENUNAME:
@@ -995,10 +973,7 @@
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 );
+ retval = (LONG)CLASS_SetProc( wndPtr->class, (WNDPROC)newval, WIN_PROC_32A );
goto END;
case GCL_HBRBACKGROUND:
case GCL_HCURSOR:
@@ -1037,9 +1012,7 @@
{
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 );
+ retval = (LONG)CLASS_SetProc( wndPtr->class, (WNDPROC)newval, WIN_PROC_32W );
WIN_ReleaseWndPtr(wndPtr);
return retval;
case GCL_MENUNAME:
@@ -1097,31 +1070,29 @@
/***********************************************************************
* GetClassInfo16 (USER.404)
*/
-BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, LPCSTR name, WNDCLASS16 *wc )
+BOOL16 WINAPI GetClassInfo16( HINSTANCE16 hInstance, SEGPTR name, WNDCLASS16 *wc )
{
ATOM atom;
CLASS *classPtr;
- TRACE("%x %s %p\n",hInstance, debugres_a(name), wc);
-
+ TRACE("%x %s %p\n",hInstance, debugres_a(PTR_SEG_TO_LIN(name)), wc);
+
hInstance = GetExePtr( hInstance );
- if (!(atom = GlobalFindAtomA( name )) ||
+ if (!(atom = GlobalFindAtomA( PTR_SEG_TO_LIN(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->lpfnWndProc = CLASS_GetProc( classPtr, 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->lpszClassName = name;
wc->lpszMenuName = (SEGPTR)CLASS_GetMenuNameA( classPtr );
if (HIWORD(wc->lpszMenuName)) /* Make it a SEGPTR */
wc->lpszMenuName = SEGPTR_GET( (LPSTR)wc->lpszMenuName );
@@ -1157,8 +1128,7 @@
}
wc->style = classPtr->style;
- wc->lpfnWndProc = (WNDPROC)WINPROC_GetProc( classPtr->winproc,
- WIN_PROC_32A );
+ wc->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
wc->cbClsExtra = classPtr->cbClsExtra;
wc->cbWndExtra = classPtr->cbWndExtra;
wc->hInstance = hInstance;
@@ -1166,7 +1136,7 @@
wc->hCursor = (HCURSOR)classPtr->hCursor;
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
- wc->lpszClassName = CLASS_GetClassNameA( classPtr );
+ wc->lpszClassName = name;
return TRUE;
}
@@ -1195,8 +1165,7 @@
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->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
wc->cbClsExtra = classPtr->cbClsExtra;
wc->cbWndExtra = classPtr->cbWndExtra;
wc->hInstance = hInstance;
@@ -1204,7 +1173,7 @@
wc->hCursor = (HCURSOR)classPtr->hCursor;
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
- wc->lpszClassName = CLASS_GetClassNameW( classPtr );
+ wc->lpszClassName = name;
return TRUE;
}
@@ -1215,19 +1184,19 @@
* 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 )
+BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, SEGPTR name, WNDCLASSEX16 *wc )
{
ATOM atom;
CLASS *classPtr;
- TRACE("%x %s %p\n",hInstance,debugres_a( name ), wc);
-
+ TRACE("%x %s %p\n",hInstance,debugres_a( PTR_SEG_TO_LIN(name) ), wc);
+
hInstance = GetExePtr( hInstance );
- if (!(atom = GlobalFindAtomA( name )) ||
+ if (!(atom = GlobalFindAtomA( PTR_SEG_TO_LIN(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->lpfnWndProc = CLASS_GetProc( classPtr, WIN_PROC_16 );
wc->cbClsExtra = (INT16)classPtr->cbClsExtra;
wc->cbWndExtra = (INT16)classPtr->cbWndExtra;
wc->hInstance = (HINSTANCE16)classPtr->hInstance;
@@ -1239,9 +1208,7 @@
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 );
+ wc->lpszClassName = name;
/* We must return the atom of the class here instead of just TRUE. */
return atom;
@@ -1263,8 +1230,7 @@
!(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->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A );
wc->cbClsExtra = classPtr->cbClsExtra;
wc->cbWndExtra = classPtr->cbWndExtra;
wc->hInstance = classPtr->hInstance;
@@ -1273,8 +1239,8 @@
wc->hCursor = (HCURSOR)classPtr->hCursor;
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
wc->lpszMenuName = CLASS_GetMenuNameA( classPtr );
- wc->lpszClassName = CLASS_GetClassNameA( classPtr );
-
+ wc->lpszClassName = name;
+
/* We must return the atom of the class here instead of just TRUE. */
return atom;
}
@@ -1295,8 +1261,7 @@
!(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->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W );
wc->cbClsExtra = classPtr->cbClsExtra;
wc->cbWndExtra = classPtr->cbWndExtra;
wc->hInstance = classPtr->hInstance;
@@ -1305,8 +1270,8 @@
wc->hCursor = (HCURSOR)classPtr->hCursor;
wc->hbrBackground = (HBRUSH)classPtr->hbrBackground;
wc->lpszMenuName = CLASS_GetMenuNameW( classPtr );
- wc->lpszClassName = CLASS_GetClassNameW( classPtr );;
-
+ wc->lpszClassName = name;
+
/* We must return the atom of the class here instead of just TRUE. */
return atom;
}