Signed-off-by: Zhiyi Zhang zzhang@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