[PATCH 1/5] uxtheme: Move themed scroll bar to uxtheme.

Zhiyi Zhang zzhang at codeweavers.com
Wed Jul 7 03:12:56 CDT 2021


Signed-off-by: Zhiyi Zhang <zzhang at codeweavers.com>
---
 dlls/comctl32/Makefile.in                     |  1 -
 dlls/comctl32/theming.c                       |  5 ----
 dlls/user32/hook.c                            | 28 +++++++++++++++++++
 dlls/user32/scroll.c                          | 13 +++++----
 dlls/user32/user32.spec                       |  2 ++
 dlls/user32/user_private.h                    |  3 ++
 dlls/uxtheme/Makefile.in                      |  1 +
 .../theme_scrollbar.c => uxtheme/scrollbar.c} | 21 +++++++-------
 dlls/uxtheme/system.c                         | 18 ++++++++++++
 dlls/uxtheme/uxtheme.spec                     |  4 +--
 dlls/uxtheme/uxthemedll.h                     |  8 ++++++
 include/winuser.h                             |  9 ++++++
 12 files changed, 89 insertions(+), 24 deletions(-)
 rename dlls/{comctl32/theme_scrollbar.c => uxtheme/scrollbar.c} (95%)

diff --git a/dlls/comctl32/Makefile.in b/dlls/comctl32/Makefile.in
index 4ea068ea731..bd99d8f0276 100644
--- a/dlls/comctl32/Makefile.in
+++ b/dlls/comctl32/Makefile.in
@@ -38,7 +38,6 @@ C_SRCS = \
 	tab.c \
 	taskdialog.c \
 	theme_dialog.c \
-	theme_scrollbar.c \
 	theming.c \
 	toolbar.c \
 	tooltips.c \
diff --git a/dlls/comctl32/theming.c b/dlls/comctl32/theming.c
index 8078e661b76..c74bcfc36a2 100644
--- a/dlls/comctl32/theming.c
+++ b/dlls/comctl32/theming.c
@@ -35,8 +35,6 @@ typedef LRESULT (CALLBACK* THEMING_SUBCLASSPROC)(HWND, UINT, WPARAM, LPARAM,
 
 extern LRESULT CALLBACK THEMING_DialogSubclassProc (HWND, UINT, WPARAM, LPARAM,
                                                     ULONG_PTR) DECLSPEC_HIDDEN;
-extern LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND, UINT, WPARAM, LPARAM,
-                                                       ULONG_PTR) DECLSPEC_HIDDEN;
 
 static const WCHAR dialogClass[] = L"#32770";
 
@@ -47,7 +45,6 @@ static const struct ThemingSubclass
 } subclasses[] = {
     /* Note: list must be sorted by class name */
     {dialogClass,          THEMING_DialogSubclassProc},
-    {WC_SCROLLBARW,        THEMING_ScrollbarSubclassProc}
 };
 
 #define NUM_SUBCLASSES        (ARRAY_SIZE(subclasses))
@@ -78,11 +75,9 @@ static LRESULT CALLBACK subclass_proc ## N (HWND wnd, UINT msg,             \
 }
 
 MAKE_SUBCLASS_PROC(0)
-MAKE_SUBCLASS_PROC(1)
 
 static const WNDPROC subclassProcs[NUM_SUBCLASSES] = {
     subclass_proc0,
-    subclass_proc1,
 };
 
 /***********************************************************************
diff --git a/dlls/user32/hook.c b/dlls/user32/hook.c
index 4c6dbcf7202..8f542a6cffd 100644
--- a/dlls/user32/hook.c
+++ b/dlls/user32/hook.c
@@ -81,6 +81,13 @@
 WINE_DEFAULT_DEBUG_CHANNEL(hook);
 WINE_DECLARE_DEBUG_CHANNEL(relay);
 
+static struct user_api_hook original_user_api =
+{
+    USER_ScrollBarProc,
+};
+static struct user_api_hook hooked_user_api;
+struct user_api_hook *user_api = &original_user_api;
+
 struct hook_info
 {
     INT id;
@@ -961,3 +968,24 @@ BOOL WINAPI IsWinEventHookInstalled(DWORD dwEvent)
     WARN("(%d)-stub!\n", dwEvent);
     return TRUE;
 }
+
+/* Uxtheme hook function, similar to the undocumented RegisterUserApiHook() */
+BOOL CDECL __wine_register_user_api_hook(const struct user_api_hook *new, struct user_api_hook *old)
+{
+    if (!new)
+        return FALSE;
+
+    USER_Lock();
+    hooked_user_api = *new;
+    user_api = &hooked_user_api;
+    if (old)
+        *old = original_user_api;
+    USER_Unlock();
+    return TRUE;
+}
+
+/* Similar to the undocumented UnregisterUserApiHook() */
+void CDECL __wine_unregister_user_api_hook(void)
+{
+    InterlockedExchangePointer((void **)&user_api, &original_user_api);
+}
diff --git a/dlls/user32/scroll.c b/dlls/user32/scroll.c
index 5561509c50c..9a22e930332 100644
--- a/dlls/user32/scroll.c
+++ b/dlls/user32/scroll.c
@@ -1317,11 +1317,7 @@ static BOOL SCROLL_SetScrollRange(HWND hwnd, INT nBar, INT minVal, INT maxVal)
     return TRUE;
 }
 
-
-/***********************************************************************
- *           ScrollBarWndProc_common
- */
-LRESULT ScrollBarWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode )
+LRESULT WINAPI USER_ScrollBarProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, BOOL unicode )
 {
     if (!IsWindow( hwnd )) return 0;
 
@@ -1496,6 +1492,13 @@ LRESULT ScrollBarWndProc_common( HWND hwnd, UINT message, WPARAM wParam, LPARAM
     return 0;
 }
 
+/***********************************************************************
+ *           ScrollBarWndProc_common
+ */
+LRESULT ScrollBarWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, BOOL unicode )
+{
+     return user_api->pScrollBarWndProc( hwnd, msg, wParam, lParam, unicode );
+}
 
 /*************************************************************************
  *           SetScrollInfo   (USER32.@)
diff --git a/dlls/user32/user32.spec b/dlls/user32/user32.spec
index 391e304a063..4cc312f9784 100644
--- a/dlls/user32/user32.spec
+++ b/dlls/user32/user32.spec
@@ -835,5 +835,7 @@
 # All functions must be prefixed with '__wine_' (for internal functions)
 # or 'wine_' (for user-visible functions) to avoid namespace conflicts.
 #
+@ cdecl __wine_register_user_api_hook(ptr ptr)
 @ cdecl __wine_send_input(long ptr ptr)
 @ cdecl __wine_set_pixel_format(long long)
+@ cdecl __wine_unregister_user_api_hook()
diff --git a/dlls/user32/user_private.h b/dlls/user32/user_private.h
index 0838ba28b32..1e3786c2b1e 100644
--- a/dlls/user32/user_private.h
+++ b/dlls/user32/user_private.h
@@ -386,4 +386,7 @@ struct png_funcs
 #define assert(expr) ((void)0)
 #endif
 
+extern struct user_api_hook *user_api 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 61817ee5468..f252f423a97 100644
--- a/dlls/uxtheme/Makefile.in
+++ b/dlls/uxtheme/Makefile.in
@@ -12,6 +12,7 @@ C_SRCS = \
 	metric.c \
 	msstyles.c \
 	property.c \
+	scrollbar.c \
 	stylemap.c \
 	system.c \
 	uxini.c
diff --git a/dlls/comctl32/theme_scrollbar.c b/dlls/uxtheme/scrollbar.c
similarity index 95%
rename from dlls/comctl32/theme_scrollbar.c
rename to dlls/uxtheme/scrollbar.c
index 7cc59bbd1e5..393b45a831d 100644
--- a/dlls/comctl32/theme_scrollbar.c
+++ b/dlls/uxtheme/scrollbar.c
@@ -28,8 +28,8 @@
 #include "wingdi.h"
 #include "winuser.h"
 #include "uxtheme.h"
+#include "uxthemedll.h"
 #include "vssym32.h"
-#include "comctl32.h"
 #include "wine/debug.h"
 
 /* Minimum size of the thumb in pixels */
@@ -525,27 +525,26 @@ static void paint_scrollbar(HWND hwnd, HTHEME theme)
     EndPaint(hwnd, &ps);
 }
 
-LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
-                                                WPARAM wParam, LPARAM lParam,
-                                                ULONG_PTR dwRefData)
+LRESULT WINAPI UXTHEME_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
+                                        BOOL unicode)
 {
     const WCHAR* themeClass = WC_SCROLLBARW;
     HTHEME theme;
     LRESULT result;
     POINT pt;
 
-    TRACE("(%p, 0x%x, %lu, %lu, %lu)\n", hwnd, msg, wParam, lParam, dwRefData);
+    TRACE("(%p, 0x%x, %lu, %lu, %d)\n", hwnd, msg, wParam, lParam, unicode);
 
     switch (msg) {
         case WM_CREATE:
-            result = THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            result = user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
             OpenThemeData(hwnd, themeClass);
             return result;
 
         case WM_DESTROY:
             theme = GetWindowTheme(hwnd);
             CloseThemeData(theme);
-            return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
 
         case WM_THEMECHANGED:
             theme = GetWindowTheme(hwnd);
@@ -556,14 +555,14 @@ LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
 
         case WM_SYSCOLORCHANGE:
             theme = GetWindowTheme(hwnd);
-            if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
             /* Do nothing. When themed, a WM_THEMECHANGED will be received, too,
              * which will do the repaint. */
             break;
 
         case WM_PAINT:
             theme = GetWindowTheme(hwnd);
-            if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
 
             paint_scrollbar(hwnd, theme);
             break;
@@ -571,7 +570,7 @@ LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
         case WM_MOUSEMOVE:
         case WM_MOUSELEAVE:
             theme = GetWindowTheme(hwnd);
-            if (!theme) return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            if (!theme) return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
 
             pt.x = (short)LOWORD(lParam);
             pt.y = (short)HIWORD(lParam);
@@ -579,7 +578,7 @@ LRESULT CALLBACK THEMING_ScrollbarSubclassProc (HWND hwnd, UINT msg,
             break;
 
         default:
-            return THEMING_CallOriginalClass(hwnd, msg, wParam, lParam);
+            return user_api.pScrollBarWndProc(hwnd, msg, wParam, lParam, unicode);
     }
 
     return 0;
diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c
index dcd2a660042..a7051a2eb05 100644
--- a/dlls/uxtheme/system.c
+++ b/dlls/uxtheme/system.c
@@ -55,6 +55,8 @@ static WCHAR szCurrentTheme[MAX_PATH];
 static WCHAR szCurrentColor[64];
 static WCHAR szCurrentSize[64];
 
+struct user_api_hook user_api = {0};
+
 /***********************************************************************/
 
 static BOOL CALLBACK UXTHEME_broadcast_msg_enumchild (HWND hWnd, LPARAM msg)
@@ -507,10 +509,12 @@ void UXTHEME_InitSystem(HINSTANCE hInst)
     atDialogThemeEnabled = GlobalAddAtomW(L"ux_dialogtheme");
 
     UXTHEME_LoadTheme();
+    ThemeHooksInstall();
 }
 
 void UXTHEME_UninitSystem(void)
 {
+    ThemeHooksRemove();
     MSSTYLES_SetActiveTheme(NULL, FALSE);
 
     GlobalDeleteAtom(atWindowTheme);
@@ -1220,3 +1224,17 @@ HRESULT WINAPI CheckThemeSignature(LPCWSTR pszThemeFileName)
     MSSTYLES_CloseThemeFile(pt);
     return S_OK;
 }
+
+BOOL WINAPI ThemeHooksInstall(void)
+{
+    struct user_api_hook hooks;
+
+    hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc;
+    return __wine_register_user_api_hook(&hooks, &user_api);
+}
+
+BOOL WINAPI ThemeHooksRemove(void)
+{
+    __wine_unregister_user_api_hook();
+    return TRUE;
+}
diff --git a/dlls/uxtheme/uxtheme.spec b/dlls/uxtheme/uxtheme.spec
index 632129b8104..22b1fc4ac3c 100644
--- a/dlls/uxtheme/uxtheme.spec
+++ b/dlls/uxtheme/uxtheme.spec
@@ -29,8 +29,8 @@
 31 stub -noname InitUserTheme
 32 stub -noname InitUserRegistry
 33 stub -noname ReestablishServerConnection
-34 stub -noname ThemeHooksInstall
-35 stub -noname ThemeHooksRemove
+34 stdcall -noname ThemeHooksInstall()
+35 stdcall -noname ThemeHooksRemove()
 36 stub -noname RefreshThemeForTS
 43 stub -noname ClassicGetSystemMetrics
 44 stub -noname ClassicSystemParametersInfoA
diff --git a/dlls/uxtheme/uxthemedll.h b/dlls/uxtheme/uxthemedll.h
index fdf529b422a..7a085b8a3f1 100644
--- a/dlls/uxtheme/uxthemedll.h
+++ b/dlls/uxtheme/uxthemedll.h
@@ -21,6 +21,8 @@
 #ifndef __WINE_UXTHEMEDLL_H
 #define __WINE_UXTHEMEDLL_H
 
+#include <winuser.h>
+
 typedef HANDLE HTHEMEFILE;
 
 /**********************************************************************
@@ -93,10 +95,16 @@ HRESULT WINAPI EnumThemeSizes(LPWSTR pszThemeFileName, LPWSTR pszColorName,
                               DWORD dwSizeNum, PTHEMENAMES pszColorNames) DECLSPEC_HIDDEN;
 HRESULT WINAPI ParseThemeIniFile(LPCWSTR pszIniFileName, LPWSTR pszUnknown,
                                  ParseThemeIniFileProc callback, LPVOID lpData) DECLSPEC_HIDDEN;
+BOOL WINAPI ThemeHooksInstall(void) DECLSPEC_HIDDEN;
+BOOL WINAPI ThemeHooksRemove(void) DECLSPEC_HIDDEN;
 
 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_ScrollbarWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam,
+                                        BOOL unicode) DECLSPEC_HIDDEN;
+
 /* No alpha blending */
 #define ALPHABLEND_NONE             0
 /* "Cheap" binary alpha blending - but possibly faster */
diff --git a/include/winuser.h b/include/winuser.h
index 0b1571c0a95..88fdbbf72fc 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -4407,6 +4407,15 @@ WORD        WINAPI SYSTEM_KillSystemTimer( WORD );
 
 #ifdef __WINESRC__
 WINUSERAPI BOOL CDECL __wine_send_input( HWND hwnd, const INPUT *input, const RAWINPUT *rawinput );
+
+/* Uxtheme hook functions and struct */
+struct user_api_hook
+{
+    LRESULT (WINAPI *pScrollBarWndProc)(HWND, UINT, WPARAM, LPARAM, BOOL);
+};
+
+BOOL CDECL __wine_register_user_api_hook(const struct user_api_hook *new, struct user_api_hook *old);
+void CDECL __wine_unregister_user_api_hook(void);
 #endif
 
 #ifdef __cplusplus
-- 
2.30.2




More information about the wine-devel mailing list