user32: Implement GetSystemMetricsForDpi().

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-04-13 14:31:43 +02:00
parent a02ed14732
commit 3458af7db0
4 changed files with 192 additions and 3 deletions

View file

@ -2539,10 +2539,10 @@ INT WINAPI GetSystemMetrics( INT index )
return ncm.iScrollHeight; return ncm.iScrollHeight;
case SM_CXICON: case SM_CXICON:
case SM_CYICON: case SM_CYICON:
return MulDiv( 32, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI ); return map_to_dpi( 32, GetDpiForSystem() );
case SM_CXCURSOR: case SM_CXCURSOR:
case SM_CYCURSOR: case SM_CYCURSOR:
ret = MulDiv( 32, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI ); ret = map_to_dpi( 32, GetDpiForSystem() );
if (ret >= 64) return 64; if (ret >= 64) return 64;
if (ret >= 48) return 48; if (ret >= 48) return 48;
return 32; return 32;
@ -2644,7 +2644,7 @@ INT WINAPI GetSystemMetrics( INT index )
return GetSystemMetrics(SM_CYMINIMIZED) + mm.iVertGap; return GetSystemMetrics(SM_CYMINIMIZED) + mm.iVertGap;
case SM_CXSMICON: case SM_CXSMICON:
case SM_CYSMICON: case SM_CYSMICON:
return MulDiv( 16, GetDpiForSystem(), USER_DEFAULT_SCREEN_DPI ) & ~1; return map_to_dpi( 16, GetDpiForSystem() ) & ~1;
case SM_CYSMCAPTION: case SM_CYSMCAPTION:
ncm.cbSize = sizeof(ncm); ncm.cbSize = sizeof(ncm);
SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0 ); SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0 );
@ -2761,6 +2761,112 @@ INT WINAPI GetSystemMetrics( INT index )
} }
/***********************************************************************
* GetSystemMetricsForDpi (USER32.@)
*/
INT WINAPI GetSystemMetricsForDpi( INT index, UINT dpi )
{
NONCLIENTMETRICSW ncm;
ICONMETRICSW im;
UINT ret;
HDC hdc;
/* some metrics are dynamic */
switch (index)
{
case SM_CXVSCROLL:
case SM_CYHSCROLL:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iScrollWidth;
case SM_CYCAPTION:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iCaptionHeight + 1;
case SM_CYVTHUMB:
case SM_CXHTHUMB:
case SM_CYVSCROLL:
case SM_CXHSCROLL:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iScrollHeight;
case SM_CXICON:
case SM_CYICON:
return map_to_dpi( 32, dpi );
case SM_CXCURSOR:
case SM_CYCURSOR:
ret = map_to_dpi( 32, dpi );
if (ret >= 64) return 64;
if (ret >= 48) return 48;
return 32;
case SM_CYMENU:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iMenuHeight + 1;
case SM_CXSIZE:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iCaptionWidth;
case SM_CYSIZE:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iCaptionHeight;
case SM_CXFRAME:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return GetSystemMetricsForDpi( SM_CXDLGFRAME, dpi ) + ncm.iBorderWidth;
case SM_CYFRAME:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return GetSystemMetricsForDpi( SM_CYDLGFRAME, dpi ) + ncm.iBorderWidth;
case SM_CXICONSPACING:
im.cbSize = sizeof(im);
SystemParametersInfoForDpi( SPI_GETICONMETRICS, sizeof(im), &im, 0, dpi );
return im.iHorzSpacing;
case SM_CYICONSPACING:
im.cbSize = sizeof(im);
SystemParametersInfoForDpi( SPI_GETICONMETRICS, sizeof(im), &im, 0, dpi );
return im.iVertSpacing;
case SM_CXSMICON:
case SM_CYSMICON:
return map_to_dpi( 16, dpi ) & ~1;
case SM_CYSMCAPTION:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iSmCaptionHeight + 1;
case SM_CXSMSIZE:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iSmCaptionWidth;
case SM_CYSMSIZE:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iSmCaptionHeight;
case SM_CXMENUSIZE:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iMenuWidth;
case SM_CYMENUSIZE:
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
return ncm.iMenuHeight;
case SM_CXMENUCHECK:
case SM_CYMENUCHECK:
{
TEXTMETRICW tm;
ncm.cbSize = sizeof(ncm);
SystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0, dpi );
hdc = get_display_dc();
get_text_metr_size( hdc, &ncm.lfMenuFont, &tm, NULL);
release_display_dc( hdc );
return tm.tmHeight <= 0 ? 13 : ((tm.tmHeight + tm.tmExternalLeading - 1) | 1);
}
default:
return GetSystemMetrics( index );
}
}
/*********************************************************************** /***********************************************************************
* SwapMouseButton (USER32.@) * SwapMouseButton (USER32.@)
* Reverse or restore the meaning of the left and right mouse buttons * Reverse or restore the meaning of the left and right mouse buttons

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 INT (WINAPI *pGetSystemMetricsForDpi)(INT,UINT);
static BOOL (WINAPI *pSystemParametersInfoForDpi)(UINT,UINT,void*,UINT,UINT); static BOOL (WINAPI *pSystemParametersInfoForDpi)(UINT,UINT,void*,UINT,UINT);
static BOOL strict; static BOOL strict;
@ -1473,6 +1474,18 @@ static int get_tmheight( LOGFONTA *plf, int flag)
return tm.tmHeight + (flag ? tm.tmExternalLeading : 0); return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
} }
static int get_tmheightW( LOGFONTW *plf, int flag)
{
TEXTMETRICW tm;
HDC hdc = GetDC(0);
HFONT hfont = CreateFontIndirectW( plf);
hfont = SelectObject( hdc, hfont);
GetTextMetricsW( hdc, &tm);
hfont = SelectObject( hdc, hfont);
ReleaseDC( 0, hdc );
return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
}
static void test_GetSystemMetrics( void); static void test_GetSystemMetrics( void);
static UINT smcxsmsize = 999999999; static UINT smcxsmsize = 999999999;
@ -2934,6 +2947,73 @@ static void test_metrics_for_dpi( int custom_dpi )
ret = pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof(ncm2), &ncm2, FALSE, custom_dpi ); ret = pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof(ncm2), &ncm2, FALSE, custom_dpi );
ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() ); ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
for (i = 0; i < 92; i++)
{
int ret1 = GetSystemMetrics( i );
int ret2 = pGetSystemMetricsForDpi( i, custom_dpi );
switch (i)
{
case SM_CXVSCROLL:
case SM_CYHSCROLL:
case SM_CYVTHUMB:
case SM_CXHTHUMB:
case SM_CXICON:
case SM_CYICON:
case SM_CYVSCROLL:
case SM_CXHSCROLL:
case SM_CYSIZE:
case SM_CXICONSPACING:
case SM_CYICONSPACING:
case SM_CXSMSIZE:
case SM_CYSMSIZE:
case SM_CYMENUSIZE:
ok( ret1 == MulDiv( ret2, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
break;
case SM_CXSIZE:
ok( ret1 == ncm1.iCaptionWidth && ret2 == ncm2.iCaptionWidth,
"%u: wrong value %u vs %u caption %u vs %u\n",
i, ret1, ret2, ncm1.iCaptionWidth, ncm2.iCaptionWidth );
break;
case SM_CXCURSOR:
case SM_CYCURSOR:
val = MulDiv( 32, custom_dpi, USER_DEFAULT_SCREEN_DPI );
if (val < 48) val = 32;
else if (val < 64) val = 48;
else val = 64;
ok( val == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
break;
case SM_CYCAPTION:
case SM_CYSMCAPTION:
case SM_CYMENU:
ok( ret1 - 1 == MulDiv( ret2 - 1, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
break;
case SM_CXMENUSIZE:
ok( ret1 / 8 == MulDiv( ret2, dpi, custom_dpi ) / 8, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
break;
case SM_CXFRAME:
case SM_CYFRAME:
ok( ret1 == ncm1.iBorderWidth + 3 && ret2 == ncm2.iBorderWidth + 3,
"%u: wrong value %u vs %u borders %u+%u vs %u+%u\n", i, ret1, ret2,
ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
break;
case SM_CXSMICON:
case SM_CYSMICON:
ok( ret1 == (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI ) & ~1) &&
ret2 == (MulDiv( 16, custom_dpi, USER_DEFAULT_SCREEN_DPI ) & ~1),
"%u: wrong value %u vs %u\n", i, ret1, ret2 );
break;
case SM_CXMENUCHECK:
case SM_CYMENUCHECK:
ok( ret1 == ((get_tmheightW( &ncm1.lfMenuFont, 1 ) - 1) | 1) &&
ret2 == ((get_tmheightW( &ncm2.lfMenuFont, 1 ) - 1) | 1),
"%u: wrong value %u vs %u font %u vs %u\n", i, ret1, ret2,
get_tmheightW( &ncm1.lfMenuFont, 1 ), get_tmheightW( &ncm2.lfMenuFont, 1 ));
break;
default:
ok( ret1 == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
break;
}
}
im1.cbSize = sizeof(im1); im1.cbSize = sizeof(im1);
ret = SystemParametersInfoW( SPI_GETICONMETRICS, sizeof(im1), &im1, FALSE ); ret = SystemParametersInfoW( SPI_GETICONMETRICS, sizeof(im1), &im1, FALSE );
ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() ); ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
@ -3376,6 +3456,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");
pGetSystemMetricsForDpi = (void*)GetProcAddress(hdll, "GetSystemMetricsForDpi");
pSystemParametersInfoForDpi = (void*)GetProcAddress(hdll, "SystemParametersInfoForDpi"); pSystemParametersInfoForDpi = (void*)GetProcAddress(hdll, "SystemParametersInfoForDpi");
hInstance = GetModuleHandleA( NULL ); hInstance = GetModuleHandleA( NULL );

View file

@ -377,6 +377,7 @@
@ stdcall GetSysColorBrush(long) @ stdcall GetSysColorBrush(long)
@ stdcall GetSystemMenu(long long) @ stdcall GetSystemMenu(long long)
@ stdcall GetSystemMetrics(long) @ stdcall GetSystemMetrics(long)
@ stdcall GetSystemMetricsForDpi(long long)
@ stdcall GetTabbedTextExtentA(long str long long ptr) @ stdcall GetTabbedTextExtentA(long str long long ptr)
@ stdcall GetTabbedTextExtentW(long wstr long long ptr) @ stdcall GetTabbedTextExtentW(long wstr long long ptr)
@ stdcall GetTaskmanWindow () @ stdcall GetTaskmanWindow ()

View file

@ -3762,6 +3762,7 @@ WINUSERAPI HBRUSH WINAPI GetSysColorBrush(INT);
#define GetSysModalWindow() ((HWND)0) #define GetSysModalWindow() ((HWND)0)
WINUSERAPI HMENU WINAPI GetSystemMenu(HWND,BOOL); WINUSERAPI HMENU WINAPI GetSystemMenu(HWND,BOOL);
WINUSERAPI INT WINAPI GetSystemMetrics(INT); WINUSERAPI INT WINAPI GetSystemMetrics(INT);
WINUSERAPI INT WINAPI GetSystemMetricsForDpi(INT,UINT);
WINUSERAPI DWORD WINAPI GetTabbedTextExtentA(HDC,LPCSTR,INT,INT,const INT*); WINUSERAPI DWORD WINAPI GetTabbedTextExtentA(HDC,LPCSTR,INT,INT,const INT*);
WINUSERAPI DWORD WINAPI GetTabbedTextExtentW(HDC,LPCWSTR,INT,INT,const INT*); WINUSERAPI DWORD WINAPI GetTabbedTextExtentW(HDC,LPCWSTR,INT,INT,const INT*);
#define GetTabbedTextExtent WINELIB_NAME_AW(GetTabbedTextExtent) #define GetTabbedTextExtent WINELIB_NAME_AW(GetTabbedTextExtent)