uxtheme: Get DPI from theme class.

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@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zhiyi Zhang 2021-09-01 14:38:10 +08:00 committed by Alexandre Julliard
parent 53a0d57aff
commit f8bc5d7627
4 changed files with 29 additions and 19 deletions

View File

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

View File

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

View File

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

View File

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