user32: Implement SystemParametersInfoForDpi().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-04-13 14:18:15 +02:00
parent 9c225fc3f9
commit a02ed14732
4 changed files with 225 additions and 38 deletions

View file

@ -258,7 +258,7 @@ union sysparam_all_entry;
struct sysparam_entry struct sysparam_entry
{ {
BOOL (*get)( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ); BOOL (*get)( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi );
BOOL (*set)( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT flags ); BOOL (*set)( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT flags );
BOOL (*init)( union sysparam_all_entry *entry ); BOOL (*init)( union sysparam_all_entry *entry );
const WCHAR *regval; const WCHAR *regval;
@ -650,6 +650,19 @@ void release_display_dc( HDC hdc )
LeaveCriticalSection( &display_dc_section ); LeaveCriticalSection( &display_dc_section );
} }
/* map value from system dpi to standard 96 dpi for storing in the registry */
static int map_from_system_dpi( int val )
{
return MulDiv( val, USER_DEFAULT_SCREEN_DPI, GetDpiForSystem() );
}
/* map value from 96 dpi to system or custom dpi */
static int map_to_dpi( int val, UINT dpi )
{
if (!dpi) dpi = GetDpiForSystem();
return MulDiv( val, dpi, USER_DEFAULT_SCREEN_DPI );
}
static INT CALLBACK real_fontname_proc(const LOGFONTW *lf, const TEXTMETRICW *ntm, DWORD type, LPARAM lparam) static INT CALLBACK real_fontname_proc(const LOGFONTW *lf, const TEXTMETRICW *ntm, DWORD type, LPARAM lparam)
{ {
const ENUMLOGFONTW *elf = (const ENUMLOGFONTW *)lf; const ENUMLOGFONTW *elf = (const ENUMLOGFONTW *)lf;
@ -706,7 +719,7 @@ static BOOL CALLBACK enum_monitors( HMONITOR monitor, HDC hdc, LPRECT rect, LPAR
} }
/* load a uint parameter from the registry */ /* load a uint parameter from the registry */
static BOOL get_uint_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_uint_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
@ -763,33 +776,45 @@ static BOOL init_int_entry( union sysparam_all_entry *entry )
} }
/* load a twips parameter from the registry */ /* load a twips parameter from the registry */
static BOOL get_twips_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_twips_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
int val;
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
if (!entry->hdr.loaded) if (!entry->hdr.loaded)
{ {
WCHAR buf[32]; WCHAR buf[32];
if (load_entry( &entry->hdr, buf, sizeof(buf) )) if (load_entry( &entry->hdr, buf, sizeof(buf) )) entry->uint.val = atoiW( buf );
{
int val = atoiW( buf );
/* Dimensions are quoted as being "twips" values if negative and pixels if positive.
* One inch is 1440 twips.
* See for example
* Technical Reference to the Windows 2000 Registry ->
* HKEY_CURRENT_USER -> Control Panel -> Desktop -> WindowMetrics
*/
if (val < 0) val = (-val * GetDpiForSystem() + 720) / 1440;
entry->uint.val = val;
}
} }
*(UINT *)ptr_param = entry->uint.val;
/* Dimensions are quoted as being "twips" values if negative and pixels if positive.
* One inch is 1440 twips.
* See for example
* Technical Reference to the Windows 2000 Registry ->
* HKEY_CURRENT_USER -> Control Panel -> Desktop -> WindowMetrics
*/
val = entry->uint.val;
if (val < 0)
val = MulDiv( -val, dpi, 1440 );
else
val = map_to_dpi( val, dpi );
*(int *)ptr_param = val;
return TRUE; return TRUE;
} }
/* set a twips parameter in the registry */
static BOOL set_twips_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT flags )
{
int val = int_param;
if (val > 0) val = map_from_system_dpi( val );
return set_int_entry( entry, val, ptr_param, flags );
}
/* load a bool parameter from the registry */ /* load a bool parameter from the registry */
static BOOL get_bool_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_bool_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
@ -825,7 +850,7 @@ static BOOL init_bool_entry( union sysparam_all_entry *entry )
} }
/* load a bool parameter using Yes/No strings from the registry */ /* load a bool parameter using Yes/No strings from the registry */
static BOOL get_yesno_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_yesno_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
@ -857,7 +882,7 @@ static BOOL init_yesno_entry( union sysparam_all_entry *entry )
} }
/* load a dword (binary) parameter from the registry */ /* load a dword (binary) parameter from the registry */
static BOOL get_dword_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_dword_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
@ -888,7 +913,7 @@ static BOOL init_dword_entry( union sysparam_all_entry *entry )
} }
/* load an RGB parameter from the registry */ /* load an RGB parameter from the registry */
static BOOL get_rgb_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_rgb_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
@ -952,25 +977,25 @@ static BOOL init_rgb_entry( union sysparam_all_entry *entry )
} }
/* load a font (binary) parameter from the registry */ /* load a font (binary) parameter from the registry */
static BOOL get_font_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_font_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
LOGFONTW font;
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
if (!entry->hdr.loaded) if (!entry->hdr.loaded)
{ {
LOGFONTW font;
switch (load_entry( &entry->hdr, &font, sizeof(font) )) switch (load_entry( &entry->hdr, &font, sizeof(font) ))
{ {
case sizeof(font): case sizeof(font):
if (font.lfHeight > 0) /* positive height value means points ( inch/72 ) */ if (font.lfHeight > 0) /* positive height value means points ( inch/72 ) */
font.lfHeight = -MulDiv( font.lfHeight, GetDpiForSystem(), 72 ); font.lfHeight = -MulDiv( font.lfHeight, USER_DEFAULT_SCREEN_DPI, 72 );
entry->font.val = font; entry->font.val = font;
break; break;
case sizeof(LOGFONT16): /* win9x-winME format */ case sizeof(LOGFONT16): /* win9x-winME format */
SYSPARAMS_LogFont16To32W( (LOGFONT16 *)&font, &entry->font.val ); SYSPARAMS_LogFont16To32W( (LOGFONT16 *)&font, &entry->font.val );
if (entry->font.val.lfHeight > 0) if (entry->font.val.lfHeight > 0)
entry->font.val.lfHeight = -MulDiv( entry->font.val.lfHeight, GetDpiForSystem(), 72 ); entry->font.val.lfHeight = -MulDiv( entry->font.val.lfHeight, USER_DEFAULT_SCREEN_DPI, 72 );
break; break;
default: default:
WARN( "Unknown format in key %s value %s\n", WARN( "Unknown format in key %s value %s\n",
@ -979,13 +1004,16 @@ static BOOL get_font_entry( union sysparam_all_entry *entry, UINT int_param, voi
/* fall through */ /* fall through */
case 0: /* use the default GUI font */ case 0: /* use the default GUI font */
GetObjectW( GetStockObject( DEFAULT_GUI_FONT ), sizeof(font), &font ); GetObjectW( GetStockObject( DEFAULT_GUI_FONT ), sizeof(font), &font );
font.lfHeight = map_from_system_dpi( font.lfHeight );
font.lfWeight = entry->font.weight; font.lfWeight = entry->font.weight;
entry->font.val = font; entry->font.val = font;
break; break;
} }
entry->hdr.loaded = TRUE; entry->hdr.loaded = TRUE;
} }
*(LOGFONTW *)ptr_param = entry->font.val; font = entry->font.val;
font.lfHeight = map_to_dpi( font.lfHeight, dpi );
*(LOGFONTW *)ptr_param = font;
return TRUE; return TRUE;
} }
@ -999,6 +1027,7 @@ static BOOL set_font_entry( union sysparam_all_entry *entry, UINT int_param, voi
/* zero pad the end of lfFaceName so we don't save uninitialised data */ /* zero pad the end of lfFaceName so we don't save uninitialised data */
ptr = memchrW( font.lfFaceName, 0, LF_FACESIZE ); ptr = memchrW( font.lfFaceName, 0, LF_FACESIZE );
if (ptr) memset( ptr, 0, (font.lfFaceName + LF_FACESIZE - ptr) * sizeof(WCHAR) ); if (ptr) memset( ptr, 0, (font.lfFaceName + LF_FACESIZE - ptr) * sizeof(WCHAR) );
font.lfHeight = map_from_system_dpi( font.lfHeight );
if (!save_entry( &entry->hdr, &font, sizeof(font), REG_BINARY, flags )) return FALSE; if (!save_entry( &entry->hdr, &font, sizeof(font), REG_BINARY, flags )) return FALSE;
entry->font.val = font; entry->font.val = font;
@ -1010,12 +1039,13 @@ static BOOL set_font_entry( union sysparam_all_entry *entry, UINT int_param, voi
static BOOL init_font_entry( union sysparam_all_entry *entry ) static BOOL init_font_entry( union sysparam_all_entry *entry )
{ {
GetObjectW( GetStockObject( DEFAULT_GUI_FONT ), sizeof(entry->font.val), &entry->font.val ); GetObjectW( GetStockObject( DEFAULT_GUI_FONT ), sizeof(entry->font.val), &entry->font.val );
entry->font.val.lfHeight = map_from_system_dpi( entry->font.val.lfHeight );
entry->font.val.lfWeight = entry->font.weight; entry->font.val.lfWeight = entry->font.weight;
return init_entry( &entry->hdr, &entry->font.val, sizeof(entry->font.val), REG_BINARY ); return init_entry( &entry->hdr, &entry->font.val, sizeof(entry->font.val), REG_BINARY );
} }
/* get a path parameter in the registry */ /* get a path parameter in the registry */
static BOOL get_path_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_path_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
@ -1053,7 +1083,7 @@ static BOOL init_path_entry( union sysparam_all_entry *entry )
} }
/* get a binary parameter in the registry */ /* get a binary parameter in the registry */
static BOOL get_binary_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_binary_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
@ -1098,14 +1128,14 @@ static BOOL init_binary_entry( union sysparam_all_entry *entry )
} }
/* get a user pref parameter in the registry */ /* get a user pref parameter in the registry */
static BOOL get_userpref_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param ) static BOOL get_userpref_entry( union sysparam_all_entry *entry, UINT int_param, void *ptr_param, UINT dpi )
{ {
union sysparam_all_entry *parent_entry = (union sysparam_all_entry *)entry->pref.parent; union sysparam_all_entry *parent_entry = (union sysparam_all_entry *)entry->pref.parent;
BYTE prefs[8]; BYTE prefs[8];
if (!ptr_param) return FALSE; if (!ptr_param) return FALSE;
if (!parent_entry->hdr.get( parent_entry, sizeof(prefs), prefs )) return FALSE; if (!parent_entry->hdr.get( parent_entry, sizeof(prefs), prefs, dpi )) return FALSE;
*(BOOL *)ptr_param = (prefs[entry->pref.offset] & entry->pref.mask) != 0; *(BOOL *)ptr_param = (prefs[entry->pref.offset] & entry->pref.mask) != 0;
return TRUE; return TRUE;
} }
@ -1117,7 +1147,7 @@ static BOOL set_userpref_entry( union sysparam_all_entry *entry, UINT int_param,
BYTE prefs[8]; BYTE prefs[8];
parent_entry->hdr.loaded = FALSE; /* force loading it again */ parent_entry->hdr.loaded = FALSE; /* force loading it again */
if (!parent_entry->hdr.get( parent_entry, sizeof(prefs), prefs )) return FALSE; if (!parent_entry->hdr.get( parent_entry, sizeof(prefs), prefs, GetDpiForSystem() )) return FALSE;
if (PtrToUlong( ptr_param )) prefs[entry->pref.offset] |= entry->pref.mask; if (PtrToUlong( ptr_param )) prefs[entry->pref.offset] |= entry->pref.mask;
else prefs[entry->pref.offset] &= ~entry->pref.mask; else prefs[entry->pref.offset] &= ~entry->pref.mask;
@ -1125,10 +1155,15 @@ static BOOL set_userpref_entry( union sysparam_all_entry *entry, UINT int_param,
return parent_entry->hdr.set( parent_entry, sizeof(prefs), prefs, flags ); return parent_entry->hdr.set( parent_entry, sizeof(prefs), prefs, flags );
} }
static BOOL get_entry( void *ptr, UINT int_param, void *ptr_param ) static BOOL get_entry_dpi( void *ptr, UINT int_param, void *ptr_param, UINT dpi )
{ {
union sysparam_all_entry *entry = ptr; union sysparam_all_entry *entry = ptr;
return entry->hdr.get( entry, int_param, ptr_param ); return entry->hdr.get( entry, int_param, ptr_param, dpi );
}
static BOOL get_entry( void *ptr, UINT int_param, void *ptr_param )
{
return get_entry_dpi( ptr, int_param, ptr_param, GetDpiForSystem() );
} }
static BOOL set_entry( void *ptr, UINT int_param, void *ptr_param, UINT flags ) static BOOL set_entry( void *ptr, UINT int_param, void *ptr_param, UINT flags )
@ -1162,7 +1197,7 @@ static BOOL set_entry( void *ptr, UINT int_param, void *ptr_param, UINT flags )
name ##_VALNAME }, (val) } name ##_VALNAME }, (val) }
#define TWIPS_ENTRY(name,val) \ #define TWIPS_ENTRY(name,val) \
struct sysparam_uint_entry entry_##name = { { get_twips_entry, set_int_entry, init_int_entry, \ struct sysparam_uint_entry entry_##name = { { get_twips_entry, set_twips_entry, init_int_entry, \
name ##_VALNAME }, (val) } name ##_VALNAME }, (val) }
#define DWORD_ENTRY(name,val) \ #define DWORD_ENTRY(name,val) \
@ -1430,6 +1465,61 @@ static BOOL update_desktop_wallpaper(void)
return TRUE; return TRUE;
} }
/***********************************************************************
* SystemParametersInfoForDpi (USER32.@)
*/
BOOL WINAPI SystemParametersInfoForDpi( UINT action, UINT val, PVOID ptr, UINT winini, UINT dpi )
{
BOOL ret = FALSE;
switch (action)
{
case SPI_GETICONTITLELOGFONT:
ret = get_entry_dpi( &entry_ICONTITLELOGFONT, val, ptr, dpi );
break;
case SPI_GETNONCLIENTMETRICS:
{
NONCLIENTMETRICSW *ncm = ptr;
if (!ncm) break;
ret = get_entry_dpi( &entry_BORDER, 0, &ncm->iBorderWidth, dpi ) &&
get_entry_dpi( &entry_SCROLLWIDTH, 0, &ncm->iScrollWidth, dpi ) &&
get_entry_dpi( &entry_SCROLLHEIGHT, 0, &ncm->iScrollHeight, dpi ) &&
get_entry_dpi( &entry_CAPTIONWIDTH, 0, &ncm->iCaptionWidth, dpi ) &&
get_entry_dpi( &entry_CAPTIONHEIGHT, 0, &ncm->iCaptionHeight, dpi ) &&
get_entry_dpi( &entry_CAPTIONLOGFONT, 0, &ncm->lfCaptionFont, dpi ) &&
get_entry_dpi( &entry_SMCAPTIONWIDTH, 0, &ncm->iSmCaptionWidth, dpi ) &&
get_entry_dpi( &entry_SMCAPTIONHEIGHT, 0, &ncm->iSmCaptionHeight, dpi ) &&
get_entry_dpi( &entry_SMCAPTIONLOGFONT, 0, &ncm->lfSmCaptionFont, dpi ) &&
get_entry_dpi( &entry_MENUWIDTH, 0, &ncm->iMenuWidth, dpi ) &&
get_entry_dpi( &entry_MENUHEIGHT, 0, &ncm->iMenuHeight, dpi ) &&
get_entry_dpi( &entry_MENULOGFONT, 0, &ncm->lfMenuFont, dpi ) &&
get_entry_dpi( &entry_STATUSLOGFONT, 0, &ncm->lfStatusFont, dpi ) &&
get_entry_dpi( &entry_MESSAGELOGFONT, 0, &ncm->lfMessageFont, dpi );
if (ret && ncm->cbSize == sizeof(NONCLIENTMETRICSW))
ret = get_entry_dpi( &entry_PADDEDBORDERWIDTH, 0, &ncm->iPaddedBorderWidth, dpi );
normalize_nonclientmetrics( ncm );
break;
}
case SPI_GETICONMETRICS:
{
ICONMETRICSW *im = ptr;
if (im && im->cbSize == sizeof(*im))
ret = get_entry_dpi( &entry_ICONHORIZONTALSPACING, 0, &im->iHorzSpacing, dpi ) &&
get_entry_dpi( &entry_ICONVERTICALSPACING, 0, &im->iVertSpacing, dpi ) &&
get_entry_dpi( &entry_ICONTITLEWRAP, 0, &im->iTitleWrap, dpi ) &&
get_entry_dpi( &entry_ICONTITLELOGFONT, 0, &im->lfFont, dpi );
break;
}
default:
SetLastError( ERROR_INVALID_PARAMETER );
break;
}
return ret;
}
/*********************************************************************** /***********************************************************************
* SystemParametersInfoW (USER32.@) * SystemParametersInfoW (USER32.@)
* *
@ -1520,7 +1610,7 @@ BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
ret = get_entry( &entry_ICONHORIZONTALSPACING, uiParam, pvParam ); ret = get_entry( &entry_ICONHORIZONTALSPACING, uiParam, pvParam );
else else
{ {
int min_val = MulDiv( 32, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI ); int min_val = map_to_dpi( 32, GetDpiForSystem() );
ret = set_entry( &entry_ICONHORIZONTALSPACING, max( min_val, uiParam ), pvParam, fWinIni ); ret = set_entry( &entry_ICONHORIZONTALSPACING, max( min_val, uiParam ), pvParam, fWinIni );
} }
break; break;
@ -1561,7 +1651,7 @@ BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam,
ret = get_entry( &entry_ICONVERTICALSPACING, uiParam, pvParam ); ret = get_entry( &entry_ICONVERTICALSPACING, uiParam, pvParam );
else else
{ {
int min_val = MulDiv( 32, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI ); int min_val = map_to_dpi( 32, GetDpiForSystem() );
ret = set_entry( &entry_ICONVERTICALSPACING, max( min_val, uiParam ), pvParam, fWinIni ); ret = set_entry( &entry_ICONVERTICALSPACING, max( min_val, uiParam ), pvParam, fWinIni );
} }
break; break;

View file

@ -50,6 +50,7 @@ static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENE
static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND); static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
static BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); static BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
static BOOL (WINAPI *pSystemParametersInfoForDpi)(UINT,UINT,void*,UINT,UINT);
static BOOL strict; static BOOL strict;
static int dpi, real_dpi; static int dpi, real_dpi;
@ -1507,7 +1508,6 @@ static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */
Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi); Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi);
/* test registry entries */ /* test registry entries */
TEST_NONCLIENTMETRICS_REG( Ncmorig); TEST_NONCLIENTMETRICS_REG( Ncmorig);
Ncmorig.lfCaptionFont.lfHeight = MulDiv( Ncmorig.lfCaptionFont.lfHeight, real_dpi, dpi );
/* make small changes */ /* make small changes */
Ncmnew = Ncmstart; Ncmnew = Ncmstart;
@ -2900,6 +2900,98 @@ static void test_GetSystemMetrics( void)
DeleteDC(hdc); DeleteDC(hdc);
} }
static void compare_font( const LOGFONTW *lf1, const LOGFONTW *lf2, int dpi, int custom_dpi, int line )
{
ok_(__FILE__,line)( lf1->lfHeight == MulDiv( lf2->lfHeight, dpi, custom_dpi ),
"wrong lfHeight %d vs %d\n", lf1->lfHeight, lf2->lfHeight );
ok_(__FILE__,line)( abs( lf1->lfWidth - MulDiv( lf2->lfWidth, dpi, custom_dpi )) <= 1,
"wrong lfWidth %d vs %d\n", lf1->lfWidth, lf2->lfWidth );
ok_(__FILE__,line)( !memcmp( &lf1->lfEscapement, &lf2->lfEscapement,
offsetof( LOGFONTW, lfFaceName ) - offsetof( LOGFONTW, lfEscapement )),
"font differs\n" );
ok_(__FILE__,line)( !lstrcmpW( lf1->lfFaceName, lf2->lfFaceName ), "wrong face name %s vs %s\n",
wine_dbgstr_w( lf1->lfFaceName ), wine_dbgstr_w( lf2->lfFaceName ));
}
static void test_metrics_for_dpi( int custom_dpi )
{
int i, val;
NONCLIENTMETRICSW ncm1, ncm2;
ICONMETRICSW im1, im2;
LOGFONTW lf1, lf2;
BOOL ret;
if (!pSystemParametersInfoForDpi)
{
win_skip( "custom dpi metrics not supported\n" );
return;
}
ncm1.cbSize = sizeof(ncm1);
ret = SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof(ncm1), &ncm1, FALSE );
ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
ncm2.cbSize = sizeof(ncm2);
ret = pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof(ncm2), &ncm2, FALSE, custom_dpi );
ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
im1.cbSize = sizeof(im1);
ret = SystemParametersInfoW( SPI_GETICONMETRICS, sizeof(im1), &im1, FALSE );
ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
im2.cbSize = sizeof(im2);
ret = pSystemParametersInfoForDpi( SPI_GETICONMETRICS, sizeof(im2), &im2, FALSE, custom_dpi );
ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
ok( im1.iHorzSpacing == MulDiv( im2.iHorzSpacing, dpi, custom_dpi ), "wrong iHorzSpacing %u vs %u\n",
im1.iHorzSpacing, im2.iHorzSpacing );
ok( im1.iVertSpacing == MulDiv( im2.iVertSpacing, dpi, custom_dpi ), "wrong iVertSpacing %u vs %u\n",
im1.iVertSpacing, im2.iVertSpacing );
ok( im1.iTitleWrap == im2.iTitleWrap, "wrong iTitleWrap %u vs %u\n",
im1.iTitleWrap, im2.iTitleWrap );
compare_font( &im1.lfFont, &im2.lfFont, dpi, custom_dpi, __LINE__ );
ret = SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf1), &lf1, FALSE );
ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
ret = pSystemParametersInfoForDpi( SPI_GETICONTITLELOGFONT, sizeof(lf2), &lf2, FALSE, custom_dpi );
ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
compare_font( &lf1, &lf2, dpi, custom_dpi, __LINE__ );
/* on high-dpi iPaddedBorderWidth is used in addition to iBorderWidth */
ok( ncm1.iBorderWidth + ncm1.iPaddedBorderWidth == MulDiv( ncm2.iBorderWidth + ncm2.iPaddedBorderWidth, dpi, custom_dpi ),
"wrong iBorderWidth %u+%u vs %u+%u\n",
ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
ok( ncm1.iScrollWidth == MulDiv( ncm2.iScrollWidth, dpi, custom_dpi ),
"wrong iScrollWidth %u vs %u\n", ncm1.iScrollWidth, ncm2.iScrollWidth );
ok( ncm1.iScrollHeight == MulDiv( ncm2.iScrollHeight, dpi, custom_dpi ),
"wrong iScrollHeight %u vs %u\n", ncm1.iScrollHeight, ncm2.iScrollHeight );
ok( ((ncm1.iCaptionWidth + 1) & ~1) == ((MulDiv( ncm2.iCaptionWidth, dpi, custom_dpi ) + 1) & ~1),
"wrong iCaptionWidth %u vs %u\n", ncm1.iCaptionWidth, ncm2.iCaptionWidth );
ok( ncm1.iCaptionHeight == MulDiv( ncm2.iCaptionHeight, dpi, custom_dpi ),
"wrong iCaptionHeight %u vs %u\n", ncm1.iCaptionHeight, ncm2.iCaptionHeight );
compare_font( &ncm1.lfCaptionFont, &ncm2.lfCaptionFont, dpi, custom_dpi, __LINE__ );
ok( ncm1.iSmCaptionHeight == MulDiv( ncm2.iSmCaptionHeight, dpi, custom_dpi ),
"wrong iSmCaptionHeight %u vs %u\n", ncm1.iSmCaptionHeight, ncm2.iSmCaptionHeight );
compare_font( &ncm1.lfSmCaptionFont, &ncm2.lfSmCaptionFont, dpi, custom_dpi, __LINE__ );
ok( ncm1.iMenuHeight == MulDiv( ncm2.iMenuHeight, dpi, custom_dpi ),
"wrong iMenuHeight %u vs %u\n", ncm1.iMenuHeight, ncm2.iMenuHeight );
/* iSmCaptionWidth and iMenuWidth apparently need to be multiples of 8 */
ok( ncm1.iSmCaptionWidth / 8 == MulDiv( ncm2.iSmCaptionWidth, dpi, custom_dpi ) / 8,
"wrong iSmCaptionWidth %u vs %u\n", ncm1.iSmCaptionWidth, ncm2.iSmCaptionWidth );
ok( ncm1.iMenuWidth / 8 == MulDiv( ncm2.iMenuWidth, dpi, custom_dpi ) / 8,
"wrong iMenuWidth %u vs %u\n", ncm1.iMenuWidth, ncm2.iMenuWidth );
compare_font( &ncm1.lfMenuFont, &ncm2.lfMenuFont, dpi, custom_dpi, __LINE__ );
compare_font( &ncm1.lfStatusFont, &ncm2.lfStatusFont, dpi, custom_dpi, __LINE__ );
compare_font( &ncm1.lfMessageFont, &ncm2.lfMessageFont, dpi, custom_dpi, __LINE__ );
for (i = 1; i < 120; i++)
{
if (i == SPI_GETICONTITLELOGFONT || i == SPI_GETNONCLIENTMETRICS || i == SPI_GETICONMETRICS)
continue;
SetLastError( 0xdeadbeef );
ret = pSystemParametersInfoForDpi( i, 0, &val, 0, custom_dpi );
ok( !ret, "%u: SystemParametersInfoForDpi succeeded\n", i );
ok( GetLastError() == ERROR_INVALID_PARAMETER, "%u: wrong error %u\n", i, GetLastError() );
}
}
static void test_EnumDisplaySettings(void) static void test_EnumDisplaySettings(void)
{ {
DEVMODEA devmode; DEVMODEA devmode;
@ -3199,6 +3291,8 @@ static void test_dpi_aware(void)
if (pGetDpiForSystem) real_dpi = pGetDpiForSystem(); if (pGetDpiForSystem) real_dpi = pGetDpiForSystem();
dpi = real_dpi; dpi = real_dpi;
test_GetSystemMetrics(); test_GetSystemMetrics();
test_metrics_for_dpi( 96 );
test_metrics_for_dpi( 192 );
} }
static void test_window_dpi(void) static void test_window_dpi(void)
@ -3282,6 +3376,7 @@ START_TEST(sysparams)
pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetWindowDpiAwarenessContext"); pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetWindowDpiAwarenessContext");
pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetAwarenessFromDpiAwarenessContext"); pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetAwarenessFromDpiAwarenessContext");
pIsValidDpiAwarenessContext = (void*)GetProcAddress(hdll, "IsValidDpiAwarenessContext"); pIsValidDpiAwarenessContext = (void*)GetProcAddress(hdll, "IsValidDpiAwarenessContext");
pSystemParametersInfoForDpi = (void*)GetProcAddress(hdll, "SystemParametersInfoForDpi");
hInstance = GetModuleHandleA( NULL ); hInstance = GetModuleHandleA( NULL );
hdc = GetDC(0); hdc = GetDC(0);
@ -3300,7 +3395,7 @@ START_TEST(sysparams)
trace("testing GetSystemMetrics with your current desktop settings\n"); trace("testing GetSystemMetrics with your current desktop settings\n");
test_GetSystemMetrics( ); test_GetSystemMetrics( );
trace("testing EnumDisplaySettings vs GetDeviceCaps\n"); test_metrics_for_dpi( 192 );
test_EnumDisplaySettings( ); test_EnumDisplaySettings( );
test_GetSysColorBrush( ); test_GetSysColorBrush( );

View file

@ -737,6 +737,7 @@
@ stdcall SwitchToThisWindow(long long) @ stdcall SwitchToThisWindow(long long)
# @ stub SysErrorBox # @ stub SysErrorBox
@ stdcall SystemParametersInfoA(long long ptr long) @ stdcall SystemParametersInfoA(long long ptr long)
@ stdcall SystemParametersInfoForDpi(long long ptr long long)
@ stdcall SystemParametersInfoW(long long ptr long) @ stdcall SystemParametersInfoW(long long ptr long)
@ stdcall TabbedTextOutA(long long long str long long ptr long) @ stdcall TabbedTextOutA(long long long str long long ptr long)
@ stdcall TabbedTextOutW(long long long wstr long long ptr long) @ stdcall TabbedTextOutW(long long long wstr long long ptr long)

View file

@ -4129,6 +4129,7 @@ WINUSERAPI VOID WINAPI SwitchToThisWindow(HWND,BOOL);
WINUSERAPI BOOL WINAPI SystemParametersInfoA(UINT,UINT,LPVOID,UINT); WINUSERAPI BOOL WINAPI SystemParametersInfoA(UINT,UINT,LPVOID,UINT);
WINUSERAPI BOOL WINAPI SystemParametersInfoW(UINT,UINT,LPVOID,UINT); WINUSERAPI BOOL WINAPI SystemParametersInfoW(UINT,UINT,LPVOID,UINT);
#define SystemParametersInfo WINELIB_NAME_AW(SystemParametersInfo) #define SystemParametersInfo WINELIB_NAME_AW(SystemParametersInfo)
WINUSERAPI BOOL WINAPI SystemParametersInfoForDpi(UINT,UINT,void*,UINT,UINT);
WINUSERAPI LONG WINAPI TabbedTextOutA(HDC,INT,INT,LPCSTR,INT,INT,const INT*,INT); WINUSERAPI LONG WINAPI TabbedTextOutA(HDC,INT,INT,LPCSTR,INT,INT,const INT*,INT);
WINUSERAPI LONG WINAPI TabbedTextOutW(HDC,INT,INT,LPCWSTR,INT,INT,const INT*,INT); WINUSERAPI LONG WINAPI TabbedTextOutW(HDC,INT,INT,LPCWSTR,INT,INT,const INT*,INT);
#define TabbedTextOut WINELIB_NAME_AW(TabbedTextOut) #define TabbedTextOut WINELIB_NAME_AW(TabbedTextOut)