Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51137 Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- dlls/comctl32/Makefile.in | 2 - dlls/comctl32/comctl32.h | 4 - dlls/comctl32/commctrl.c | 7 +- dlls/comctl32/theming.c | 157 ------------------ dlls/user32/defdlg.c | 35 +++- dlls/user32/hook.c | 1 + dlls/user32/user_private.h | 1 + dlls/uxtheme/Makefile.in | 1 + .../theme_dialog.c => uxtheme/dialog.c} | 25 ++- dlls/uxtheme/system.c | 1 + dlls/uxtheme/uxthemedll.h | 1 + include/winuser.h | 1 + 12 files changed, 45 insertions(+), 191 deletions(-) delete mode 100644 dlls/comctl32/theming.c rename dlls/{comctl32/theme_dialog.c => uxtheme/dialog.c} (81%)
diff --git a/dlls/comctl32/Makefile.in b/dlls/comctl32/Makefile.in index bd99d8f0276..63bfbf0892c 100644 --- a/dlls/comctl32/Makefile.in +++ b/dlls/comctl32/Makefile.in @@ -37,8 +37,6 @@ C_SRCS = \ syslink.c \ tab.c \ taskdialog.c \ - theme_dialog.c \ - theming.c \ toolbar.c \ tooltips.c \ trackbar.c \ diff --git a/dlls/comctl32/comctl32.h b/dlls/comctl32/comctl32.h index 66b341ae5ad..44d3b43ab9b 100644 --- a/dlls/comctl32/comctl32.h +++ b/dlls/comctl32/comctl32.h @@ -280,8 +280,4 @@ int MONTHCAL_MonthLength(int month, int year) DECLSPEC_HIDDEN; int MONTHCAL_CalculateDayOfWeek(SYSTEMTIME *date, BOOL inplace) DECLSPEC_HIDDEN; LONG MONTHCAL_CompareSystemTime(const SYSTEMTIME *first, const SYSTEMTIME *second) DECLSPEC_HIDDEN;
-extern void THEMING_Initialize(void) DECLSPEC_HIDDEN; -extern void THEMING_Uninitialize(void) DECLSPEC_HIDDEN; -extern LRESULT THEMING_CallOriginalClass(HWND, UINT, WPARAM, LPARAM) DECLSPEC_HIDDEN; - #endif /* __WINE_COMCTL32_H */ diff --git a/dlls/comctl32/commctrl.c b/dlls/comctl32/commctrl.c index cb9c22a3a88..1c7718e2400 100644 --- a/dlls/comctl32/commctrl.c +++ b/dlls/comctl32/commctrl.c @@ -72,6 +72,7 @@ #define NO_SHLWAPI_STREAM #include "shlwapi.h" #include "comctl32.h" +#include "uxtheme.h" #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(commctrl); @@ -208,14 +209,12 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) TREEVIEW_Register (); UPDOWN_Register ();
- /* subclass user32 controls */ - THEMING_Initialize (); + /* Call IsThemeActive() so that delay-loaded uxtheme.dll is loaded for hooking user32 */ + IsThemeActive(); break;
case DLL_PROCESS_DETACH: if (lpvReserved) break; - /* clean up subclassing */ - THEMING_Uninitialize();
/* unregister all common control classes */ ANIMATE_Unregister (); diff --git a/dlls/comctl32/theming.c b/dlls/comctl32/theming.c deleted file mode 100644 index c74bcfc36a2..00000000000 --- a/dlls/comctl32/theming.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Theming - Initialization - * - * Copyright (c) 2005 by Frank Richter - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#include <stdarg.h> - -#include "windef.h" -#include "winbase.h" -#include "wingdi.h" -#include "winuser.h" -#include "comctl32.h" -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(theming); - -typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM, - ULONG_PTR); - -extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM, - ULONG_PTR) DECLSPEC_HIDDEN; - -static const WCHAR dialogClass[] = L"#32770"; - -static const struct ThemingSubclass -{ - const WCHAR* className; - THEMING_SUBCLASSPROC subclassProc; -} subclasses[] = { - /* Note: list must be sorted by class name */ - {dialogClass, THEMING_DialogSubclassProc}, -}; - -#define NUM_SUBCLASSES (ARRAY_SIZE(subclasses)) - -static WNDPROC originalProcs[NUM_SUBCLASSES]; -static ATOM atRefDataProp; -static ATOM atSubclassProp; - -/* Generate a number of subclass window procs. - * With a single proc alone, we can't really reliably find out the superclass, - * so have one for each subclass. The subclass number is also stored in a prop - * since it's needed by THEMING_CallOriginalClass(). Then, the subclass - * proc and ref data are fetched and the proc called. - */ -#define MAKE_SUBCLASS_PROC(N) \ -static LRESULT CALLBACK subclass_proc ## N (HWND wnd, UINT msg, \ - WPARAM wParam, LPARAM lParam) \ -{ \ - LRESULT result; \ - ULONG_PTR refData; \ - SetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp), (HANDLE)N); \ - refData = (ULONG_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atRefDataProp)); \ - TRACE ("%d; (%p, %x, %lx, %lx, %lx)\n", N, wnd, msg, wParam, lParam, \ - refData); \ - result = subclasses[N].subclassProc (wnd, msg, wParam, lParam, refData);\ - TRACE ("result = %lx\n", result); \ - return result; \ -} - -MAKE_SUBCLASS_PROC(0) - -static const WNDPROC subclassProcs[NUM_SUBCLASSES] = { - subclass_proc0, -}; - -/*********************************************************************** - * THEMING_Initialize - * - * Register classes for standard controls that will shadow the system - * classes. - */ -void THEMING_Initialize (void) -{ - unsigned int i; - - atSubclassProp = GlobalAddAtomW (L"CC32ThemingSubCl"); - atRefDataProp = GlobalAddAtomW (L"CC32ThemingData"); - - for (i = 0; i < NUM_SUBCLASSES; i++) - { - WNDCLASSEXW class; - - class.cbSize = sizeof(class); - if (!GetClassInfoExW (NULL, subclasses[i].className, &class)) - { - ERR("Could not retrieve information for class %s\n", - debugstr_w (subclasses[i].className)); - continue; - } - originalProcs[i] = class.lpfnWndProc; - class.lpfnWndProc = subclassProcs[i]; - - if (!class.lpfnWndProc) - { - ERR("Missing proc for class %s\n", - debugstr_w (subclasses[i].className)); - continue; - } - - if (!RegisterClassExW (&class)) - { - ERR("Could not re-register class %s: %x\n", - debugstr_w (subclasses[i].className), GetLastError ()); - } - else - { - TRACE("Re-registered class %s\n", - debugstr_w (subclasses[i].className)); - } - } -} - -/*********************************************************************** - * THEMING_Uninitialize - * - * Unregister shadow classes for standard controls. - */ -void THEMING_Uninitialize (void) -{ - unsigned int i; - - if (!atSubclassProp) return; /* not initialized */ - - for (i = 0; i < NUM_SUBCLASSES; i++) - { - UnregisterClassW (subclasses[i].className, NULL); - } -} - -/*********************************************************************** - * THEMING_CallOriginalClass - * - * Determines the original window proc and calls it. - */ -LRESULT THEMING_CallOriginalClass (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - INT_PTR subclass = (INT_PTR)GetPropW (wnd, (LPCWSTR)MAKEINTATOM(atSubclassProp)); - WNDPROC oldProc = originalProcs[subclass]; - return CallWindowProcW (oldProc, wnd, msg, wParam, lParam); -} diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c index 00a73c6b927..4f44a93cd49 100644 --- a/dlls/user32/defdlg.c +++ b/dlls/user32/defdlg.c @@ -354,10 +354,7 @@ out: return dlgInfo; }
-/*********************************************************************** - * DefDlgProcA (USER32.@) - */ -LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +static LRESULT USER_DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { DIALOGINFO *dlgInfo; DLGPROC dlgproc; @@ -411,11 +408,7 @@ LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) return GetWindowLongPtrW( hwnd, DWLP_MSGRESULT ); }
- -/*********************************************************************** - * DefDlgProcW (USER32.@) - */ -LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +static LRESULT USER_DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) { DIALOGINFO *dlgInfo; DLGPROC dlgproc; @@ -468,3 +461,27 @@ LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
return GetWindowLongPtrW( hwnd, DWLP_MSGRESULT ); } + +LRESULT WINAPI USER_DefDlgProc( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode ) +{ + if (unicode) + return USER_DefDlgProcW( hwnd, msg, wParam, lParam ); + else + return USER_DefDlgProcA( hwnd, msg, wParam, lParam ); +} + +/*********************************************************************** + * DefDlgProcA (USER32.@) + */ +LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + return user_api->pDefDlgProc( hwnd, msg, wParam, lParam, FALSE ); +} + +/*********************************************************************** + * DefDlgProcW (USER32.@) + */ +LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam ) +{ + return user_api->pDefDlgProc( hwnd, msg, wParam, lParam, TRUE ); +} diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c index 8f542a6cffd..c4e71ec49b6 100644 --- a/dlls/user32/hook.c +++ b/dlls/user32/hook.c @@ -83,6 +83,7 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
static struct user_api_hook original_user_api = { + USER_DefDlgProc, USER_ScrollBarProc, }; static struct user_api_hook hooked_user_api; diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h index 1e3786c2b1e..8750008a5fb 100644 --- a/dlls/user32/user_private.h +++ b/dlls/user32/user_private.h @@ -387,6 +387,7 @@ struct png_funcs #endif
extern struct user_api_hook *user_api DECLSPEC_HIDDEN; +LRESULT WINAPI USER_DefDlgProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN; LRESULT WINAPI USER_ScrollBarProc(HWND, UINT, WPARAM, LPARAM, BOOL) DECLSPEC_HIDDEN;
#endif /* __WINE_USER_PRIVATE_H */ diff --git a/dlls/uxtheme/Makefile.in b/dlls/uxtheme/Makefile.in index f252f423a97..d272e049cf9 100644 --- a/dlls/uxtheme/Makefile.in +++ b/dlls/uxtheme/Makefile.in @@ -7,6 +7,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \ buffer.c \ + dialog.c \ draw.c \ main.c \ metric.c \ diff --git a/dlls/comctl32/theme_dialog.c b/dlls/uxtheme/dialog.c similarity index 81% rename from dlls/comctl32/theme_dialog.c rename to dlls/uxtheme/dialog.c index 0f7835ae32f..043346b24e2 100644 --- a/dlls/comctl32/theme_dialog.c +++ b/dlls/uxtheme/dialog.c @@ -28,16 +28,11 @@ #include "wingdi.h" #include "winuser.h" #include "uxtheme.h" +#include "uxthemedll.h" #include "vssym32.h" -#include "comctl32.h" #include "wine/debug.h"
-/********************************************************************** - * The dialog subclass window proc. - */ -LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, - WPARAM wParam, LPARAM lParam, - ULONG_PTR dwRefData) +LRESULT WINAPI UXTHEME_DefDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode) { HTHEME theme = GetWindowTheme ( hWnd ); static const WCHAR themeClass[] = L"Window"; @@ -48,7 +43,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, switch (msg) { case WM_CREATE: - result = THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + result = user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode); theme = OpenThemeData( hWnd, themeClass ); return result;
@@ -56,7 +51,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, CloseThemeData ( theme ); SetWindowTheme( hWnd, NULL, NULL ); OpenThemeData( hWnd, NULL ); - return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
case WM_THEMECHANGED: CloseThemeData ( theme ); @@ -65,7 +60,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, return 0;
case WM_ERASEBKGND: - if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + if (!doTheming) return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode); { RECT rc; WNDPROC dlgp = (WNDPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC); @@ -82,7 +77,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, DrawThemeBackground (theme, (HDC)wParam, WP_DIALOG, 0, &rc, NULL); #endif - return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode); else /* We might have gotten a TAB theme class, so check if we can * draw as a tab page. */ @@ -90,13 +85,13 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, DrawThemeBackground (theme, (HDC)wParam, TABP_BODY, 0, &rc, NULL); else - return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode); } return 1; }
case WM_CTLCOLORSTATIC: - if (!doTheming) return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + if (!doTheming) return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode); { WNDPROC dlgp = (WNDPROC)GetWindowLongPtrW (hWnd, DWLP_DLGPROC); LRESULT result = CallWindowProcW(dlgp, hWnd, msg, wParam, lParam); @@ -121,7 +116,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg, return (LRESULT)GetStockObject (NULL_BRUSH); } else - return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode);
} return result; @@ -129,7 +124,7 @@ LRESULT CALLBACK THEMING_DialogSubclassProc (HWND hWnd, UINT msg,
default: /* Call old proc */ - return THEMING_CallOriginalClass (hWnd, msg, wParam, lParam); + return user_api.pDefDlgProc(hWnd, msg, wParam, lParam, unicode); } return 0; } diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c index a7051a2eb05..f5ddc20eb08 100644 --- a/dlls/uxtheme/system.c +++ b/dlls/uxtheme/system.c @@ -1229,6 +1229,7 @@ BOOL WINAPI ThemeHooksInstall(void) { struct user_api_hook hooks;
+ hooks.pDefDlgProc = UXTHEME_DefDlgProc; hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc; return __wine_register_user_api_hook(&hooks, &user_api); } diff --git a/dlls/uxtheme/uxthemedll.h b/dlls/uxtheme/uxthemedll.h index 7a085b8a3f1..67932f22f88 100644 --- a/dlls/uxtheme/uxthemedll.h +++ b/dlls/uxtheme/uxthemedll.h @@ -102,6 +102,7 @@ extern void UXTHEME_InitSystem(HINSTANCE hInst) DECLSPEC_HIDDEN; extern void UXTHEME_UninitSystem(void) DECLSPEC_HIDDEN;
extern struct user_api_hook user_api DECLSPEC_HIDDEN; +LRESULT WINAPI UXTHEME_DefDlgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL unicode) DECLSPEC_HIDDEN; LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode) DECLSPEC_HIDDEN;
diff --git a/include/winuser.h b/include/winuser.h index 88fdbbf72fc..6df5ead5bc5 100644 --- a/include/winuser.h +++ b/include/winuser.h @@ -4411,6 +4411,7 @@ WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RA /* Uxtheme hook functions and struct */ struct user_api_hook { + LRESULT (WINAPI *pDefDlgProc)(HWND, UINT, WPARAM, LPARAM, BOOL); LRESULT (WINAPI *pScrollBarWndProc)(HWND, UINT, WPARAM, LPARAM, BOOL); };