uxtheme: Move themed dialog to uxtheme.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51137
Signed-off-by: Zhiyi Zhang <zzhang@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2021-07-20 21:04:24 +08:00 committed by Alexandre Julliard
parent d9063802f2
commit b0e51ead0d
12 changed files with 45 additions and 191 deletions

View File

@ -37,8 +37,6 @@ C_SRCS = \
syslink.c \
tab.c \
taskdialog.c \
theme_dialog.c \
theming.c \
toolbar.c \
tooltips.c \
trackbar.c \

View File

@ -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 */

View File

@ -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 ();

View File

@ -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);
}

View File

@ -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 );
}

View File

@ -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;

View File

@ -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 */

View File

@ -7,6 +7,7 @@ EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
buffer.c \
dialog.c \
draw.c \
main.c \
metric.c \

View File

@ -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;
}

View File

@ -1229,6 +1229,7 @@ BOOL WINAPI ThemeHooksInstall(void)
{
struct user_api_hook hooks;
hooks.pDefDlgProc = UXTHEME_DefDlgProc;
hooks.pScrollBarWndProc = UXTHEME_ScrollbarWndProc;
return RegisterUserApiHook(&hooks, &user_api);
}

View File

@ -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;

View File

@ -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);
};