sysparams : nonclient metric fixes

Rein Klazes wijn at wanadoo.nl
Wed Dec 14 13:04:58 CST 2005


Hi,

Changelog:
dlls/user		: sysparams.c
dlls/user/tests	: sysparams.c
Implement saving and fix reading of nonclient metrics with conformance
tests.

Rein.
-------------- next part --------------
--- wine/dlls/user/sysparams.c	2005-12-14 13:32:13.000000000 +0100
+++ mywine/dlls/user/sysparams.c	2005-12-14 15:15:22.000000000 +0100
@@ -803,7 +803,7 @@ static BOOL save_int_param( LPCWSTR regk
 
     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 
     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 
 
         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 
 
     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
--- wine/dlls/user/tests/sysparams.c	2005-12-14 13:32:14.000000000 +0100
+++ mywine/dlls/user/tests/sysparams.c	2005-12-14 17:56:11.000000000 +0100
@@ -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 subKey
 #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, (char *) &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 )   
     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,174 @@ static void test_SPI_SETDRAGFULLWINDOWS(
     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);
+    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 +1587,15 @@ static void test_SPI_SETICONMETRICS( voi
     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 +2152,7 @@ static DWORD WINAPI SysParamsThreadFunc(
     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 +2402,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 +2442,6 @@ START_TEST(sysparams)
         TranslateMessage( &msg );
         DispatchMessageA( &msg );
     }
+    ReleaseDC( 0, hdc);
+
 }


More information about the wine-patches mailing list