From 9877906b267c76b4ae068a0deaaa6e84d6f4d2a1 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 7 Dec 2000 23:39:16 +0000 Subject: [PATCH] Removed dependencies on the internals of the CLASS structure. Added support for having both ASCII and Unicode window procedures for builtin classes. --- controls/button.c | 38 ++- controls/desktop.c | 6 +- controls/widgets.c | 171 ++++--------- dlls/ttydrv/ttydrv.h | 4 +- dlls/ttydrv/wnd.c | 11 +- dlls/user/user.spec | 4 +- include/button.h | 4 +- include/class.h | 45 ---- include/win.h | 39 ++- include/wine/winuser16.h | 4 +- include/x11drv.h | 4 +- windows/class.c | 523 ++++++++++++++++++--------------------- windows/dce.c | 9 +- windows/defwnd.c | 18 +- windows/mdi.c | 7 +- windows/user.c | 1 - windows/win.c | 76 +++--- windows/x11drv/wnd.c | 16 +- 18 files changed, 413 insertions(+), 567 deletions(-) delete mode 100644 include/class.h diff --git a/controls/button.c b/controls/button.c index 9a8ee6d80b3..1250bdf75e8 100644 --- a/controls/button.c +++ b/controls/button.c @@ -79,7 +79,7 @@ static WORD checkBoxWidth = 0, checkBoxHeight = 0; * Called with window lock held. */ static inline LRESULT WINAPI ButtonWndProc_locked(WND* wndPtr, UINT uMsg, - WPARAM wParam, LPARAM lParam ) + WPARAM wParam, LPARAM lParam, BOOL unicode ) { RECT rect; HWND hWnd = wndPtr->hwndSelf; @@ -215,12 +215,9 @@ static inline LRESULT WINAPI ButtonWndProc_locked(WND* wndPtr, UINT uMsg, } break; - case WM_NCHITTEST: - if(style == BS_GROUPBOX) return HTTRANSPARENT; - return DefWindowProcW( hWnd, uMsg, wParam, lParam ); - case WM_SETTEXT: - DEFWND_SetTextW( wndPtr, (LPCWSTR)lParam ); + if (unicode) DEFWND_SetTextW( wndPtr, (LPCWSTR)lParam ); + else DEFWND_SetTextA( wndPtr, (LPCSTR)lParam ); if( wndPtr->dwStyle & WS_VISIBLE ) PAINT_BUTTON( wndPtr, style, ODA_DRAWENTIRE ); return 1; /* success. FIXME: check text length */ @@ -352,30 +349,49 @@ static inline LRESULT WINAPI ButtonWndProc_locked(WND* wndPtr, UINT uMsg, PAINT_BUTTON( wndPtr, style, ODA_SELECT ); break; + case WM_NCHITTEST: + if(style == BS_GROUPBOX) return HTTRANSPARENT; + /* fall through */ default: - return DefWindowProcW(hWnd, uMsg, wParam, lParam); + return unicode ? DefWindowProcW(hWnd, uMsg, wParam, lParam) : + DefWindowProcA(hWnd, uMsg, wParam, lParam); } return 0; } /*********************************************************************** - * ButtonWndProc + * ButtonWndProcW * The button window procedure. This is just a wrapper which locks * the passed HWND and calls the real window procedure (with a WND* * pointer pointing to the locked windowstructure). */ -LRESULT WINAPI ButtonWndProc( HWND hWnd, UINT uMsg, - WPARAM wParam, LPARAM lParam ) +LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { LRESULT res; WND *wndPtr = WIN_FindWndPtr(hWnd); - res = ButtonWndProc_locked(wndPtr,uMsg,wParam,lParam); + res = ButtonWndProc_locked(wndPtr,uMsg,wParam,lParam,TRUE); WIN_ReleaseWndPtr(wndPtr); return res; } + +/*********************************************************************** + * ButtonWndProcA + */ +LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) +{ + LRESULT res; + WND *wndPtr = WIN_FindWndPtr(hWnd); + + res = ButtonWndProc_locked(wndPtr,uMsg,wParam,lParam,FALSE); + + WIN_ReleaseWndPtr(wndPtr); + return res; +} + + /********************************************************************** * Push Button Functions */ diff --git a/controls/desktop.c b/controls/desktop.c index 72e41de4a51..a1b70c1c363 100644 --- a/controls/desktop.c +++ b/controls/desktop.c @@ -96,10 +96,12 @@ static LRESULT DESKTOP_DoEraseBkgnd( HWND hwnd, HDC hdc, (!desktopPtr->fTileWallPaper && ((desktopPtr->bitmapSize.cx < rect.right) || (desktopPtr->bitmapSize.cy < rect.bottom)))) { + HBRUSH brush = desktopPtr->hbrushPattern; + if (!brush) brush = GetClassLongA( hwnd, GCL_HBRBACKGROUND ); /* Set colors in case pattern is a monochrome bitmap */ SetBkColor( hdc, RGB(0,0,0) ); SetTextColor( hdc, GetSysColor(COLOR_BACKGROUND) ); - FillRect( hdc, &rect, desktopPtr->hbrushPattern ); + FillRect( hdc, &rect, brush ); } /* Paint wall paper */ @@ -289,7 +291,7 @@ BOOL DESKTOP_SetPattern( LPCSTR pattern ) desktopPtr->hbrushPattern = CreatePatternBrush( hbitmap ); DeleteObject( hbitmap ); } - else desktopPtr->hbrushPattern = CreateSolidBrush( GetSysColor(COLOR_BACKGROUND) ); + else desktopPtr->hbrushPattern = 0; WIN_ReleaseDesktop(); return TRUE; } diff --git a/controls/widgets.c b/controls/widgets.c index 5ee17ddfa5b..bc7ab1d590c 100644 --- a/controls/widgets.c +++ b/controls/widgets.c @@ -19,106 +19,49 @@ #include "static.h" #include "wine/unicode.h" -/* Built-in classes */ - -static const char bi_class_nameA[BIC32_NB_CLASSES][10] = +struct builtin_class { - "Button", - "Edit", - "ListBox", - "ComboBox", - "ComboLBox", - POPUPMENU_CLASS_NAME, - "Static", - "ScrollBar", - "MDIClient", - DESKTOP_CLASS_NAME, - DIALOG_CLASS_NAME, - ICONTITLE_CLASS_NAME + LPCSTR name; + UINT style; + WNDPROC procA; + WNDPROC procW; + INT extra; + LPCSTR cursor; + HBRUSH brush; }; -static const WCHAR bi_class_nameW[BIC32_NB_CLASSES][10] = +/* Under NT all builtin classes have both ASCII and Unicode window + * procedures except ScrollBar, PopupMenu, Desktop, WinSwitch and + * IconTitle which are Unicode-only. + */ +static const struct builtin_class classes[] = { - {'B','u','t','t','o','n',0}, - {'E','d','i','t',0}, - {'L','i','s','t','B','o','x',0}, - {'C','o','m','b','o','B','o','x',0}, - {'C','o','m','b','o','L','B','o','x',0}, - {'#','3','2','7','6','8',0}, - {'S','t','a','t','i','c',0}, - {'S','c','r','o','l','l','B','a','r',0}, - {'M','D','I','C','l','i','e','n','t',0}, - {'#','3','2','7','6','9',0}, - {'#','3','2','7','7','0',0}, - {'#','3','2','7','7','2',0} + { "Button", CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, + ButtonWndProcA, ButtonWndProcW, sizeof(BUTTONINFO), IDC_ARROWA, 0 }, + { "Edit", CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/, + EditWndProc, NULL, sizeof(void *), IDC_IBEAMA, 0 }, + { "ListBox", CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/, + ListBoxWndProc, NULL, sizeof(void *), IDC_ARROWA, 0 }, + { "ComboBox", CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, + ComboWndProc, NULL, sizeof(void *), IDC_ARROWA, 0 }, + { "ComboLBox", CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS, + ComboLBWndProc, NULL, sizeof(void *), IDC_ARROWA, 0 }, + { "Static", CS_GLOBALCLASS | CS_DBLCLKS | CS_PARENTDC, + StaticWndProc, NULL, sizeof(STATICINFO), IDC_ARROWA, 0 }, + { "ScrollBar", CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, + ScrollBarWndProc, NULL, sizeof(SCROLLBAR_INFO), IDC_ARROWA, 0 }, + { "MDIClient", CS_GLOBALCLASS, + MDIClientWndProc, NULL, sizeof(MDICLIENTINFO), IDC_ARROWA, STOCK_LTGRAY_BRUSH }, + { POPUPMENU_CLASS_NAME, CS_GLOBALCLASS | CS_SAVEBITS, + PopupMenuWndProc, NULL, sizeof(HMENU), IDC_ARROWA, COLOR_MENU+1 }, + { DESKTOP_CLASS_NAME, CS_GLOBALCLASS, + DesktopWndProc, NULL, sizeof(DESKTOP), IDC_ARROWA, COLOR_BACKGROUND+1 }, + { DIALOG_CLASS_NAME, CS_GLOBALCLASS | CS_SAVEBITS, + DefDlgProcA, DefDlgProcW, DLGWINDOWEXTRA, IDC_ARROWA, 0 }, + { ICONTITLE_CLASS_NAME, CS_GLOBALCLASS, + IconTitleWndProc, NULL, 0, IDC_ARROWA, 0 } }; -typedef struct { - BOOL unicode; - union { - WNDCLASSA A; - WNDCLASSW W; - } wnd_class; -} BUILTINCLASS; - -static BUILTINCLASS WIDGETS_BuiltinClasses[BIC32_NB_CLASSES] = -{ - /* BIC32_BUTTON */ - { TRUE, { - { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, - ButtonWndProc, 0, sizeof(BUTTONINFO), 0, 0, - (HCURSOR)IDC_ARROWW, 0, 0, (LPCSTR)bi_class_nameW[0] }}}, - /* BIC32_EDIT */ - { FALSE, { - { CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/, - EditWndProc, 0, sizeof(void *), 0, 0, - (HCURSOR)IDC_IBEAMA, 0, 0, bi_class_nameA[1] }}}, - /* BIC32_LISTBOX */ - { FALSE, { - { CS_GLOBALCLASS | CS_DBLCLKS /*| CS_PARENTDC*/, - ListBoxWndProc, 0, sizeof(void *), 0, 0, - (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[2] }}}, - /* BIC32_COMBO */ - { FALSE, { - { CS_GLOBALCLASS | CS_PARENTDC | CS_DBLCLKS, - ComboWndProc, 0, sizeof(void *), 0, 0, - (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[3] }}}, - /* BIC32_COMBOLB */ - { FALSE, { - { CS_GLOBALCLASS | CS_DBLCLKS | CS_SAVEBITS, ComboLBWndProc, - 0, sizeof(void *), 0, 0, (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[4] }}}, - /* BIC32_POPUPMENU */ - { FALSE, { - { CS_GLOBALCLASS | CS_SAVEBITS, PopupMenuWndProc, 0, sizeof(HMENU), - 0, 0, (HCURSOR)IDC_ARROWA, NULL_BRUSH, 0, bi_class_nameA[5] }}}, - /* BIC32_STATIC */ - { FALSE, { - { CS_GLOBALCLASS | CS_DBLCLKS | CS_PARENTDC, StaticWndProc, - 0, sizeof(STATICINFO), 0, 0, (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[6] }}}, - /* BIC32_SCROLL */ - { FALSE, { - { CS_GLOBALCLASS | CS_DBLCLKS | CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, - ScrollBarWndProc, 0, sizeof(SCROLLBAR_INFO), 0, 0, - (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[7] }}}, - /* BIC32_MDICLIENT */ - { FALSE, { - { CS_GLOBALCLASS, MDIClientWndProc, - 0, sizeof(MDICLIENTINFO), 0, 0, (HCURSOR)IDC_ARROWA, STOCK_LTGRAY_BRUSH, 0, bi_class_nameA[8] }}}, - /* BIC32_DESKTOP */ - { FALSE, { - { CS_GLOBALCLASS, DesktopWndProc, 0, sizeof(DESKTOP), - 0, 0, (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[9] }}}, - /* BIC32_DIALOG */ - { FALSE, { - { CS_GLOBALCLASS | CS_SAVEBITS, DefDlgProcA, 0, DLGWINDOWEXTRA, - 0, 0, (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[10] }}}, - /* BIC32_ICONTITLE */ - { FALSE, { - { CS_GLOBALCLASS, IconTitleWndProc, 0, 0, - 0, 0, (HCURSOR)IDC_ARROWA, 0, 0, bi_class_nameA[11] }}} -}; - -static ATOM bicAtomTable[BIC32_NB_CLASSES]; /*********************************************************************** * WIDGETS_Init @@ -127,44 +70,14 @@ static ATOM bicAtomTable[BIC32_NB_CLASSES]; */ BOOL WIDGETS_Init(void) { + const struct builtin_class *cls = classes; int i; - BUILTINCLASS *cls = WIDGETS_BuiltinClasses; - /* Create builtin classes */ - - for (i = 0; i < BIC32_NB_CLASSES; i++, cls++) + for (i = 0; i < sizeof(classes)/sizeof(classes[0]); i++, cls++) { - if(cls->unicode) - { - WCHAR nameW[20]; - /* Just to make sure the string is > 0x10000 */ - strcpyW( nameW, (WCHAR *)cls->wnd_class.W.lpszClassName ); - cls->wnd_class.W.lpszClassName = nameW; - cls->wnd_class.W.hCursor = LoadCursorW( 0, (LPCWSTR)cls->wnd_class.W.hCursor ); - if (!(bicAtomTable[i] = RegisterClassW( &(cls->wnd_class.W) ))) return FALSE; - } - else - { - char name[20]; - /* Just to make sure the string is > 0x10000 */ - strcpy( name, (char *)cls->wnd_class.A.lpszClassName ); - cls->wnd_class.A.lpszClassName = name; - cls->wnd_class.A.hCursor = LoadCursorA( 0, (LPCSTR)cls->wnd_class.A.hCursor ); - if (!(bicAtomTable[i] = RegisterClassA( &(cls->wnd_class.A) ))) return FALSE; - } + if (!CLASS_RegisterBuiltinClass( cls->name, cls->style, cls->extra, cls->cursor, + cls->brush, cls->procA, cls->procW )) + return FALSE; } - return TRUE; } - - -/*********************************************************************** - * WIDGETS_IsControl32 - * - * Check whether pWnd is a built-in control or not. - */ -BOOL WIDGETS_IsControl( WND* pWnd, BUILTIN_CLASS32 cls ) -{ - assert( cls < BIC32_NB_CLASSES ); - return (GetClassWord(pWnd->hwndSelf, GCW_ATOM) == bicAtomTable[cls]); -} diff --git a/dlls/ttydrv/ttydrv.h b/dlls/ttydrv/ttydrv.h index e44f8ec8b6d..615a9434adc 100644 --- a/dlls/ttydrv/ttydrv.h +++ b/dlls/ttydrv/ttydrv.h @@ -143,8 +143,8 @@ extern HANDLE TTYDRV_LoadOEMResource(WORD resid, WORD type); extern void TTYDRV_WND_Initialize(struct tagWND *wndPtr); extern void TTYDRV_WND_Finalize(struct tagWND *wndPtr); -extern BOOL TTYDRV_WND_CreateDesktopWindow(struct tagWND *wndPtr, struct tagCLASS *classPtr, BOOL bUnicode); -extern BOOL TTYDRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCLASS *classPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode); +extern BOOL TTYDRV_WND_CreateDesktopWindow(struct tagWND *wndPtr, BOOL bUnicode); +extern BOOL TTYDRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode); extern BOOL TTYDRV_WND_DestroyWindow(struct tagWND *pWnd); extern struct tagWND *TTYDRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent); extern void TTYDRV_WND_ForceWindowRaise(struct tagWND *pWnd); diff --git a/dlls/ttydrv/wnd.c b/dlls/ttydrv/wnd.c index 5e32ded1aa7..5d0eebba10f 100644 --- a/dlls/ttydrv/wnd.c +++ b/dlls/ttydrv/wnd.c @@ -6,7 +6,6 @@ #include "config.h" -#include "class.h" #include "gdi.h" #include "heap.h" #include "ttydrv.h" @@ -89,12 +88,12 @@ void TTYDRV_WND_Finalize(WND *wndPtr) /********************************************************************** * TTYDRV_WND_CreateDesktopWindow */ -BOOL TTYDRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode) +BOOL TTYDRV_WND_CreateDesktopWindow(WND *wndPtr, BOOL bUnicode) { TTYDRV_WND_DATA *pWndDriverData = (TTYDRV_WND_DATA *) wndPtr->pDriverData; - TRACE("(%p, %p, %d)\n", wndPtr, classPtr, bUnicode); + TRACE("(%p, %d)\n", wndPtr, bUnicode); if(!pWndDriverData) { ERR("WND never initialized\n"); return FALSE; } @@ -105,13 +104,13 @@ BOOL TTYDRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode) /********************************************************************** * TTYDRV_WND_CreateWindow */ -BOOL TTYDRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BOOL bUnicode) +BOOL TTYDRV_WND_CreateWindow(WND *wndPtr, CREATESTRUCTA *cs, BOOL bUnicode) { #ifdef WINE_CURSES WINDOW *window; INT cellWidth=8, cellHeight=8; /* FIXME: Hardcoded */ - TRACE("(%p, %p, %p, %d)\n", wndPtr, classPtr, cs, bUnicode); + TRACE("(%p, %p, %d)\n", wndPtr, cs, bUnicode); /* Only create top-level windows */ if(cs->style & WS_CHILD) @@ -124,7 +123,7 @@ BOOL TTYDRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO return TRUE; #else /* defined(WINE_CURSES) */ - FIXME("(%p, %p, %p, %d): stub\n", wndPtr, classPtr, cs, bUnicode); + FIXME("(%p, %p, %p, %d): stub\n", wndPtr, cs, bUnicode); return TRUE; #endif /* defined(WINE_CURSES) */ diff --git a/dlls/user/user.spec b/dlls/user/user.spec index bda1a8ab20e..66df95f4655 100644 --- a/dlls/user/user.spec +++ b/dlls/user/user.spec @@ -378,12 +378,12 @@ owner user32 394 pascal16 DrawIconEx(word word word word word word word word word) DrawIconEx16 395 pascal16 GetIconInfo(word ptr) GetIconInfo16 397 pascal16 RegisterClassEx(ptr) RegisterClassEx16 -398 pascal16 GetClassInfoEx(word str ptr) GetClassInfoEx16 +398 pascal16 GetClassInfoEx(word segstr ptr) GetClassInfoEx16 399 pascal16 ChildWindowFromPointEx(word long word) ChildWindowFromPointEx16 400 pascal16 FinalUserInit() FinalUserInit16 402 pascal16 GetPriorityClipboardFormat(ptr s_word) GetPriorityClipboardFormat16 403 pascal16 UnregisterClass(str word) UnregisterClass16 -404 pascal16 GetClassInfo(word str ptr) GetClassInfo16 +404 pascal16 GetClassInfo(word segstr ptr) GetClassInfo16 406 pascal16 CreateCursor(word word word word word ptr ptr) CreateCursor16 407 pascal16 CreateIcon(word word word word word ptr ptr) CreateIcon16 408 pascal16 CreateCursorIconIndirect(word ptr ptr ptr) diff --git a/include/button.h b/include/button.h index e4e84ade172..09d9590087d 100644 --- a/include/button.h +++ b/include/button.h @@ -35,7 +35,7 @@ typedef struct #define BUTTON_STATE(hwnd) ((WIN_FindWndPtr(hwnd))->wExtra[0]) -extern LRESULT WINAPI ButtonWndProc( HWND hWnd, UINT uMsg, - WPARAM wParam, LPARAM lParam ); +extern LRESULT WINAPI ButtonWndProcA( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); +extern LRESULT WINAPI ButtonWndProcW( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); #endif /* __WINE_BUTTON_H */ diff --git a/include/class.h b/include/class.h deleted file mode 100644 index ca6bb48a423..00000000000 --- a/include/class.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Window classes definitions - * - * Copyright 1993 Alexandre Julliard - */ - -#ifndef __WINE_CLASS_H -#define __WINE_CLASS_H - -#include "windef.h" -#include "winproc.h" - -#define CLASS_MAGIC ('C' | ('L' << 8) | ('A' << 16) | ('S' << 24)) - -struct tagDCE; - -typedef struct tagCLASS -{ - struct tagCLASS *next; /* Next class */ - UINT magic; /* Magic number */ - UINT cWindows; /* Count of existing windows */ - UINT style; /* Class style */ - HWINDOWPROC winproc; /* Window procedure */ - INT cbClsExtra; /* Class extra bytes */ - INT cbWndExtra; /* Window extra bytes */ - LPSTR menuNameA; /* Default menu name (ASCII string) */ - LPWSTR menuNameW; /* Default menu name (Unicode) */ - struct tagDCE *dce; /* Class DCE (if CS_CLASSDC) */ - HINSTANCE hInstance; /* Module that created the task */ - HICON16 hIcon; /* Default icon */ - HICON16 hIconSm; /* Default small icon */ - HCURSOR16 hCursor; /* Default cursor */ - HBRUSH16 hbrBackground; /* Default background */ - ATOM atomName; /* Name of the class */ - LPSTR classNameA; /* Class name (ASCII string) */ - LPWSTR classNameW; /* Class name (Unicode) */ - LONG wExtra[1]; /* Class extra bytes */ -} CLASS; - -extern void CLASS_DumpClass( CLASS *class ); -extern void CLASS_WalkClasses(void); -extern void CLASS_FreeModuleClasses( HMODULE16 hModule ); -extern CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance ); - -#endif /* __WINE_CLASS_H */ diff --git a/include/win.h b/include/win.h index 1eb5530295a..b6a65c6f16c 100644 --- a/include/win.h +++ b/include/win.h @@ -28,24 +28,6 @@ #define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */ #define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */ -/* Built-in 32-bit classes */ -typedef enum -{ - BIC32_BUTTON, - BIC32_EDIT, - BIC32_LISTBOX, - BIC32_COMBO, - BIC32_COMBOLB, - BIC32_POPUPMENU, - BIC32_STATIC, - BIC32_SCROLL, - BIC32_MDICLIENT, - BIC32_DESKTOP, - BIC32_DIALOG, - BIC32_ICONTITLE, - BIC32_NB_CLASSES -} BUILTIN_CLASS32; - /* PAINT_RedrawWindow() control flags */ #define RDW_EX_USEHRGN 0x0001 #define RDW_EX_DELETEHRGN 0x0002 @@ -79,13 +61,15 @@ typedef struct tagWND HGLOBAL16 hmemTaskQ; /* Task queue global memory handle */ HRGN16 hrgnUpdate; /* Update region */ HRGN hrgnWnd; /* window's region */ - HWND hwndLastActive;/* Last active popup hwnd */ + HWND hwndLastActive;/* Last active popup hwnd */ DWORD dwStyle; /* Window style (from CreateWindow) */ DWORD dwExStyle; /* Extended style (from CreateWindowEx) */ - UINT wIDmenu; /* ID or hmenu (from CreateWindow) */ + DWORD clsStyle; /* Class style at window creation */ + UINT wIDmenu; /* ID or hmenu (from CreateWindow) */ DWORD helpContext; /* Help context ID */ WORD flags; /* Misc. flags (see below) */ HMENU16 hSysMenu; /* window's copy of System Menu */ + int cbWndExtra; /* class cbWndExtra at window creation */ int irefCount; /* window's reference count*/ DWORD userdata; /* User private data */ struct tagWND_DRIVER *pDriver; /* Window driver */ @@ -118,8 +102,8 @@ typedef struct tagWND_DRIVER { void (*pInitialize)(WND *); void (*pFinalize)(WND *); - BOOL (*pCreateDesktopWindow)(WND *, struct tagCLASS *, BOOL); - BOOL (*pCreateWindow)(WND *, struct tagCLASS *, CREATESTRUCTA *, BOOL); + BOOL (*pCreateDesktopWindow)(WND *, BOOL); + BOOL (*pCreateWindow)(WND *, CREATESTRUCTA *, BOOL); BOOL (*pDestroyWindow)(WND *); WND* (*pSetParent)(WND *, WND *); void (*pForceWindowRaise)(WND *); @@ -215,9 +199,18 @@ extern BOOL PAINT_RedrawWindow( HWND hwnd, const RECT *rectUpdate, UINT control ); /* windows/painting.c */ extern HRGN WIN_UpdateNCRgn(WND* wnd, HRGN hRgn, UINT flags); /* windows/painting.c */ +/* Classes functions */ +struct tagCLASS; /* opaque structure */ +extern ATOM CLASS_RegisterBuiltinClass( LPCSTR name, DWORD style, INT winExtra, LPCSTR cursor, + HBRUSH brush, WNDPROC wndProcA, WNDPROC wndProcW ); +extern struct tagCLASS *CLASS_AddWindow( ATOM atom, HINSTANCE inst, WINDOWPROCTYPE type, + INT *winExtra, WNDPROC *winproc, + DWORD *style, struct tagDCE **dce ); +extern void CLASS_RemoveWindow( struct tagCLASS *cls ); +extern void CLASS_FreeModuleClasses( HMODULE16 hModule ); + /* controls/widgets.c */ extern BOOL WIDGETS_Init( void ); -extern BOOL WIDGETS_IsControl( WND* pWnd, BUILTIN_CLASS32 cls ); /* controls/icontitle.c */ extern LRESULT WINAPI IconTitleWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); diff --git a/include/wine/winuser16.h b/include/wine/winuser16.h index 3f444005e80..8df3b658b61 100644 --- a/include/wine/winuser16.h +++ b/include/wine/winuser16.h @@ -710,8 +710,8 @@ WORD WINAPI GetAsyncKeyState16(INT16); HWND16 WINAPI GetCapture16(void); UINT16 WINAPI GetCaretBlinkTime16(void); VOID WINAPI GetCaretPos16(LPPOINT16); -BOOL16 WINAPI GetClassInfo16(HINSTANCE16,LPCSTR,WNDCLASS16 *); -BOOL16 WINAPI GetClassInfoEx16(HINSTANCE16,LPCSTR,WNDCLASSEX16 *); +BOOL16 WINAPI GetClassInfo16(HINSTANCE16,SEGPTR,WNDCLASS16 *); +BOOL16 WINAPI GetClassInfoEx16(HINSTANCE16,SEGPTR,WNDCLASSEX16 *); LONG WINAPI GetClassLong16(HWND16,INT16); INT16 WINAPI GetClassName16(HWND16,LPSTR,INT16); WORD WINAPI GetClassWord16(HWND16,INT16); diff --git a/include/x11drv.h b/include/x11drv.h index bb8421decfd..56451f1b2c8 100644 --- a/include/x11drv.h +++ b/include/x11drv.h @@ -417,8 +417,8 @@ extern Window X11DRV_WND_FindXWindow(struct tagWND *wndPtr); extern void X11DRV_WND_Initialize(struct tagWND *wndPtr); extern void X11DRV_WND_Finalize(struct tagWND *wndPtr); -extern BOOL X11DRV_WND_CreateDesktopWindow(struct tagWND *wndPtr, struct tagCLASS *classPtr, BOOL bUnicode); -extern BOOL X11DRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCLASS *classPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode); +extern BOOL X11DRV_WND_CreateDesktopWindow(struct tagWND *wndPtr, BOOL bUnicode); +extern BOOL X11DRV_WND_CreateWindow(struct tagWND *wndPtr, struct tagCREATESTRUCTA *cs, BOOL bUnicode); extern BOOL X11DRV_WND_DestroyWindow(struct tagWND *pWnd); extern struct tagWND *X11DRV_WND_SetParent(struct tagWND *wndPtr, struct tagWND *pWndParent); extern void X11DRV_WND_ForceWindowRaise(struct tagWND *pWnd); diff --git a/windows/class.c b/windows/class.c index c4c467ebc9a..dc6c2d93051 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 @@ void CLASS_WalkClasses(void) * * 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 @@ static LPSTR CLASS_GetMenuNameA( CLASS *classPtr ) * * 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 LPWSTR CLASS_GetMenuNameW( CLASS *classPtr ) */ 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_SetMenuNameA( CLASS *classPtr, LPCSTR name ) */ 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 void CLASS_SetClassNameW( CLASS *classPtr, LPCWSTR name ) */ 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 @@ static BOOL CLASS_FreeClass( CLASS *classPtr ) 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 @@ void CLASS_FreeModuleClasses( HMODULE16 hModule ) * 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 @@ CLASS *CLASS_FindClassByAtom( ATOM atom, HINSTANCE hinstance ) * 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 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, /* 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,35 +324,96 @@ static CLASS *CLASS_RegisterClass( ATOM atom, HINSTANCE hInstance, /* 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) */ @@ -421,8 +426,7 @@ ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc ) 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 @@ ATOM WINAPI RegisterClass16( const WNDCLASS16 *wc ) 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 @@ ATOM WINAPI RegisterClassA( const WNDCLASSA* wc ) /* [in] Address of structure w 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 @@ ATOM WINAPI RegisterClassA( const WNDCLASSA* wc ) /* [in] Address of structure w 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 @@ ATOM WINAPI RegisterClassW( const WNDCLASSW* wc ) 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 @@ ATOM WINAPI RegisterClassW( const WNDCLASSW* wc ) 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 @@ ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc ) 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 @@ ATOM WINAPI RegisterClassEx16( const WNDCLASSEX16 *wc ) 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 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) 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 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc ) 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 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) 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 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc ) 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 @@ BOOL16 WINAPI UnregisterClass16( LPCSTR className, HINSTANCE16 hInstance ) * */ 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 @@ BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance ) 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 @@ BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance ) 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 @@ LONG WINAPI GetClassLong16( HWND16 hwnd, INT16 offset ) { 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 @@ LONG WINAPI GetClassLongA( HWND hwnd, INT offset ) 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 @@ LONG WINAPI GetClassLongW( HWND hwnd, INT offset ) { 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 @@ WORD WINAPI SetClassWord( HWND hwnd, INT offset, WORD newval ) } 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 @@ LONG WINAPI SetClassLong16( HWND16 hwnd, INT16 offset, LONG newval ) { 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 @@ LONG WINAPI SetClassLongA( HWND hwnd, INT offset, LONG 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 ); + retval = (LONG)CLASS_SetProc( wndPtr->class, (WNDPROC)newval, WIN_PROC_32A ); goto END; case GCL_HBRBACKGROUND: case GCL_HCURSOR: @@ -1037,9 +1012,7 @@ LONG WINAPI SetClassLongW( HWND hwnd, INT offset, LONG newval ) { 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 @@ INT WINAPI GetClassNameW( HWND hwnd, LPWSTR buffer, INT count ) /*********************************************************************** * 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 @@ BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name, } 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 @@ BOOL WINAPI GetClassInfoA( HINSTANCE hInstance, LPCSTR name, 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 @@ BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name, 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 @@ BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name, 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 @@ BOOL WINAPI GetClassInfoW( HINSTANCE hInstance, LPCWSTR name, * 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 @@ BOOL16 WINAPI GetClassInfoEx16( HINSTANCE16 hInstance, LPCSTR name, WNDCLASSEX16 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 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR 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->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32A ); wc->cbClsExtra = classPtr->cbClsExtra; wc->cbWndExtra = classPtr->cbWndExtra; wc->hInstance = classPtr->hInstance; @@ -1273,8 +1239,8 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, 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 @@ BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR 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->lpfnWndProc = (WNDPROC)CLASS_GetProc( classPtr, WIN_PROC_32W ); wc->cbClsExtra = classPtr->cbClsExtra; wc->cbWndExtra = classPtr->cbWndExtra; wc->hInstance = classPtr->hInstance; @@ -1305,8 +1270,8 @@ BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, 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; } diff --git a/windows/dce.c b/windows/dce.c index 0f0215ed3b3..ad2b57faf2c 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -20,7 +20,6 @@ #include #include "options.h" #include "dce.h" -#include "class.h" #include "win.h" #include "gdi.h" #include "region.h" @@ -161,7 +160,7 @@ void DCE_FreeWindowDCE( WND* pWnd ) { if( pDCE == pWnd->dce ) /* owned or Class DCE*/ { - if (pWnd->class->style & CS_OWNDC) /* owned DCE*/ + if (pWnd->clsStyle & CS_OWNDC) /* owned DCE*/ { pDCE = DCE_FreeDCE( pDCE ); pWnd->dce = NULL; @@ -676,7 +675,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) /* fixup flags */ - if (!(wndPtr->class->style & (CS_OWNDC | CS_CLASSDC))) flags |= DCX_CACHE; + if (!wndPtr->dce) flags |= DCX_CACHE; if (flags & DCX_USESTYLE) { @@ -687,7 +686,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) if ( !(flags & DCX_WINDOW) ) { - if (wndPtr->class->style & CS_PARENTDC) flags |= DCX_PARENTCLIP; + if (wndPtr->clsStyle & CS_PARENTDC) flags |= DCX_PARENTCLIP; if (wndPtr->dwStyle & WS_CLIPCHILDREN && !(wndPtr->dwStyle & WS_MINIMIZE) ) flags |= DCX_CLIPCHILDREN; @@ -767,7 +766,7 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) } else { - dce = (wndPtr->class->style & CS_OWNDC) ? wndPtr->dce : wndPtr->class->dce; + dce = wndPtr->dce; if( dce->hwndCurrent == hwnd ) { TRACE("\tskipping hVisRgn update\n"); diff --git a/windows/defwnd.c b/windows/defwnd.c index 1f924eb37ea..de053426d38 100644 --- a/windows/defwnd.c +++ b/windows/defwnd.c @@ -7,7 +7,6 @@ #include -#include "class.h" #include "win.h" #include "user.h" #include "heap.h" @@ -324,7 +323,8 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam, HDC16 hdc = BeginPaint16( wndPtr->hwndSelf, &ps ); if( hdc ) { - if( (wndPtr->dwStyle & WS_MINIMIZE) && wndPtr->class->hIcon ) + HICON hIcon; + if( (wndPtr->dwStyle & WS_MINIMIZE) && ((hIcon = GetClassLongA( wndPtr->hwndSelf, GCL_HICON))) ) { int x = (wndPtr->rectWindow.right - wndPtr->rectWindow.left - GetSystemMetrics(SM_CXICON))/2; @@ -332,7 +332,7 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam, GetSystemMetrics(SM_CYICON))/2; TRACE("Painting class icon: vis rect=(%i,%i - %i,%i)\n", ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right, ps.rcPaint.bottom ); - DrawIcon( hdc, x, y, wndPtr->class->hIcon ); + DrawIcon( hdc, x, y, hIcon ); } EndPaint16( wndPtr->hwndSelf, &ps ); } @@ -387,8 +387,8 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam, case WM_ICONERASEBKGND: { RECT rect; - - if (!wndPtr->class->hbrBackground) return 0; + HBRUSH hbr = GetClassLongA( wndPtr->hwndSelf, GCL_HBRBACKGROUND ); + if (!hbr) return 0; /* Since WM_ERASEBKGND may receive either a window dc or a */ /* client dc, the area to be erased has to be retrieved from */ @@ -400,7 +400,7 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam, * supports special background brushes for a window class, * the Win16 variant of FillRect does not. */ - FillRect( (HDC) wParam, &rect, wndPtr->class->hbrBackground); + FillRect( (HDC) wParam, &rect, hbr ); return 1; } @@ -457,7 +457,7 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam, { HWND hWnd = WIN_GetTopParent( wndPtr->hwndSelf ); wndPtr = WIN_FindWndPtr( hWnd ); - if( wndPtr && !(wndPtr->class->style & CS_NOCLOSE) ) + if( wndPtr && !(wndPtr->clsStyle & CS_NOCLOSE) ) PostMessage16( hWnd, WM_SYSCOMMAND, SC_CLOSE, 0 ); WIN_ReleaseWndPtr(wndPtr); } @@ -528,10 +528,10 @@ static LRESULT DEFWND_DefWinProc( WND *wndPtr, UINT msg, WPARAM wParam, case WM_QUERYDRAGICON: { - HICON16 hIcon=0; UINT16 len; - if( (hIcon=wndPtr->class->hCursor) ) return (LRESULT)hIcon; + HICON hIcon = GetClassLongA( wndPtr->hwndSelf, GCL_HICON ); + if (hIcon) return hIcon; for(len=1; len<64; len++) if((hIcon=LoadIconA(wndPtr->hInstance,MAKEINTRESOURCEA(len)))) return (LRESULT)hIcon; diff --git a/windows/mdi.c b/windows/mdi.c index 8211efc57d3..f6056d9454a 100644 --- a/windows/mdi.c +++ b/windows/mdi.c @@ -75,7 +75,6 @@ #include "winuser.h" #include "wine/unicode.h" #include "win.h" -#include "class.h" #include "heap.h" #include "nonclient.h" #include "mdi.h" @@ -1647,7 +1646,7 @@ LRESULT WINAPI DefMDIChildProc16( HWND16 hwnd, UINT16 message, WIN_ReleaseWndPtr(tmpWnd); /* Sanity check */ - if (clientWnd->class->cbWndExtra < sizeof(MDICLIENTINFO)) + if (clientWnd->cbWndExtra < sizeof(MDICLIENTINFO)) { WARN("called on non-MDI child window %x\n", hwnd); WIN_ReleaseWndPtr(clientWnd); @@ -1847,7 +1846,7 @@ LRESULT WINAPI DefMDIChildProcA( HWND hwnd, UINT message, WIN_ReleaseWndPtr(tmpWnd); /* Sanity check */ - if (clientWnd->class->cbWndExtra < sizeof(MDICLIENTINFO)) + if (clientWnd->cbWndExtra < sizeof(MDICLIENTINFO)) { WARN("called on non-MDI child window %x\n", hwnd); WIN_ReleaseWndPtr(clientWnd); @@ -1925,7 +1924,7 @@ LRESULT WINAPI DefMDIChildProcW( HWND hwnd, UINT message, WIN_ReleaseWndPtr(tmpWnd); /* Sanity check */ - if (clientWnd->class->cbWndExtra < sizeof(MDICLIENTINFO)) + if (clientWnd->cbWndExtra < sizeof(MDICLIENTINFO)) { WARN("called on non-MDI child window %x\n", hwnd); WIN_ReleaseWndPtr(clientWnd); diff --git a/windows/user.c b/windows/user.c index 5c1d8de788f..43f7f570e1e 100644 --- a/windows/user.c +++ b/windows/user.c @@ -14,7 +14,6 @@ #include "user.h" #include "task.h" #include "queue.h" -#include "class.h" #include "win.h" #include "clipboard.h" #include "menu.h" diff --git a/windows/win.c b/windows/win.c index bfe006f274d..53236150955 100644 --- a/windows/win.c +++ b/windows/win.c @@ -11,7 +11,6 @@ #include "wine/winuser16.h" #include "wine/unicode.h" #include "options.h" -#include "class.h" #include "win.h" #include "heap.h" #include "user.h" @@ -229,10 +228,10 @@ void WIN_DumpWindow( HWND hwnd ) ptr->rectWindow.right, ptr->rectWindow.bottom, ptr->hSysMenu, ptr->flags, ptr->pProp, ptr->pVScroll, ptr->pHScroll ); - if (ptr->class->cbWndExtra) + if (ptr->cbWndExtra) { DPRINTF( "extra bytes:" ); - for (i = 0; i < ptr->class->cbWndExtra; i++) + for (i = 0; i < ptr->cbWndExtra; i++) DPRINTF( " %02x", *((BYTE*)ptr->wExtra+i) ); DPRINTF( "\n" ); } @@ -268,8 +267,7 @@ void WIN_WalkWindows( HWND hwnd, int indent ) { DPRINTF( "%*s%04x%*s", indent, "", ptr->hwndSelf, 13-indent,""); - GlobalGetAtomNameA(ptr->class->atomName,className,sizeof(className)); - + GetClassNameA( hwnd, className, sizeof(className) ); DPRINTF( "%08lx %-6.4x %-17.17s %08x %08x %.14s\n", (DWORD)ptr, ptr->hmemTaskQ, className, (UINT)ptr->dwStyle, (UINT)ptr->winproc, @@ -504,7 +502,7 @@ static WND* WIN_DestroyWindow( WND* wndPtr ) wndPtr->pDriver->pDestroyWindow( wndPtr ); DCE_FreeWindowDCE( wndPtr ); /* Always do this to catch orphaned DCs */ WINPROC_FreeProc( wndPtr->winproc, WIN_PROC_WINDOW ); - wndPtr->class->cWindows--; + CLASS_RemoveWindow( wndPtr->class ); wndPtr->class = NULL; WIN_UpdateWndPtr(&pWnd,wndPtr->next); @@ -577,18 +575,23 @@ BOOL WIN_ResetQueueWindows( WND* wnd, HQUEUE16 hQueue, HQUEUE16 hNew ) */ BOOL WIN_CreateDesktopWindow(void) { - CLASS *class; + struct tagCLASS *class; HWND hwndDesktop; + INT wndExtra; + DWORD clsStyle; + WNDPROC winproc; + DCE *dce; TRACE("Creating desktop window\n"); if (!ICONTITLE_Init() || !WINPOS_CreateInternalPosAtom() || - !(class = CLASS_FindClassByAtom( DESKTOP_CLASS_ATOM, 0 ))) - return FALSE; + !(class = CLASS_AddWindow( DESKTOP_CLASS_ATOM, 0, WIN_PROC_32A, + &wndExtra, &winproc, &clsStyle, &dce ))) + return FALSE; - hwndDesktop = USER_HEAP_ALLOC( sizeof(WND)+class->cbWndExtra ); + hwndDesktop = USER_HEAP_ALLOC( sizeof(WND) + wndExtra ); if (!hwndDesktop) return FALSE; pWndDesktop = (WND *) USER_HEAP_LIN_ADDR( hwndDesktop ); @@ -615,6 +618,7 @@ BOOL WIN_CreateDesktopWindow(void) pWndDesktop->dwStyle = WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; pWndDesktop->dwExStyle = 0; + pWndDesktop->clsStyle = clsStyle; pWndDesktop->dce = NULL; pWndDesktop->pVScroll = NULL; pWndDesktop->pHScroll = NULL; @@ -624,11 +628,12 @@ BOOL WIN_CreateDesktopWindow(void) pWndDesktop->flags = Options.desktopGeometry ? WIN_NATIVE : 0; pWndDesktop->hSysMenu = 0; pWndDesktop->userdata = 0; - pWndDesktop->winproc = (WNDPROC16)class->winproc; + pWndDesktop->winproc = winproc; + pWndDesktop->cbWndExtra = wndExtra; pWndDesktop->irefCount = 0; /* FIXME: How do we know if it should be Unicode or not */ - if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, class, FALSE)) + if(!pWndDesktop->pDriver->pCreateDesktopWindow(pWndDesktop, FALSE)) return FALSE; SendMessageA( hwndDesktop, WM_NCCREATE, 0, 0 ); @@ -711,11 +716,15 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, WINDOWPROCTYPE type ) { INT sw = SW_SHOW; - CLASS *classPtr; + struct tagCLASS *classPtr; WND *wndPtr; HWND retvalue; HWND16 hwnd, hwndLinkAfter; POINT maxSize, maxPos, minTrack, maxTrack; + INT wndExtra; + DWORD clsStyle; + WNDPROC winproc; + DCE *dce; LRESULT (CALLBACK *localSend32)(HWND, UINT, WPARAM, LPARAM); TRACE("%s %s %08lx %08lx %d,%d %dx%d %04x %04x %08x %p\n", @@ -743,7 +752,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, } /* Find the window class */ - if (!(classPtr = CLASS_FindClassByAtom( classAtom, (type == WIN_PROC_16) ? GetExePtr(cs->hInstance) : cs->hInstance ))) + if (!(classPtr = CLASS_AddWindow( classAtom, cs->hInstance, type, + &wndExtra, &winproc, &clsStyle, &dce ))) { WARN("Bad class '%s'\n", cs->lpszClass ); return 0; @@ -753,8 +763,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, /* Create the window structure */ - if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + classPtr->cbWndExtra - - sizeof(wndPtr->wExtra) ))) + if (!(hwnd = USER_HEAP_ALLOC( sizeof(*wndPtr) + wndExtra - sizeof(wndPtr->wExtra) ))) { TRACE("out of memory\n" ); return 0; @@ -791,7 +800,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, wndPtr->pDriver->pInitialize(wndPtr); wndPtr->class = classPtr; - wndPtr->winproc = classPtr->winproc; + wndPtr->winproc = winproc; wndPtr->dwMagic = WND_MAGIC; wndPtr->hwndSelf = hwnd; wndPtr->hInstance = cs->hInstance; @@ -802,6 +811,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, wndPtr->hwndLastActive = hwnd; wndPtr->dwStyle = cs->style & ~WS_VISIBLE; wndPtr->dwExStyle = cs->dwExStyle; + wndPtr->clsStyle = clsStyle; wndPtr->wIDmenu = 0; wndPtr->helpContext = 0; wndPtr->flags = (type == WIN_PROC_16) ? 0 : WIN_ISWIN32; @@ -811,9 +821,10 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, wndPtr->userdata = 0; wndPtr->hSysMenu = (wndPtr->dwStyle & WS_SYSMENU) ? MENU_GetSysMenu( hwnd, 0 ) : 0; + wndPtr->cbWndExtra = wndExtra; wndPtr->irefCount = 1; - if (classPtr->cbWndExtra) memset( wndPtr->wExtra, 0, classPtr->cbWndExtra); + if (wndExtra) memset( wndPtr->wExtra, 0, wndExtra); /* Call the WH_CBT hook */ @@ -834,15 +845,12 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, TRACE("CBT-hook returned 0\n"); wndPtr->pDriver->pFinalize(wndPtr); USER_HEAP_FREE( hwnd ); + CLASS_RemoveWindow( classPtr ); retvalue = 0; goto end; } } - /* Increment class window counter */ - - classPtr->cWindows++; - /* Correct the window style */ if (!(cs->style & WS_CHILD)) @@ -857,8 +865,8 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, /* Get class or window DC if needed */ - if (classPtr->style & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC); - else if (classPtr->style & CS_CLASSDC) wndPtr->dce = classPtr->dce; + if (clsStyle & CS_OWNDC) wndPtr->dce = DCE_AllocDCE(hwnd,DCE_WINDOW_DC); + else if (clsStyle & CS_CLASSDC) wndPtr->dce = dce; else wndPtr->dce = NULL; /* Initialize the dimensions before sending WM_GETMINMAXINFO */ @@ -889,7 +897,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, wndPtr->rectWindow.bottom = cs->y + cs->cy; wndPtr->rectClient = wndPtr->rectWindow; - if(!wndPtr->pDriver->pCreateWindow(wndPtr, classPtr, cs, type == WIN_PROC_32W)) + if(!wndPtr->pDriver->pCreateWindow(wndPtr, cs, type == WIN_PROC_32W)) { retvalue = FALSE; goto end; @@ -902,7 +910,6 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, if (cs->hMenu) SetMenu(hwnd, cs->hMenu); else { - /* FIXME: should check if classPtr->menuNameW can be used as is */ LPCSTR menuName = (LPCSTR)GetClassLongA( hwnd, GCL_MENUNAME ); if (menuName) { @@ -1001,6 +1008,7 @@ static HWND WIN_CreateWindowEx( CREATESTRUCTA *cs, ATOM classAtom, WARN("aborted by WM_xxCREATE!\n"); WIN_ReleaseWndPtr(WIN_DestroyWindow( wndPtr )); + CLASS_RemoveWindow( classPtr ); retvalue = 0; end: WIN_ReleaseWndPtr(wndPtr); @@ -1541,7 +1549,7 @@ static HWND WIN_FindWindow( HWND parent, HWND child, ATOM className, for ( ; pWnd ; WIN_UpdateWndPtr(&pWnd,pWnd->next)) { - if (className && (pWnd->class->atomName != className)) + if (className && (GetClassWord(pWnd->hwndSelf, GCW_ATOM) != className)) continue; /* Not the right class */ /* Now check the title */ @@ -1824,7 +1832,7 @@ WORD WINAPI GetWindowWord( HWND hwnd, INT offset ) if (!wndPtr) return 0; if (offset >= 0) { - if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra) + if (offset + sizeof(WORD) > wndPtr->cbWndExtra) { WARN("Invalid offset %d\n", offset ); retvalue = 0; @@ -1879,7 +1887,7 @@ WORD WINAPI SetWindowWord( HWND hwnd, INT offset, WORD newval ) if (!wndPtr) return 0; if (offset >= 0) { - if (offset + sizeof(WORD) > wndPtr->class->cbWndExtra) + if (offset + sizeof(WORD) > wndPtr->cbWndExtra) { WARN("Invalid offset %d\n", offset ); retval = 0; @@ -1918,7 +1926,7 @@ static LONG WIN_GetWindowLong( HWND hwnd, INT offset, WINDOWPROCTYPE type ) if (!wndPtr) return 0; if (offset >= 0) { - if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra) + if (offset + sizeof(LONG) > wndPtr->cbWndExtra) { WARN("Invalid offset %d\n", offset ); retvalue = 0; @@ -1989,7 +1997,7 @@ static LONG WIN_SetWindowLong( HWND hwnd, INT offset, LONG newval, if (offset >= 0) { - if (offset + sizeof(LONG) > wndPtr->class->cbWndExtra) + if (offset + sizeof(LONG) > wndPtr->cbWndExtra) { WARN("Invalid offset %d\n", offset ); @@ -2502,9 +2510,9 @@ BOOL WINAPI IsWindowVisible( HWND hwnd ) */ BOOL WIN_IsWindowDrawable( WND* wnd, BOOL icon ) { - if( (wnd->dwStyle & WS_MINIMIZE && - icon && wnd->class->hIcon) || - !(wnd->dwStyle & WS_VISIBLE) ) return FALSE; + if (!(wnd->dwStyle & WS_VISIBLE)) return FALSE; + if ((wnd->dwStyle & WS_MINIMIZE) && + icon && GetClassLongA( wnd->hwndSelf, GCL_HICON )) return FALSE; for(wnd = wnd->parent; wnd; wnd = wnd->parent) if( wnd->dwStyle & WS_MINIMIZE || !(wnd->dwStyle & WS_VISIBLE) ) break; diff --git a/windows/x11drv/wnd.c b/windows/x11drv/wnd.c index a0b1908d661..e8ef341b629 100644 --- a/windows/x11drv/wnd.c +++ b/windows/x11drv/wnd.c @@ -26,7 +26,6 @@ #include "heap.h" #include "win.h" #include "windef.h" -#include "class.h" #include "x11drv.h" #include "wingdi.h" #include "winnls.h" @@ -174,7 +173,7 @@ void X11DRV_WND_Finalize(WND *wndPtr) /********************************************************************** * X11DRV_WND_CreateDesktopWindow */ -BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, CLASS *classPtr, BOOL bUnicode) +BOOL X11DRV_WND_CreateDesktopWindow(WND *wndPtr, BOOL bUnicode) { if (wmProtocols == None) wmProtocols = TSXInternAtom( display, "WM_PROTOCOLS", True ); @@ -306,7 +305,7 @@ static void X11DRV_WND_UpdateIconHints(WND *wndPtr) /********************************************************************** * X11DRV_WND_CreateWindow */ -BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BOOL bUnicode) +BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CREATESTRUCTA *cs, BOOL bUnicode) { /* Create the X window (only for top-level windows, and then only */ /* when there's no desktop window) */ @@ -336,10 +335,10 @@ BOOL X11DRV_WND_CreateWindow(WND *wndPtr, CLASS *classPtr, CREATESTRUCTA *cs, BO } wndPtr->flags |= WIN_NATIVE; - win_attr.bit_gravity = (classPtr->style & (CS_VREDRAW | CS_HREDRAW)) ? BGForget : BGNorthWest; + win_attr.bit_gravity = (wndPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW)) ? BGForget : BGNorthWest; win_attr.colormap = X11DRV_PALETTE_PaletteXColormap; win_attr.backing_store = NotUseful; - win_attr.save_under = ((classPtr->style & CS_SAVEBITS) != 0); + win_attr.save_under = ((wndPtr->clsStyle & CS_SAVEBITS) != 0); win_attr.cursor = X11DRV_MOUSE_XCursor; ((X11DRV_WND_DATA *) wndPtr->pDriverData)->hWMIconBitmap = 0; @@ -520,8 +519,7 @@ WND *X11DRV_WND_SetParent(WND *wndPtr, WND *pWndParent) cs.lpszName = 0; /* not used in following call */ cs.lpszClass = 0; /*not used in following call */ cs.dwExStyle = wndPtr->dwExStyle; - X11DRV_WND_CreateWindow(wndPtr, wndPtr->class, - &cs, FALSE); + X11DRV_WND_CreateWindow(wndPtr, &cs, FALSE); } } else /* a child window */ @@ -759,7 +757,7 @@ void X11DRV_WND_SetWindowPos(WND *wndPtr, const WINDOWPOS *winpos, BOOL bChangeP if (changeMask && X11DRV_WND_GetXWindow(winposPtr)) { TSXReconfigureWMWindow( display, X11DRV_WND_GetXWindow(winposPtr), 0, changeMask, &winChanges ); - if( winposPtr->class->style & (CS_VREDRAW | CS_HREDRAW) ) + if( winposPtr->clsStyle & (CS_VREDRAW | CS_HREDRAW) ) X11DRV_WND_SetHostAttr( winposPtr, HAK_BITGRAVITY, BGForget ); } } @@ -937,7 +935,7 @@ void X11DRV_WND_SetDrawable(WND *wndPtr, HDC hdc, WORD flags, BOOL bSetClipOrigi * modify the origin and reset the clipping. When the clipping is set, * it is moved according to the new DC origin. */ - if ( (wndPtr->class->style & (CS_OWNDC | CS_CLASSDC)) && (dc->hClipRgn > 0)) + if ( (wndPtr->clsStyle & (CS_OWNDC | CS_CLASSDC)) && (dc->hClipRgn > 0)) { dcOrgXCopy = dc->DCOrgX; dcOrgYCopy = dc->DCOrgY;