[PATCH 2/5] uxtheme: Move themed dialog to uxtheme.

Zhiyi Zhang zzhang at codeweavers.com
Wed Jul 7 03:13:05 CDT 2021


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51137
Signed-off-by: Zhiyi Zhang <zzhang at 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);
 };
 
-- 
2.30.2




More information about the wine-devel mailing list