From 615a90e2192231ac6d37b3d336b4abfc996d96f4 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Wed, 1 Sep 2021 14:37:38 +0800 Subject: [PATCH] uxtheme: Implement OpenThemeDataForDpi(). Signed-off-by: Zhiyi Zhang Signed-off-by: Alexandre Julliard --- dlls/uxtheme/msstyles.c | 4 +++- dlls/uxtheme/msstyles.h | 3 ++- dlls/uxtheme/system.c | 31 +++++++++++++++++++++++++------ dlls/uxtheme/tests/system.c | 31 +++++++++++++++++++++++++++++++ dlls/uxtheme/uxtheme.spec | 1 + include/uxtheme.h | 1 + 6 files changed, 63 insertions(+), 8 deletions(-) diff --git a/dlls/uxtheme/msstyles.c b/dlls/uxtheme/msstyles.c index 6f74d2d3d7d..99eda64233c 100644 --- a/dlls/uxtheme/msstyles.c +++ b/dlls/uxtheme/msstyles.c @@ -971,8 +971,9 @@ static void MSSTYLES_ParseThemeIni(PTHEME_FILE tf, BOOL setMetrics) * pszAppName Application name, for theme styles specific * to a particular application * pszClassList List of requested classes, semicolon delimited + * dpi DPI for theme parts */ -PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList) +PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList, UINT dpi) { PTHEME_CLASS cls = NULL; WCHAR szClassName[MAX_THEME_CLASS_NAME]; @@ -1004,6 +1005,7 @@ PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList) TRACE("Opened app %s, class %s from list %s\n", debugstr_w(cls->szAppName), debugstr_w(cls->szClassName), debugstr_w(pszClassList)); cls->tf = tfActiveTheme; cls->tf->dwRefCount++; + cls->dpi = dpi; } return cls; } diff --git a/dlls/uxtheme/msstyles.h b/dlls/uxtheme/msstyles.h index 0b7e1ab35cc..1cb27b93ab3 100644 --- a/dlls/uxtheme/msstyles.h +++ b/dlls/uxtheme/msstyles.h @@ -53,6 +53,7 @@ typedef struct _THEME_CLASS { struct _THEME_FILE* tf; WCHAR szAppName[MAX_THEME_APP_NAME]; WCHAR szClassName[MAX_THEME_CLASS_NAME]; + UINT dpi; PTHEME_PARTSTATE partstate; struct _THEME_CLASS *overrides; @@ -87,7 +88,7 @@ typedef struct _UXINI_FILE *PUXINI_FILE; HRESULT MSSTYLES_OpenThemeFile(LPCWSTR lpThemeFile, LPCWSTR pszColorName, LPCWSTR pszSizeName, PTHEME_FILE *tf) DECLSPEC_HIDDEN; void MSSTYLES_CloseThemeFile(PTHEME_FILE tf) DECLSPEC_HIDDEN; HRESULT MSSTYLES_SetActiveTheme(PTHEME_FILE tf, BOOL setMetrics) DECLSPEC_HIDDEN; -PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList) DECLSPEC_HIDDEN; +PTHEME_CLASS MSSTYLES_OpenThemeClass(LPCWSTR pszAppName, LPCWSTR pszClassList, UINT dpi) DECLSPEC_HIDDEN; HRESULT MSSTYLES_CloseThemeClass(PTHEME_CLASS tc) DECLSPEC_HIDDEN; BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, int *dwPrimitive, int *dwId) DECLSPEC_HIDDEN; BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue) DECLSPEC_HIDDEN; diff --git a/dlls/uxtheme/system.c b/dlls/uxtheme/system.c index afae1e23f2b..ca0dd228b2c 100644 --- a/dlls/uxtheme/system.c +++ b/dlls/uxtheme/system.c @@ -617,10 +617,7 @@ static LPWSTR UXTHEME_GetWindowProperty(HWND hwnd, ATOM aProp, LPWSTR pszBuffer, return NULL; } -/*********************************************************************** - * OpenThemeDataEx (UXTHEME.61) - */ -HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) +static HTHEME open_theme_data(HWND hwnd, LPCWSTR pszClassList, DWORD flags, UINT dpi) { WCHAR szAppBuff[256]; WCHAR szClassBuff[256]; @@ -647,11 +644,11 @@ HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) pszUseClassList = pszClassList; if (pszUseClassList) - hTheme = MSSTYLES_OpenThemeClass(pszAppName, pszUseClassList); + hTheme = MSSTYLES_OpenThemeClass(pszAppName, pszUseClassList, dpi); /* Fall back to default class if the specified subclass is not found */ if (!hTheme) - hTheme = MSSTYLES_OpenThemeClass(NULL, pszUseClassList); + hTheme = MSSTYLES_OpenThemeClass(NULL, pszUseClassList, dpi); } if(IsWindow(hwnd)) SetPropW(hwnd, (LPCWSTR)MAKEINTATOM(atWindowTheme), hTheme); @@ -661,6 +658,28 @@ HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) return hTheme; } +/*********************************************************************** + * OpenThemeDataEx (UXTHEME.61) + */ +HTHEME WINAPI OpenThemeDataEx(HWND hwnd, LPCWSTR pszClassList, DWORD flags) +{ + UINT dpi; + + dpi = GetDpiForWindow(hwnd); + if (!dpi) + dpi = 96; + + return open_theme_data(hwnd, pszClassList, flags, dpi); +} + +/*********************************************************************** + * OpenThemeDataForDpi (UXTHEME.@) + */ +HTHEME WINAPI OpenThemeDataForDpi(HWND hwnd, LPCWSTR class_list, UINT dpi) +{ + return open_theme_data(hwnd, class_list, 0, dpi); +} + /*********************************************************************** * OpenThemeData (UXTHEME.@) */ diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c index b3b1afde14e..584a71a82b4 100644 --- a/dlls/uxtheme/tests/system.c +++ b/dlls/uxtheme/tests/system.c @@ -34,6 +34,7 @@ #include "wine/test.h" static HTHEME (WINAPI * pOpenThemeDataEx)(HWND, LPCWSTR, DWORD); +static HTHEME (WINAPI *pOpenThemeDataForDpi)(HWND, LPCWSTR, UINT); static HPAINTBUFFER (WINAPI *pBeginBufferedPaint)(HDC, const RECT *, BP_BUFFERFORMAT, BP_PAINTPARAMS *, HDC *); static HRESULT (WINAPI *pBufferedPaintClear)(HPAINTBUFFER, const RECT *); static HRESULT (WINAPI *pEndBufferedPaint)(HPAINTBUFFER, BOOL); @@ -79,6 +80,7 @@ static void init_funcs(void) GET_PROC(uxtheme, GetBufferedPaintTargetDC) GET_PROC(uxtheme, GetBufferedPaintTargetRect) GET_PROC(uxtheme, OpenThemeDataEx) + GET_PROC(uxtheme, OpenThemeDataForDpi) GET_PROC(user32, DisplayConfigGetDeviceInfo) GET_PROC(user32, DisplayConfigSetDeviceInfo) @@ -642,6 +644,34 @@ static void test_OpenThemeDataEx(void) DestroyWindow(hWnd); } +static void test_OpenThemeDataForDpi(void) +{ + BOOL is_theme_active; + HTHEME htheme; + + if (!pOpenThemeDataForDpi) + { + win_skip("OpenThemeDataForDpi is unavailable.\n"); + return; + } + + is_theme_active = IsThemeActive(); + SetLastError(0xdeadbeef); + htheme = OpenThemeDataForDpi(NULL, WC_BUTTONW, 96); + if (is_theme_active) + { + ok(!!htheme, "Got a NULL handle.\n"); + ok(GetLastError() == NO_ERROR, "Expected error %u, got %u.\n", NO_ERROR, GetLastError()); + CloseThemeData(htheme); + } + else + { + ok(!htheme, "Got a non-NULL handle.\n"); + ok(GetLastError() == E_PROP_ID_UNSUPPORTED, "Expected error %u, got %u.\n", + E_PROP_ID_UNSUPPORTED, GetLastError()); + } +} + static void test_GetCurrentThemeName(void) { BOOL bThemeActive; @@ -1084,6 +1114,7 @@ START_TEST(system) test_SetWindowTheme(); test_OpenThemeData(); test_OpenThemeDataEx(); + test_OpenThemeDataForDpi(); test_GetCurrentThemeName(); test_GetThemePartSize(); test_CloseThemeData(); diff --git a/dlls/uxtheme/uxtheme.spec b/dlls/uxtheme/uxtheme.spec index 22b1fc4ac3c..140388245f2 100644 --- a/dlls/uxtheme/uxtheme.spec +++ b/dlls/uxtheme/uxtheme.spec @@ -106,6 +106,7 @@ @ stdcall IsThemeDialogTextureEnabled(ptr) @ stdcall IsThemePartDefined(ptr long long) @ stdcall OpenThemeData(ptr wstr) +@ stdcall OpenThemeDataForDpi(ptr wstr long) @ stdcall SetThemeAppProperties(long) @ stdcall SetWindowTheme(ptr wstr wstr) @ stdcall SetWindowThemeAttribute(ptr long ptr long) diff --git a/include/uxtheme.h b/include/uxtheme.h index 449dc6f6d40..384c3655b41 100644 --- a/include/uxtheme.h +++ b/include/uxtheme.h @@ -213,6 +213,7 @@ BOOL WINAPI IsThemeDialogTextureEnabled(HWND); BOOL WINAPI IsThemePartDefined(HTHEME,int,int); HTHEME WINAPI OpenThemeData(HWND,LPCWSTR); HTHEME WINAPI OpenThemeDataEx(HWND,LPCWSTR,DWORD); +HTHEME WINAPI OpenThemeDataForDpi(HWND,LPCWSTR,UINT); void WINAPI SetThemeAppProperties(DWORD); HRESULT WINAPI SetWindowTheme(HWND,LPCWSTR,LPCWSTR); HRESULT WINAPI SetWindowThemeAttribute(HWND,enum WINDOWTHEMEATTRIBUTETYPE,PVOID,DWORD);