Fix Command Link glyphs not scaled according to DPI because a NULL device context handle was
passed to GetThemePartSize() and GetThemePartSize() was using a device context to get DPI.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/uxtheme/draw.c | 36 ++++++++++++++++++------------------
dlls/uxtheme/msstyles.c | 10 ++++++++++
dlls/uxtheme/msstyles.h | 1 +
dlls/uxtheme/tests/system.c | 1 -
4 files changed, 29 insertions(+), 19 deletions(-)
diff --git a/dlls/uxtheme/draw.c b/dlls/uxtheme/draw.c
index 4394f4943b7..a03217b65cf 100644
--- a/dlls/uxtheme/draw.c
+++ b/dlls/uxtheme/draw.c
@@ -172,7 +172,7 @@ static int imagefile_index_to_property(int index)
*
* Select the image to use
*/
-static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
+static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, int iPartId, int iStateId,
const RECT *pRect, BOOL glyph, int *imageDpi)
{
PTHEME_PROPERTY tp;
@@ -193,14 +193,15 @@ static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId,
if(imageselecttype == IST_DPI) {
int reqdpi = 0;
- int screendpi = GetDeviceCaps(hdc, LOGPIXELSX);
+ int dpi = MSSTYLES_GetThemeDPI(hTheme);
for (i = 7; i >= 1; i--)
{
reqdpi = 0;
if (SUCCEEDED(GetThemeInt(hTheme, iPartId, iStateId, mindpi_index_to_property(i),
&reqdpi)))
{
- if(reqdpi != 0 && screendpi >= reqdpi) {
+ if (reqdpi != 0 && dpi >= reqdpi)
+ {
TRACE("Using %d DPI, image %d\n", reqdpi, imagefile_index_to_property(i));
if (imageDpi)
@@ -269,9 +270,9 @@ static PTHEME_PROPERTY UXTHEME_SelectImage(HTHEME hTheme, HDC hdc, int iPartId,
*
* Load image for part/state
*/
-static HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId, int iStateId,
- const RECT *pRect, BOOL glyph, HBITMAP *hBmp, RECT *bmpRect,
- BOOL *hasImageAlpha, int *imageDpi)
+static HRESULT UXTHEME_LoadImage(HTHEME hTheme, int iPartId, int iStateId, const RECT *pRect,
+ BOOL glyph, HBITMAP *hBmp, RECT *bmpRect, BOOL *hasImageAlpha,
+ int *imageDpi)
{
int imagelayout = IL_HORIZONTAL;
int imagecount = 1;
@@ -280,7 +281,7 @@ static HRESULT UXTHEME_LoadImage(HTHEME hTheme, HDC hdc, int iPartId, int iState
WCHAR szPath[MAX_PATH];
PTHEME_PROPERTY tp;
- tp = UXTHEME_SelectImage(hTheme, hdc, iPartId, iStateId, pRect, glyph, imageDpi);
+ tp = UXTHEME_SelectImage(hTheme, iPartId, iStateId, pRect, glyph, imageDpi);
if(!tp) {
FIXME("Couldn't determine image for part/state %d/%d, invalid theme?\n", iPartId, iStateId);
return E_PROP_ID_UNSUPPORTED;
@@ -528,7 +529,7 @@ static HRESULT UXTHEME_DrawImageGlyph(HTHEME hTheme, HDC hdc, int iPartId,
POINT topleft;
BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, TRUE, &bmpSrc, &rcSrc, &hasAlpha,
+ hr = UXTHEME_LoadImage(hTheme, iPartId, iStateId, pRect, TRUE, &bmpSrc, &rcSrc, &hasAlpha,
NULL);
if(FAILED(hr)) return hr;
hdcSrc = CreateCompatibleDC(hdc);
@@ -594,9 +595,8 @@ static HRESULT UXTHEME_DrawGlyph(HTHEME hTheme, HDC hdc, int iPartId,
*
* Used by GetThemePartSize and UXTHEME_DrawImageBackground
*/
-static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId,
- int iStateId, RECT *prc, THEMESIZE eSize,
- POINT *psz)
+static HRESULT get_image_part_size(HTHEME hTheme, int iPartId, int iStateId, RECT *prc,
+ THEMESIZE eSize, POINT *psz)
{
int imageDpi, dstDpi;
HRESULT hr = S_OK;
@@ -604,7 +604,7 @@ static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId,
RECT rcSrc;
BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, prc, FALSE, &bmpSrc, &rcSrc, &hasAlpha,
+ hr = UXTHEME_LoadImage(hTheme, iPartId, iStateId, prc, FALSE, &bmpSrc, &rcSrc, &hasAlpha,
&imageDpi);
if (FAILED(hr)) return hr;
@@ -627,8 +627,8 @@ static HRESULT get_image_part_size (HTHEME hTheme, HDC hdc, int iPartId,
{
/* Scale to DPI only if the destination DPI exceeds the source DPI by
* stretchMark percent */
- dstDpi = GetDeviceCaps(hdc, LOGPIXELSY);
- if (dstDpi && dstDpi != imageDpi && MulDiv(100, dstDpi, imageDpi) >= stretchMark + 100)
+ dstDpi = MSSTYLES_GetThemeDPI(hTheme);
+ if (dstDpi != imageDpi && MulDiv(100, dstDpi, imageDpi) >= stretchMark + 100)
{
srcSize.x = MulDiv(srcSize.x, dstDpi, imageDpi);
srcSize.y = MulDiv(srcSize.y, dstDpi, imageDpi);
@@ -707,7 +707,7 @@ static HRESULT UXTHEME_DrawImageBackground(HTHEME hTheme, HDC hdc, int iPartId,
COLORREF transparentcolor = 0;
BOOL hasAlpha;
- hr = UXTHEME_LoadImage(hTheme, hdc, iPartId, iStateId, pRect, FALSE, &bmpSrc, &rcSrc, &hasAlpha,
+ hr = UXTHEME_LoadImage(hTheme, iPartId, iStateId, pRect, FALSE, &bmpSrc, &rcSrc, &hasAlpha,
NULL);
if(FAILED(hr)) return hr;
hdcSrc = CreateCompatibleDC(hdc);
@@ -731,7 +731,7 @@ static HRESULT UXTHEME_DrawImageBackground(HTHEME hTheme, HDC hdc, int iPartId,
if(sizingtype == ST_TRUESIZE) {
int valign = VA_CENTER, halign = HA_CENTER;
- get_image_part_size (hTheme, hdc, iPartId, iStateId, pRect, TS_DRAW, &drawSize);
+ get_image_part_size(hTheme, iPartId, iStateId, pRect, TS_DRAW, &drawSize);
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_VALIGN, &valign);
GetThemeEnumValue(hTheme, iPartId, iStateId, TMT_HALIGN, &halign);
@@ -2072,7 +2072,7 @@ HRESULT WINAPI GetThemePartSize(HTHEME hTheme, HDC hdc, int iPartId,
if (bgtype == BT_NONE)
/* do nothing */;
else if(bgtype == BT_IMAGEFILE)
- hr = get_image_part_size (hTheme, hdc, iPartId, iStateId, prc, eSize, &size);
+ hr = get_image_part_size(hTheme, iPartId, iStateId, prc, eSize, &size);
else if(bgtype == BT_BORDERFILL)
hr = get_border_background_size (hTheme, iPartId, iStateId, eSize, &size);
else {
@@ -2183,7 +2183,7 @@ BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId,
if (bgtype != BT_IMAGEFILE) return FALSE;
- if (FAILED(UXTHEME_LoadImage(hTheme, 0, iPartId, iStateId, &rect, FALSE, &bmpSrc, &rcSrc,
+ if (FAILED(UXTHEME_LoadImage(hTheme, iPartId, iStateId, &rect, FALSE, &bmpSrc, &rcSrc,
&hasAlpha, NULL)))
return FALSE;
diff --git a/dlls/uxtheme/msstyles.c b/dlls/uxtheme/msstyles.c
index 99eda64233c..efabd06f7c0 100644
--- a/dlls/uxtheme/msstyles.c
+++ b/dlls/uxtheme/msstyles.c
@@ -247,6 +247,16 @@ PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf)
return UXINI_LoadINI(tf->hTheme, L"themes_ini");
}
+/***********************************************************************
+ * MSSTYLES_GetThemeDPI
+ *
+ * Retrieves the DPI from a theme handle when it was opened
+ */
+UINT MSSTYLES_GetThemeDPI(PTHEME_CLASS tc)
+{
+ return tc->dpi;
+}
+
/***********************************************************************
* MSSTYLES_GetActiveThemeIni
*
diff --git a/dlls/uxtheme/msstyles.h b/dlls/uxtheme/msstyles.h
index 1cb27b93ab3..12292cefae4 100644
--- a/dlls/uxtheme/msstyles.h
+++ b/dlls/uxtheme/msstyles.h
@@ -94,6 +94,7 @@ BOOL MSSTYLES_LookupProperty(LPCWSTR pszPropertyName, int *dwPrimitive, int *dwI
BOOL MSSTYLES_LookupEnum(LPCWSTR pszValueName, int dwEnum, int *dwValue) DECLSPEC_HIDDEN;
BOOL MSSTYLES_LookupPartState(LPCWSTR pszClass, LPCWSTR pszPart, LPCWSTR pszState, int *iPartId, int *iStateId) DECLSPEC_HIDDEN;
PUXINI_FILE MSSTYLES_GetThemeIni(PTHEME_FILE tf) DECLSPEC_HIDDEN;
+UINT MSSTYLES_GetThemeDPI(PTHEME_CLASS tc) DECLSPEC_HIDDEN;
PTHEME_PARTSTATE MSSTYLES_FindPartState(PTHEME_CLASS tc, int iPartId, int iStateId, PTHEME_CLASS *tcNext) DECLSPEC_HIDDEN;
PTHEME_PROPERTY MSSTYLES_FindProperty(PTHEME_CLASS tc, int iPartId, int iStateId, int iPropertyPrimitive, int iPropertyId) DECLSPEC_HIDDEN;
PTHEME_PROPERTY MSSTYLES_FindMetric(int iPropertyPrimitive, int iPropertyId) DECLSPEC_HIDDEN;
diff --git a/dlls/uxtheme/tests/system.c b/dlls/uxtheme/tests/system.c
index 584a71a82b4..f9bf371e6bf 100644
--- a/dlls/uxtheme/tests/system.c
+++ b/dlls/uxtheme/tests/system.c
@@ -1030,7 +1030,6 @@ static void test_GetThemePartSize(void)
ok(hr == S_OK, "GetThemePartSize failed, hr %#x.\n", hr);
hr = GetThemePartSize(htheme, NULL, BP_CHECKBOX, CBS_CHECKEDNORMAL, NULL, TS_DRAW, &size2);
ok(hr == S_OK, "GetThemePartSize failed, hr %#x.\n", hr);
- todo_wine
ok(size2.cx == size.cx && size2.cy == size.cy, "Expected size %dx%d, got %dx%d.\n",
size.cx, size.cy, size2.cx, size2.cy);
ReleaseDC(hwnd, hdc);
--
2.30.2