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..9a1d010525a 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; } + +/* Undocumented RegisterUserApiHook() */ +BOOL WINAPI RegisterUserApiHook(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; +} + +/* Undocumented UnregisterUserApiHook() */ +void WINAPI UnregisterUserApiHook(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..8d3ac70210c 100644 --- a/dlls/user32/user32.spec +++ b/dlls/user32/user32.spec @@ -612,7 +612,7 @@ @ stdcall RegisterTasklist (long) @ stdcall RegisterTouchHitTestingWindow(long long) @ stdcall RegisterTouchWindow(long long) -# @ stub RegisterUserApiHook +@ stdcall RegisterUserApiHook(ptr ptr) @ stdcall RegisterWindowMessageA(str) @ stdcall RegisterWindowMessageW(wstr) @ stdcall ReleaseCapture() @@ -784,7 +784,7 @@ # @ stub UnregisterMessagePumpHook @ stdcall UnregisterPowerSettingNotification(ptr) @ stdcall UnregisterTouchWindow(long) -# @ stub UnregisterUserApiHook +@ stdcall UnregisterUserApiHook() @ stdcall UpdateLayeredWindow(long long ptr ptr long ptr long ptr long) @ stdcall UpdateLayeredWindowIndirect(long ptr) @ stub UpdatePerUserSystemParameters 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..84b5cbc5fbc 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 RegisterUserApiHook(&hooks, &user_api); +} + +BOOL WINAPI ThemeHooksRemove(void) +{ + UnregisterUserApiHook(); + 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 + 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..5ad9b3ab70b 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); +}; + +WINUSERAPI BOOL WINAPI RegisterUserApiHook(const struct user_api_hook *new, struct user_api_hook *old); +WINUSERAPI void WINAPI UnregisterUserApiHook(void); #endif #ifdef __cplusplus