From 13b9923165b7c1430d1acd1adbf05b35093d54d9 Mon Sep 17 00:00:00 2001 From: Rein Klazes Date: Fri, 16 Dec 2005 12:38:06 +0100 Subject: [PATCH] user32: Implement saving and fix reading of nonclient metrics. With conformance tests. --- dlls/user/sysparams.c | 161 ++++++++++++------ dlls/user/tests/sysparams.c | 314 +++++++++++++++++++++++++++++++++--- 2 files changed, 402 insertions(+), 73 deletions(-) diff --git a/dlls/user/sysparams.c b/dlls/user/sysparams.c index 4b3190ef444..dde61ff4c81 100644 --- a/dlls/user/sysparams.c +++ b/dlls/user/sysparams.c @@ -803,7 +803,7 @@ static BOOL save_int_param( LPCWSTR regkey, LPCWSTR value, INT *value_ptr, wsprintfW(buf, CSd, new_val); if (!SYSPARAMS_Save( regkey, value, buf, fWinIni )) return FALSE; - *value_ptr = new_val; + if( value_ptr) *value_ptr = new_val; return TRUE; } @@ -992,84 +992,105 @@ static void load_minimized_metrics(void) spi_loaded[SPI_MINIMIZEDMETRICS_IDX] = TRUE; } +/* adjust some of the raw values found in the registry */ +static void normalize_nonclientmetrics( NONCLIENTMETRICSW *pncm) +{ + TEXTMETRICW tm; + if( pncm->iBorderWidth < 1) pncm->iBorderWidth = 1; + if( pncm->iCaptionWidth < 8) pncm->iCaptionWidth = 8; + if( pncm->iScrollWidth < 8) pncm->iScrollWidth = 8; + if( pncm->iScrollHeight < 8) pncm->iScrollHeight = 8; + + /* get some extra metrics */ + get_text_metr_size( get_display_dc(), &pncm->lfMenuFont, + &tmMenuFont, NULL); + get_text_metr_size( get_display_dc(), &pncm->lfCaptionFont, + NULL, &CaptionFontAvCharWidth); + + /* adjust some heights to the corresponding font */ + pncm->iMenuHeight = max( pncm->iMenuHeight, + 2 + tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading); + get_text_metr_size( get_display_dc(), &pncm->lfCaptionFont, &tm, NULL); + pncm->iCaptionHeight = max( pncm->iCaptionHeight, 2 + tm.tmHeight); + get_text_metr_size( get_display_dc(), &pncm->lfSmCaptionFont, &tm, NULL); + pncm->iSmCaptionHeight = max( pncm->iSmCaptionHeight, 2 + tm.tmHeight); +} + /* load all the non-client metrics */ static void load_nonclient_metrics(void) { HKEY hkey; + NONCLIENTMETRICSW ncm; if (RegOpenKeyExW (HKEY_CURRENT_USER, METRICS_REGKEY, 0, KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS) hkey = 0; /* initialize geometry entries */ - nonclient_metrics.iBorderWidth = get_reg_metric(hkey, METRICS_BORDERWIDTH_VALNAME, 1); - if( nonclient_metrics.iBorderWidth < 1) nonclient_metrics.iBorderWidth = 1; - nonclient_metrics.iScrollWidth = get_reg_metric(hkey, METRICS_SCROLLWIDTH_VALNAME, 16); - nonclient_metrics.iScrollHeight = get_reg_metric(hkey, METRICS_SCROLLHEIGHT_VALNAME, 16); + ncm.iBorderWidth = get_reg_metric(hkey, METRICS_BORDERWIDTH_VALNAME, 1); + ncm.iScrollWidth = get_reg_metric(hkey, METRICS_SCROLLWIDTH_VALNAME, 16); + ncm.iScrollHeight = get_reg_metric(hkey, METRICS_SCROLLHEIGHT_VALNAME, 16); /* size of the normal caption buttons */ - nonclient_metrics.iCaptionHeight = get_reg_metric(hkey, METRICS_CAPTIONHEIGHT_VALNAME, 18); - nonclient_metrics.iCaptionWidth = get_reg_metric(hkey, METRICS_CAPTIONWIDTH_VALNAME, nonclient_metrics.iCaptionHeight); + ncm.iCaptionHeight = get_reg_metric(hkey, METRICS_CAPTIONHEIGHT_VALNAME, 18); + ncm.iCaptionWidth = get_reg_metric(hkey, METRICS_CAPTIONWIDTH_VALNAME, ncm.iCaptionHeight); /* caption font metrics */ - if (!reg_get_logfont(METRICS_REGKEY, METRICS_CAPTIONLOGFONT_VALNAME, &nonclient_metrics.lfCaptionFont)) + if (!reg_get_logfont(METRICS_REGKEY, METRICS_CAPTIONLOGFONT_VALNAME, &ncm.lfCaptionFont)) { - SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfCaptionFont, 0 ); - nonclient_metrics.lfCaptionFont.lfWeight = FW_BOLD; + SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &ncm.lfCaptionFont, 0 ); + ncm.lfCaptionFont.lfWeight = FW_BOLD; } /* size of the small caption buttons */ - nonclient_metrics.iSmCaptionWidth = get_reg_metric(hkey, METRICS_SMCAPTIONWIDTH_VALNAME, 13); - nonclient_metrics.iSmCaptionHeight = get_reg_metric(hkey, METRICS_SMCAPTIONHEIGHT_VALNAME, 15); + ncm.iSmCaptionWidth = get_reg_metric(hkey, METRICS_SMCAPTIONWIDTH_VALNAME, 13); + ncm.iSmCaptionHeight = get_reg_metric(hkey, METRICS_SMCAPTIONHEIGHT_VALNAME, 15); /* small caption font metrics */ - if (!reg_get_logfont(METRICS_REGKEY, METRICS_SMCAPTIONLOGFONT_VALNAME, &nonclient_metrics.lfSmCaptionFont)) - SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfSmCaptionFont, 0 ); + if (!reg_get_logfont(METRICS_REGKEY, METRICS_SMCAPTIONLOGFONT_VALNAME, &ncm.lfSmCaptionFont)) + SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &ncm.lfSmCaptionFont, 0 ); /* menus, FIXME: names of wine.conf entries are bogus */ /* size of the menu (MDI) buttons */ - nonclient_metrics.iMenuHeight = get_reg_metric(hkey, METRICS_MENUHEIGHT_VALNAME, 18); - nonclient_metrics.iMenuWidth = get_reg_metric(hkey, METRICS_MENUWIDTH_VALNAME, nonclient_metrics.iMenuHeight); + ncm.iMenuHeight = get_reg_metric(hkey, METRICS_MENUHEIGHT_VALNAME, 18); + ncm.iMenuWidth = get_reg_metric(hkey, METRICS_MENUWIDTH_VALNAME, ncm.iMenuHeight); /* menu font metrics */ - if (!reg_get_logfont(METRICS_REGKEY, METRICS_MENULOGFONT_VALNAME, &nonclient_metrics.lfMenuFont)) + if (!reg_get_logfont(METRICS_REGKEY, METRICS_MENULOGFONT_VALNAME, &ncm.lfMenuFont)) { - SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfMenuFont, 0 ); - GetProfileStringW( Desktop, MenuFont, nonclient_metrics.lfCaptionFont.lfFaceName, - nonclient_metrics.lfMenuFont.lfFaceName, LF_FACESIZE ); - nonclient_metrics.lfMenuFont.lfHeight = -GetProfileIntW( Desktop, MenuFontSize, 11 ); - nonclient_metrics.lfMenuFont.lfWeight = FW_NORMAL; + SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &ncm.lfMenuFont, 0 ); + GetProfileStringW( Desktop, MenuFont, ncm.lfCaptionFont.lfFaceName, + ncm.lfMenuFont.lfFaceName, LF_FACESIZE ); + ncm.lfMenuFont.lfHeight = -GetProfileIntW( Desktop, MenuFontSize, 11 ); + ncm.lfMenuFont.lfWeight = FW_NORMAL; } /* status bar font metrics */ - if (!reg_get_logfont(METRICS_REGKEY, METRICS_STATUSLOGFONT_VALNAME, &nonclient_metrics.lfStatusFont)) + if (!reg_get_logfont(METRICS_REGKEY, METRICS_STATUSLOGFONT_VALNAME, &ncm.lfStatusFont)) { - SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfStatusFont, 0 ); - GetProfileStringW( Desktop, StatusFont, nonclient_metrics.lfCaptionFont.lfFaceName, - nonclient_metrics.lfStatusFont.lfFaceName, LF_FACESIZE ); - nonclient_metrics.lfStatusFont.lfHeight = -GetProfileIntW( Desktop, StatusFontSize, 11 ); - nonclient_metrics.lfStatusFont.lfWeight = FW_NORMAL; + SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &ncm.lfStatusFont, 0 ); + GetProfileStringW( Desktop, StatusFont, ncm.lfCaptionFont.lfFaceName, + ncm.lfStatusFont.lfFaceName, LF_FACESIZE ); + ncm.lfStatusFont.lfHeight = -GetProfileIntW( Desktop, StatusFontSize, 11 ); + ncm.lfStatusFont.lfWeight = FW_NORMAL; } /* message font metrics */ - if (!reg_get_logfont(METRICS_REGKEY, METRICS_MESSAGELOGFONT_VALNAME, &nonclient_metrics.lfMessageFont)) + if (!reg_get_logfont(METRICS_REGKEY, METRICS_MESSAGELOGFONT_VALNAME, &ncm.lfMessageFont)) { - SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &nonclient_metrics.lfMessageFont, 0 ); - GetProfileStringW( Desktop, MessageFont, nonclient_metrics.lfCaptionFont.lfFaceName, - nonclient_metrics.lfMessageFont.lfFaceName, LF_FACESIZE ); - nonclient_metrics.lfMessageFont.lfHeight = -GetProfileIntW( Desktop, MessageFontSize, 11 ); - nonclient_metrics.lfMessageFont.lfWeight = FW_NORMAL; + SystemParametersInfoW( SPI_GETICONTITLELOGFONT, 0, &ncm.lfMessageFont, 0 ); + GetProfileStringW( Desktop, MessageFont, ncm.lfCaptionFont.lfFaceName, + ncm.lfMessageFont.lfFaceName, LF_FACESIZE ); + ncm.lfMessageFont.lfHeight = -GetProfileIntW( Desktop, MessageFontSize, 11 ); + ncm.lfMessageFont.lfWeight = FW_NORMAL; } /* some extra fields not in the nonclient structure */ icon_size.cx = icon_size.cy = get_reg_metric( hkey, METRICS_ICONSIZE_VALNAME, 32 ); - get_text_metr_size( get_display_dc(), &nonclient_metrics.lfMenuFont, - &tmMenuFont, NULL); - get_text_metr_size( get_display_dc(), &nonclient_metrics.lfCaptionFont, - NULL, &CaptionFontAvCharWidth); - if (hkey) RegCloseKey( hkey ); + normalize_nonclientmetrics( &ncm); + memcpy( &nonclient_metrics, &ncm, sizeof(nonclient_metrics) ); spi_loaded[SPI_NONCLIENTMETRICS_IDX] = TRUE; } @@ -1115,8 +1136,6 @@ BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam, BOOL ret = TRUE; unsigned spi_idx = 0; - TRACE("(%u, %u, %p, %u)\n", uiAction, uiParam, pvParam, fWinIni); - switch (uiAction) { case SPI_GETBEEP: /* 1 */ @@ -1494,15 +1513,55 @@ BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam, if (lpnm && lpnm->cbSize == sizeof(NONCLIENTMETRICSW)) { - /* FIXME: there are likely a few more parameters to save here */ - set_uint_param( SPI_SETBORDER_IDX, - SPI_SETBORDER_REGKEY, - SPI_SETBORDER_VALNAME, - &border, - lpnm->iBorderWidth, fWinIni ); - if( lpnm->iBorderWidth < 1) lpnm->iBorderWidth = 1; - memcpy( &nonclient_metrics, lpnm, sizeof(nonclient_metrics) ); - spi_loaded[SPI_NONCLIENTMETRICS_IDX] = TRUE; + NONCLIENTMETRICSW ncm; + ret = set_uint_param( SPI_SETBORDER_IDX, + SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, + &border, lpnm->iBorderWidth, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_SCROLLWIDTH_VALNAME, NULL, + lpnm->iScrollWidth, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_SCROLLHEIGHT_VALNAME, NULL, + lpnm->iScrollHeight, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_CAPTIONWIDTH_VALNAME, NULL, + lpnm->iCaptionWidth, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_CAPTIONHEIGHT_VALNAME, NULL, + lpnm->iCaptionHeight, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_SMCAPTIONWIDTH_VALNAME, NULL, + lpnm->iSmCaptionWidth, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_SMCAPTIONHEIGHT_VALNAME, NULL, + lpnm->iSmCaptionHeight, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_MENUWIDTH_VALNAME, NULL, + lpnm->iMenuWidth, fWinIni ); + if( ret) ret = save_int_param( METRICS_REGKEY, + METRICS_MENUHEIGHT_VALNAME, NULL, + lpnm->iMenuHeight, fWinIni ); + if( ret) ret = SYSPARAMS_SaveLogFont( + METRICS_REGKEY, METRICS_MENULOGFONT_VALNAME, + &lpnm->lfMenuFont, fWinIni); + if( ret) ret = SYSPARAMS_SaveLogFont( + METRICS_REGKEY, METRICS_CAPTIONLOGFONT_VALNAME, + &lpnm->lfCaptionFont, fWinIni); + if( ret) ret = SYSPARAMS_SaveLogFont( + METRICS_REGKEY, METRICS_SMCAPTIONLOGFONT_VALNAME, + &lpnm->lfSmCaptionFont, fWinIni); + if( ret) ret = SYSPARAMS_SaveLogFont( + METRICS_REGKEY, METRICS_STATUSLOGFONT_VALNAME, + &lpnm->lfStatusFont, fWinIni); + if( ret) ret = SYSPARAMS_SaveLogFont( + METRICS_REGKEY, METRICS_MESSAGELOGFONT_VALNAME, + &lpnm->lfMessageFont, fWinIni); + if( ret) { + memcpy( &ncm, lpnm, sizeof(nonclient_metrics) ); + normalize_nonclientmetrics( &ncm); + memcpy( &nonclient_metrics, &ncm, sizeof(nonclient_metrics) ); + spi_loaded[SPI_NONCLIENTMETRICS_IDX] = TRUE; + } } break; } @@ -2140,6 +2199,8 @@ BOOL WINAPI SystemParametersInfoW( UINT uiAction, UINT uiParam, if (ret) SYSPARAMS_NotifyChange( uiAction, fWinIni ); + TRACE("(%u, %u, %p, %u) ret %d\n", + uiAction, uiParam, pvParam, fWinIni, ret); return ret; #undef WINE_SPI_FIXME diff --git a/dlls/user/tests/sysparams.c b/dlls/user/tests/sysparams.c index bb519bc84c3..ac7c9078e9f 100644 --- a/dlls/user/tests/sysparams.c +++ b/dlls/user/tests/sysparams.c @@ -31,6 +31,7 @@ #include "wingdi.h" #include "winreg.h" #include "winuser.h" +#include "winnls.h" #ifndef SPI_GETDESKWALLPAPER # define SPI_GETDESKWALLPAPER 0x0073 @@ -38,6 +39,7 @@ static int strict; static int dpi; +static HDC hdc; #define eq(received, expected, label, type) \ ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected)) @@ -52,6 +54,21 @@ static int dpi; #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop\\WindowMetrics" #define SPI_SETBORDER_REGKEY2 "Control Panel\\Desktop" #define SPI_SETBORDER_VALNAME "BorderWidth" +#define SPI_METRIC_REGKEY "Control Panel\\Desktop\\WindowMetrics" +#define SPI_SCROLLWIDTH_VALNAME "ScrollWidth" +#define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight" +#define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth" +#define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight" +#define SPI_CAPTIONFONT_VALNAME "CaptionFont" +#define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth" +#define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight" +#define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont" +#define SPI_MENUWIDTH_VALNAME "MenuWidth" +#define SPI_MENUHEIGHT_VALNAME "MenuHeight" +#define SPI_MENUFONT_VALNAME "MenuFont" +#define SPI_STATUSFONT_VALNAME "StatusFont" +#define SPI_MESSAGEFONT_VALNAME "MessageFont" + #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard" #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed" #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics" @@ -314,6 +331,98 @@ static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCS #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \ _test_reg_key( subKey1, subKey2, valName1, valName2, testValue ) +/* get a metric from the registry. If the value is negative + * it is assumed to be in twips and converted to pixels */ +static UINT metricfromreg( char *keyname, char *valname, int dpi) +{ + HKEY hkey; + char buf[64]; + DWORD ret; + DWORD size, type; + int value; + + RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey ); + size = sizeof(buf); + ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size ); + RegCloseKey( hkey ); + if( ret != ERROR_SUCCESS) return -1; + value = atoi( buf); + if( value < 0) + value = ( -value * dpi + 720) / 1440; + return value; +} + +typedef struct +{ + INT16 lfHeight; + INT16 lfWidth; + INT16 lfEscapement; + INT16 lfOrientation; + INT16 lfWeight; + BYTE lfItalic; + BYTE lfUnderline; + BYTE lfStrikeOut; + BYTE lfCharSet; + BYTE lfOutPrecision; + BYTE lfClipPrecision; + BYTE lfQuality; + BYTE lfPitchAndFamily; + CHAR lfFaceName[LF_FACESIZE]; +} LOGFONT16, *LPLOGFONT16; + +/* get logfont from the registry */ +static int lffromreg( char *keyname, char *valname, LOGFONTA *plf) +{ + HKEY hkey; + LOGFONTW lfw; + DWORD ret, size, type; + + RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey ); + size = sizeof( lfw); + ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size ); + RegCloseKey( hkey ); + ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname); + if( ret != ERROR_SUCCESS) + return FALSE; + if( size <= sizeof( LOGFONT16)) { + LOGFONT16 *plf16 = (LOGFONT16*) &lfw; + plf->lfHeight = plf16->lfHeight; + plf->lfWidth = plf16->lfWidth; + plf->lfEscapement = plf16->lfEscapement; + plf->lfOrientation = plf16->lfOrientation; + plf->lfWeight = plf16->lfWeight; + plf->lfItalic = plf16->lfItalic; + plf->lfUnderline = plf16->lfUnderline; + plf->lfStrikeOut = plf16->lfStrikeOut; + plf->lfCharSet = plf16->lfCharSet; + plf->lfOutPrecision = plf16->lfOutPrecision; + plf->lfClipPrecision = plf16->lfClipPrecision; + plf->lfQuality = plf16->lfQuality; + plf->lfPitchAndFamily = plf16->lfPitchAndFamily; + memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE ); + } else if( size <= sizeof( LOGFONTA)) { + plf = (LOGFONTA*) &lfw; + } else { + plf->lfHeight = lfw.lfHeight; + plf->lfWidth = lfw.lfWidth; + plf->lfEscapement = lfw.lfEscapement; + plf->lfOrientation = lfw.lfOrientation; + plf->lfWeight = lfw.lfWeight; + plf->lfItalic = lfw.lfItalic; + plf->lfUnderline = lfw.lfUnderline; + plf->lfStrikeOut = lfw.lfStrikeOut; + plf->lfCharSet = lfw.lfCharSet; + plf->lfOutPrecision = lfw.lfOutPrecision; + plf->lfClipPrecision = lfw.lfClipPrecision; + plf->lfQuality = lfw.lfQuality; + plf->lfPitchAndFamily = lfw.lfPitchAndFamily; + WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName, + LF_FACESIZE, NULL, NULL); + + } + return TRUE; +} + static void test_SPI_SETBEEP( void ) /* 2 */ { BOOL rc; @@ -517,27 +626,6 @@ static void test_SPI_SETMOUSE( void ) /* 4 */ ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); } -/* get a metric from the registry. If the value is negative - * it is assumed to be in twips and converted to pixels */ -static UINT metricfromreg( char *keyname, char *valname, int dpi) -{ - HKEY hkey; - char buf[64]; - DWORD ret; - DWORD size, type; - int value; - - RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey ); - size = sizeof(buf); - ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size ); - RegCloseKey( hkey ); - if( ret != ERROR_SUCCESS) return -1; - value = atoi( buf); - if( value < 0) - value = ( -value * dpi + 720) / 1440; - return value; -} - static void test_setborder(UINT curr_val, int usesetborder, int dpi) { BOOL rc; @@ -1192,6 +1280,175 @@ static void test_SPI_SETDRAGFULLWINDOWS( void ) /* 37 */ ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); } +#define test_reg_metric( KEY, VAL, val) \ +{ INT regval;\ + regval = metricfromreg( KEY, VAL, dpi);\ + ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\ +} + +#define test_reg_metric2( KEY1, KEY2, VAL, val) \ +{ INT regval;\ + regval = metricfromreg( KEY1, VAL, dpi);\ + if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\ + ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\ +} + +#define test_reg_font( KEY, VAL, LF) \ +{ LOGFONTA lfreg;\ + lffromreg( KEY, VAL, &lfreg);\ + ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == lfreg.lfHeight :\ + MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\ + (LF).lfWidth == lfreg.lfWidth &&\ + (LF).lfWeight == lfreg.lfWeight &&\ + !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\ + , "wrong value \"%s\" in registry %ld, %ld\n", VAL, (LF).lfHeight, lfreg.lfHeight);\ +} + +#define TEST_NONCLIENTMETRICS_REG( ncm) \ +test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\ +/*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\ +test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\ +test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont); + +/* get text metric height value for the specified logfont */ +static int get_tmheight( LOGFONTA *plf, int flag) +{ + TEXTMETRICA tm; + HFONT hfont = CreateFontIndirectA( plf); + hfont = SelectObject( hdc, hfont); + GetTextMetricsA( hdc, &tm); + hfont = SelectObject( hdc, hfont); + return tm.tmHeight + (flag ? tm.tmExternalLeading : 0); +} + +void test_GetSystemMetrics( void); + +static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */ +{ + BOOL rc; + INT expect; + NONCLIENTMETRICSA Ncmorig; + NONCLIENTMETRICSA Ncmnew; + NONCLIENTMETRICSA Ncmcur; + NONCLIENTMETRICSA Ncmstart; + + Ncmorig.cbSize = sizeof(NONCLIENTMETRICSA); + Ncmnew.cbSize = sizeof(NONCLIENTMETRICSA); + Ncmcur.cbSize = sizeof(NONCLIENTMETRICSA); + Ncmstart.cbSize = sizeof(NONCLIENTMETRICSA); + + trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n"); + SetLastError(0xdeadbeef); + rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmorig, FALSE ); + if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS")) + return; + Ncmstart = Ncmorig; + /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if + the caption font height is higher than the CaptionHeight field, + the latter is adjusted accordingly. To be able to restore these setting + accurately be restore the raw values. */ + Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, dpi); + Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi); + Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi); + Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi); + /* test registry entries */ + TEST_NONCLIENTMETRICS_REG( Ncmorig) + /* make small changes */ + Ncmnew = Ncmstart; + Ncmnew.iBorderWidth += 1; + Ncmnew.iScrollWidth += 1; + Ncmnew.iScrollHeight -= 1; + Ncmnew.iCaptionWidth -= 2; + Ncmnew.iCaptionHeight += 2; + Ncmnew.lfCaptionFont.lfHeight +=1; + Ncmnew.lfCaptionFont.lfWidth +=2; + Ncmnew.lfCaptionFont.lfWeight +=1; + Ncmnew.iSmCaptionWidth += 1; + Ncmnew.iSmCaptionHeight += 2; + Ncmnew.lfSmCaptionFont.lfHeight +=3; + Ncmnew.lfSmCaptionFont.lfWidth -=1; + Ncmnew.lfSmCaptionFont.lfWeight +=3; + Ncmnew.iMenuWidth += 1; + Ncmnew.iMenuHeight += 2; + Ncmnew.lfMenuFont.lfHeight +=1; + Ncmnew.lfMenuFont.lfWidth +=1; + Ncmnew.lfMenuFont.lfWeight +=2; + Ncmnew.lfStatusFont.lfHeight -=1; + Ncmnew.lfStatusFont.lfWidth -=1; + Ncmnew.lfStatusFont.lfWeight +=3; + Ncmnew.lfMessageFont.lfHeight -=2; + Ncmnew.lfMessageFont.lfWidth -=1; + Ncmnew.lfMessageFont.lfWeight +=4; + + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE| + SPIF_SENDCHANGE); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_SETNONCLIENTMETRICS, 1 ); + /* get them back */ + rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmcur, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + /* test registry entries */ + TEST_NONCLIENTMETRICS_REG( Ncmcur) + /* test the systemm metrics with these settings */ + test_GetSystemMetrics(); + /* now for something invalid: increase the {menu|caption|smcaption} fonts + by a large amount will increase the {menu|caption|smcaption} height*/ + Ncmnew = Ncmstart; + Ncmnew.lfMenuFont.lfHeight -= 8; + Ncmnew.lfCaptionFont.lfHeight =-4; + Ncmnew.lfSmCaptionFont.lfHeight -=10; + /* also show that a few values are lo limited */ + Ncmnew.iCaptionWidth = 0; + Ncmnew.iCaptionHeight = 0; + Ncmnew.iScrollHeight = 0; + Ncmnew.iScrollWidth = 0; + + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE| + SPIF_SENDCHANGE); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + test_change_message( SPI_SETNONCLIENTMETRICS, 1 ); + /* raw values are in registry */ + TEST_NONCLIENTMETRICS_REG( Ncmnew) + /* get them back */ + rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmcur, FALSE ); + ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,GetLastError()); + /* cooked values are returned */ + expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1)); + ok( Ncmcur.iMenuHeight == expect, + "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect); + expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0)); + ok( Ncmcur.iCaptionHeight == expect, + "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect); + expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0)); + ok( Ncmcur.iSmCaptionHeight == expect, + "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect); + + ok( Ncmcur.iCaptionWidth == 8 || + Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */ + "CaptionWidth: %d expected 8\n", Ncmcur.iCaptionWidth); + ok( Ncmcur.iScrollWidth == 8, + "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth); + ok( Ncmcur.iScrollHeight == 8, + "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight); + /* test the systemm metrics with these settings */ + test_GetSystemMetrics(); + /* restore */ + rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), + &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE); + test_change_message( SPI_SETNONCLIENTMETRICS, 0 ); + ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%ld\n",rc,GetLastError()); +} + static void test_SPI_SETMINIMIZEDMETRICS( void ) /* 44 */ { BOOL rc; @@ -1331,6 +1588,15 @@ static void test_SPI_SETICONMETRICS( void ) /* 46 */ rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE ); if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS")) return; + /* check some registry values */ + regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi); + ok( regval==im_orig.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing); + regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi); + ok( regval==im_orig.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing); + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi); + if( regval != im_orig.iTitleWrap) + regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi); + ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap); /* change everything without creating something invalid ( Win9x would ignore * an invalid font for instance) */ @@ -1887,6 +2153,7 @@ static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam ) test_SPI_SETMOUSEBUTTONSWAP(); /* 33 */ test_SPI_SETFASTTASKSWITCH(); /* 36 */ test_SPI_SETDRAGFULLWINDOWS(); /* 37 */ + test_SPI_SETNONCLIENTMETRICS(); /* 42 */ test_SPI_SETMINIMIZEDMETRICS(); /* 44 */ test_SPI_SETICONMETRICS(); /* 46 */ test_SPI_SETWORKAREA(); /* 47 */ @@ -2136,9 +2403,8 @@ START_TEST(sysparams) DWORD dwThreadId; HANDLE hInstance = GetModuleHandleA( NULL ); - HDC hdc = GetDC(0); + hdc = GetDC(0); dpi = GetDeviceCaps( hdc, LOGPIXELSY); - ReleaseDC( 0, hdc); /* This test requires interactivity, if we don't have it, give up */ if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) && @@ -2177,4 +2443,6 @@ START_TEST(sysparams) TranslateMessage( &msg ); DispatchMessageA( &msg ); } + ReleaseDC( 0, hdc); + }