user32: Add a test for EnumDisplaySettings vs GetDeviceCaps.
[wine] / dlls / user32 / tests / sysparams.c
1 /* Unit test suite for functions SystemParametersInfo and GetSystemMetrics.
2  *
3  * Copyright 2002 Andriy Palamarchuk
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include <assert.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24
25 #undef _WIN32_WINNT
26 #define _WIN32_WINNT 0x0500 /* For SPI_GETMOUSEHOVERWIDTH and more */
27
28 #include "wine/test.h"
29 #include "windef.h"
30 #include "winbase.h"
31 #include "wingdi.h"
32 #include "winreg.h"
33 #include "winuser.h"
34 #include "winnls.h"
35
36 #ifndef SPI_GETDESKWALLPAPER
37 # define SPI_GETDESKWALLPAPER 0x0073
38 #endif
39
40 static int strict;
41 static int dpi;
42 static int iswin9x;
43 static HDC hdc;
44
45 #define eq(received, expected, label, type) \
46         ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
47
48
49 #define SPI_SETBEEP_REGKEY                      "Control Panel\\Sound"
50 #define SPI_SETBEEP_VALNAME                     "Beep"
51 #define SPI_SETMOUSE_REGKEY                     "Control Panel\\Mouse"
52 #define SPI_SETMOUSE_VALNAME1                   "MouseThreshold1"
53 #define SPI_SETMOUSE_VALNAME2                   "MouseThreshold2"
54 #define SPI_SETMOUSE_VALNAME3                   "MouseSpeed"
55 #define SPI_SETBORDER_REGKEY                    "Control Panel\\Desktop\\WindowMetrics"
56 #define SPI_SETBORDER_REGKEY2                   "Control Panel\\Desktop"
57 #define SPI_SETBORDER_VALNAME                   "BorderWidth"
58 #define SPI_METRIC_REGKEY                       "Control Panel\\Desktop\\WindowMetrics"
59 #define SPI_SCROLLWIDTH_VALNAME                 "ScrollWidth"
60 #define SPI_SCROLLHEIGHT_VALNAME                "ScrollHeight"
61 #define SPI_CAPTIONWIDTH_VALNAME                "CaptionWidth"
62 #define SPI_CAPTIONHEIGHT_VALNAME               "CaptionHeight"
63 #define SPI_CAPTIONFONT_VALNAME                 "CaptionFont"
64 #define SPI_SMCAPTIONWIDTH_VALNAME              "SmCaptionWidth"
65 #define SPI_SMCAPTIONHEIGHT_VALNAME             "SmCaptionHeight"
66 #define SPI_SMCAPTIONFONT_VALNAME               "SmCaptionFont"
67 #define SPI_MENUWIDTH_VALNAME                   "MenuWidth"
68 #define SPI_MENUHEIGHT_VALNAME                  "MenuHeight"
69 #define SPI_MENUFONT_VALNAME                    "MenuFont"
70 #define SPI_STATUSFONT_VALNAME                  "StatusFont"
71 #define SPI_MESSAGEFONT_VALNAME                 "MessageFont"
72
73 #define SPI_SETKEYBOARDSPEED_REGKEY             "Control Panel\\Keyboard"
74 #define SPI_SETKEYBOARDSPEED_VALNAME            "KeyboardSpeed"
75 #define SPI_ICONHORIZONTALSPACING_REGKEY        "Control Panel\\Desktop\\WindowMetrics"
76 #define SPI_ICONHORIZONTALSPACING_REGKEY2       "Control Panel\\Desktop"
77 #define SPI_ICONHORIZONTALSPACING_VALNAME       "IconSpacing"
78 #define SPI_ICONVERTICALSPACING_REGKEY          "Control Panel\\Desktop\\WindowMetrics"
79 #define SPI_ICONVERTICALSPACING_REGKEY2         "Control Panel\\Desktop"
80 #define SPI_ICONVERTICALSPACING_VALNAME         "IconVerticalSpacing"
81 #define SPI_MINIMIZEDMETRICS_REGKEY             "Control Panel\\Desktop\\WindowMetrics"
82 #define SPI_MINWIDTH_VALNAME                    "MinWidth"
83 #define SPI_MINHORZGAP_VALNAME                  "MinHorzGap"
84 #define SPI_MINVERTGAP_VALNAME                  "MinVertGap"
85 #define SPI_MINARRANGE_VALNAME                  "MinArrange"
86 #define SPI_SETSCREENSAVETIMEOUT_REGKEY         "Control Panel\\Desktop"
87 #define SPI_SETSCREENSAVETIMEOUT_VALNAME        "ScreenSaveTimeOut"
88 #define SPI_SETSCREENSAVEACTIVE_REGKEY          "Control Panel\\Desktop"
89 #define SPI_SETSCREENSAVEACTIVE_VALNAME         "ScreenSaveActive"
90 #define SPI_SETGRIDGRANULARITY_REGKEY           "Control Panel\\Desktop"
91 #define SPI_SETGRIDGRANULARITY_VALNAME          "GridGranularity"
92 #define SPI_SETKEYBOARDDELAY_REGKEY             "Control Panel\\Keyboard"
93 #define SPI_SETKEYBOARDDELAY_VALNAME            "KeyboardDelay"
94 #define SPI_SETICONTITLEWRAP_REGKEY1            "Control Panel\\Desktop\\WindowMetrics"
95 #define SPI_SETICONTITLEWRAP_REGKEY2            "Control Panel\\Desktop"
96 #define SPI_SETICONTITLEWRAP_VALNAME            "IconTitleWrap"
97 #define SPI_SETMENUDROPALIGNMENT_REGKEY1        "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
98 #define SPI_SETMENUDROPALIGNMENT_REGKEY2        "Control Panel\\Desktop"
99 #define SPI_SETMENUDROPALIGNMENT_VALNAME        "MenuDropAlignment"
100 #define SPI_SETDOUBLECLKWIDTH_REGKEY1           "Control Panel\\Mouse"
101 #define SPI_SETDOUBLECLKWIDTH_REGKEY2           "Control Panel\\Desktop"
102 #define SPI_SETDOUBLECLKWIDTH_VALNAME           "DoubleClickWidth"
103 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1          "Control Panel\\Mouse"
104 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2          "Control Panel\\Desktop"
105 #define SPI_SETDOUBLECLKHEIGHT_VALNAME          "DoubleClickHeight"
106 #define SPI_SETDOUBLECLICKTIME_REGKEY           "Control Panel\\Mouse"
107 #define SPI_SETDOUBLECLICKTIME_VALNAME          "DoubleClickSpeed"
108 #define SPI_SETMOUSEBUTTONSWAP_REGKEY           "Control Panel\\Mouse"
109 #define SPI_SETMOUSEBUTTONSWAP_VALNAME          "SwapMouseButtons"
110 #define SPI_SETWORKAREA_REGKEY                  "Control Panel\\Desktop"
111 #define SPI_SETWORKAREA_VALNAME                 "WINE_WorkArea"
112 #define SPI_SETSHOWSOUNDS_REGKEY                "Control Panel\\Accessibility\\ShowSounds"
113 #define SPI_SETSHOWSOUNDS_VALNAME               "On"
114 #define SPI_SETKEYBOARDPREF_REGKEY              "Control Panel\\Accessibility\\Keyboard Preference"
115 #define SPI_SETKEYBOARDPREF_VALNAME             "On"
116 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY       "Control Panel\\Accessibility"
117 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY      "Keyboard Preference"
118 #define SPI_SETSCREENREADER_REGKEY              "Control Panel\\Accessibility\\Blind Access"
119 #define SPI_SETSCREENREADER_VALNAME             "On"
120 #define SPI_SETSCREENREADER_REGKEY_LEGACY       "Control Panel\\Accessibility"
121 #define SPI_SETSCREENREADER_VALNAME_LEGACY      "Blind Access"
122 #define SPI_SETFONTSMOOTHING_REGKEY             "Control Panel\\Desktop"
123 #define SPI_SETFONTSMOOTHING_VALNAME            "FontSmoothing"
124 #define SPI_SETLOWPOWERACTIVE_REGKEY            "Control Panel\\Desktop"
125 #define SPI_SETLOWPOWERACTIVE_VALNAME           "LowPowerActive"
126 #define SPI_SETPOWEROFFACTIVE_REGKEY            "Control Panel\\Desktop"
127 #define SPI_SETPOWEROFFACTIVE_VALNAME           "PowerOffActive"
128 #define SPI_SETDRAGFULLWINDOWS_REGKEY           "Control Panel\\Desktop"
129 #define SPI_SETDRAGFULLWINDOWS_VALNAME          "DragFullWindows"
130 #define SPI_SETMOUSEHOVERWIDTH_REGKEY           "Control Panel\\Mouse"
131 #define SPI_SETMOUSEHOVERWIDTH_VALNAME          "MouseHoverWidth"
132 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY          "Control Panel\\Mouse"
133 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME         "MouseHoverHeight"
134 #define SPI_SETMOUSEHOVERTIME_REGKEY            "Control Panel\\Mouse"
135 #define SPI_SETMOUSEHOVERTIME_VALNAME           "MouseHoverTime"
136 #define SPI_SETMOUSESCROLLLINES_REGKEY          "Control Panel\\Desktop"
137 #define SPI_SETMOUSESCROLLLINES_VALNAME         "WheelScrollLines"
138 #define SPI_SETMENUSHOWDELAY_REGKEY             "Control Panel\\Desktop"
139 #define SPI_SETMENUSHOWDELAY_VALNAME            "MenuShowDelay"
140 #define SPI_SETDESKWALLPAPER_REGKEY             "Control Panel\\Desktop"
141 #define SPI_SETDESKWALLPAPER_VALNAME            "Wallpaper"
142
143 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
144 #define WINE_CURRENT_USER_REGKEY     "Wine"
145
146 static HWND ghTestWnd;
147
148 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
149 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
150                                               LPARAM lParam );
151 static int change_counter;
152 static int change_last_param;
153 static int last_bpp;
154 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
155 static HANDLE displaychange_sem = 0;
156
157 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
158                                               LPARAM lParam )
159 {
160     switch (msg) {
161
162     case WM_DISPLAYCHANGE:
163         ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
164         last_bpp = wParam;
165         displaychange_ok = FALSE;
166         ReleaseSemaphore(displaychange_sem, 1, 0);
167         break;
168
169     case WM_SETTINGCHANGE:
170         if (change_counter>0) { 
171             /* ignore these messages caused by resizing of toolbars */
172             if( wParam == SPI_SETWORKAREA || displaychange_test_active) break;
173             if( change_last_param == SPI_SETWORKAREA) {
174                 change_last_param = wParam;
175                 break;
176             }
177             ok(0,"too many changes counter=%d last change=%d\n",
178                change_counter,change_last_param);
179         }
180         change_counter++;
181         change_last_param = wParam;
182         break;
183
184     case WM_DESTROY:
185         PostQuitMessage( 0 );
186         break;
187
188     /* drop through */
189     default:
190         return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
191     }
192
193     return 0;
194 }
195
196 /*
197 Performs testing for system parameters messages
198 params:
199  - system parameter id
200  - supposed value of the registry key
201 */
202 static void test_change_message( int action, int optional )
203 {
204     if (change_counter==0 && optional==1)
205         return;
206     ok( 1 == change_counter,
207         "Missed a message: change_counter=%d\n", change_counter );
208     change_counter = 0;
209     ok( action == change_last_param,
210         "Wrong action got %d expected %d\n", change_last_param, action );
211     change_last_param = 0;
212 }
213
214 static BOOL test_error_msg ( int rc, const char *name )
215 {
216     DWORD last_error = GetLastError();
217
218     if (rc==0)
219     {
220         if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE)
221         {
222             trace("%s not supported on this platform. Skipping test\n", name);
223         }
224         else if (last_error==ERROR_ACCESS_DENIED)
225         {
226             trace("%s does not have privileges to run. Skipping test\n", name);
227         }
228         else
229         {
230             trace("%s failed for reason: %d. Indicating test failure and skipping remainder of test\n",name,last_error);
231             ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
232         }
233         return FALSE;
234     }
235     else
236     {
237         ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
238         return TRUE;
239     }
240 }
241
242 /*
243  * Tests the HKEY_CURRENT_USER subkey value.
244  * The value should contain string value.
245  *
246  * Params:
247  * lpsSubKey - subkey name
248  * lpsRegName - registry entry name
249  * lpsTestValue - value to test
250  */
251 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2, LPCSTR testValue )
252 {
253     CHAR  value[MAX_PATH];
254     DWORD valueLen;
255     DWORD type;
256     HKEY hKey;
257     LONG rc;
258     int found=0;
259
260     *value='\0';
261     valueLen=sizeof(value);
262     RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
263     rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
264     RegCloseKey( hKey );
265     if (rc==ERROR_SUCCESS)
266     {
267         ok( !strcmp( testValue, value ),
268             "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
269             subKey1, valName1, testValue, value );
270         found++;
271     }
272     else if (strict)
273     {
274         ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
275            subKey1, valName1);
276     }
277     if (valName2)
278     {
279         *value='\0';
280         valueLen=sizeof(value);
281         RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
282         rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
283         RegCloseKey( hKey );
284         if (rc==ERROR_SUCCESS)
285         {
286             ok( !strcmp( testValue, value ),
287                 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
288                 subKey1, valName2, testValue, value );
289             found++;
290         }
291         else if (strict)
292         {
293             ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
294                 subKey1, valName2 );
295         }
296     }
297     if (subKey2 && !strict)
298     {
299         *value='\0';
300         valueLen=sizeof(value);
301         RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
302         rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
303         RegCloseKey( hKey );
304         if (rc==ERROR_SUCCESS)
305         {
306             ok( !strcmp( testValue, value ),
307                 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
308                 subKey2, valName1, testValue, value );
309             found++;
310         }
311         else if (strict)
312         {
313             ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
314                 subKey2, valName1 );
315         }
316         if (valName2)
317         {
318             *value='\0';
319             valueLen=sizeof(value);
320             RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
321             rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
322             RegCloseKey( hKey );
323             if (rc==ERROR_SUCCESS)
324             {
325                 ok( !strcmp( testValue, value ),
326                     "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
327                     subKey2, valName2, testValue, value );
328                 found++;
329             }
330             else if (strict)
331             {
332                 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
333                     subKey2, valName2 );
334             }
335          }
336     }
337     ok(found,"Missing registry values: %s or %s in keys: %s or %s\n",
338        valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
339 }
340
341 #define test_reg_key( subKey, valName, testValue ) \
342     _test_reg_key( subKey, NULL, valName, NULL, testValue )
343 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
344     _test_reg_key( subKey1, subKey2, valName, NULL, testValue )
345 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
346     _test_reg_key( subKey1, subKey2, valName1, valName2, testValue )
347
348 /* get a metric from the registry. If the value is negative
349  * it is assumed to be in twips and converted to pixels */
350 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
351 {
352     HKEY hkey;
353     char buf[64];
354     DWORD ret;
355     DWORD size, type;
356     int value;
357
358     RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
359     size = sizeof(buf);
360     ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
361     RegCloseKey( hkey );
362     if( ret != ERROR_SUCCESS) return -1;
363     value = atoi( buf);
364     if( value < 0)
365         value = ( -value * dpi + 720) / 1440;
366     return value;
367 }
368
369 typedef struct
370 {
371     INT16  lfHeight;
372     INT16  lfWidth;
373     INT16  lfEscapement;
374     INT16  lfOrientation;
375     INT16  lfWeight;
376     BYTE   lfItalic;
377     BYTE   lfUnderline;
378     BYTE   lfStrikeOut;
379     BYTE   lfCharSet;
380     BYTE   lfOutPrecision;
381     BYTE   lfClipPrecision;
382     BYTE   lfQuality;
383     BYTE   lfPitchAndFamily;
384     CHAR   lfFaceName[LF_FACESIZE];
385 } LOGFONT16, *LPLOGFONT16;
386
387 /* get logfont from the registry */
388 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
389 {
390     HKEY hkey;
391     LOGFONTW lfw;
392     DWORD ret, size, type;
393
394     RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey ); 
395     size = sizeof( lfw);
396     ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
397     RegCloseKey( hkey );
398     ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
399     if( ret != ERROR_SUCCESS) 
400         return FALSE;
401     if( size <= sizeof( LOGFONT16)) {
402         LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
403         plf->lfHeight = plf16->lfHeight;
404         plf->lfWidth = plf16->lfWidth;
405         plf->lfEscapement = plf16->lfEscapement;
406         plf->lfOrientation = plf16->lfOrientation;
407         plf->lfWeight = plf16->lfWeight;
408         plf->lfItalic = plf16->lfItalic;
409         plf->lfUnderline = plf16->lfUnderline;
410         plf->lfStrikeOut = plf16->lfStrikeOut;
411         plf->lfCharSet = plf16->lfCharSet;
412         plf->lfOutPrecision = plf16->lfOutPrecision;
413         plf->lfClipPrecision = plf16->lfClipPrecision;
414         plf->lfQuality = plf16->lfQuality;
415         plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
416         memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
417     } else if( size <= sizeof( LOGFONTA)) {
418         plf = (LOGFONTA*) &lfw;
419     } else {
420         plf->lfHeight = lfw.lfHeight;
421         plf->lfWidth = lfw.lfWidth;
422         plf->lfEscapement = lfw.lfEscapement;
423         plf->lfOrientation = lfw.lfOrientation;
424         plf->lfWeight = lfw.lfWeight;
425         plf->lfItalic = lfw.lfItalic;
426         plf->lfUnderline = lfw.lfUnderline;
427         plf->lfStrikeOut = lfw.lfStrikeOut;
428         plf->lfCharSet = lfw.lfCharSet;
429         plf->lfOutPrecision = lfw.lfOutPrecision;
430         plf->lfClipPrecision = lfw.lfClipPrecision;
431         plf->lfQuality = lfw.lfQuality;
432         plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
433         WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
434             LF_FACESIZE, NULL, NULL);
435
436     }
437     return TRUE;
438 }
439
440 static void test_SPI_SETBEEP( void )                   /*      2 */
441 {
442     BOOL rc;
443     BOOL old_b;
444     BOOL b;
445     BOOL curr_val;
446
447     trace("testing SPI_{GET,SET}BEEP\n");
448     SetLastError(0xdeadbeef);
449     rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
450     if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
451         return;
452
453     curr_val = TRUE;
454     rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
455     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
456     test_change_message( SPI_SETBEEP, 0 );
457     test_reg_key( SPI_SETBEEP_REGKEY,
458                   SPI_SETBEEP_VALNAME,
459                   curr_val ? "Yes" : "No" );
460     rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
461     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
462     eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
463     rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
464     if (rc!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED)
465     {
466         ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
467         eq( b, curr_val, "SystemParametersInfoW", "%d" );
468     }
469
470     /* is a message sent for the second change? */
471     rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
472     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
473     test_change_message( SPI_SETBEEP, 0 );
474
475     curr_val = FALSE;
476     rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
477     if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
478         rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
479     ok(rc!=0,"SystemParametersInfo: rc=%d err=%d\n",rc,GetLastError());
480     test_change_message( SPI_SETBEEP, 0 );
481     test_reg_key( SPI_SETBEEP_REGKEY,
482                   SPI_SETBEEP_VALNAME,
483                   curr_val ? "Yes" : "No" );
484     rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
485     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
486     eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
487     rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
488     if (rc!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED)
489     {
490         ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
491         eq( b, curr_val, "SystemParametersInfoW", "%d" );
492     }
493     ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
494
495     rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
496     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
497 }
498
499 static const char *setmouse_valuenames[3] = {
500     SPI_SETMOUSE_VALNAME1,
501     SPI_SETMOUSE_VALNAME2,
502     SPI_SETMOUSE_VALNAME3
503 };
504
505 /*
506  * Runs check for one setting of spi_setmouse.
507  */
508 static void run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change,
509                                    int nchange )
510 {
511     BOOL rc;
512     INT mi[3];
513     static int aw_turn = 0;
514     static BOOL w_implemented = 1;
515
516     char buf[20];
517     int i;
518
519     aw_turn++;
520     rc=0;
521     if ((aw_turn % 2!=0) && (w_implemented))
522     {
523         /* call unicode on odd (non even) calls */ 
524         SetLastError(0xdeadbeef);
525         rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
526         if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
527         {
528             w_implemented = 0;
529             trace("SystemParametersInfoW not supported on this platform\n");
530         }
531     }
532
533     if ((aw_turn % 2==0) || (!w_implemented))
534     {
535         /* call ascii version on even calls or if unicode is not available */
536         rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
537     }
538
539     ok(rc!=0,"SystemParametersInfo: rc=%d err=%d\n",rc,GetLastError());
540     test_change_message( SPI_SETMOUSE, 0 );
541     for (i = 0; i < 3; i++)
542     {
543         sprintf( buf, "%d", curr_val[i] );
544         test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
545     }
546
547     rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
548     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
549     for (i = 0; i < 3; i++)
550     {
551         ok(mi[i] == curr_val[i],
552            "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
553     }
554
555     if (w_implemented)
556     { 
557         rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
558         ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
559         for (i = 0; i < 3; i++)
560         {
561             ok(mi[i] == curr_val[i],
562                "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
563         }
564     }
565
566     if (0)
567     {
568     /* FIXME: this always fails for me  - AJ */
569     for (i = 0; i < nchange; i++)
570     {
571         POINT mv;
572         mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
573         mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
574         GetCursorPos( &mv );
575         ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
576         ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
577     }
578     }
579 }
580
581 static void test_SPI_SETMOUSE( void )                  /*      4 */
582 {
583     BOOL rc;
584     INT old_mi[3];
585
586     /* win nt default values - 6, 10, 1 */
587     INT curr_val[3] = {6, 10, 1};
588
589     /* requested and projected mouse movements */
590     POINT req_change[] =   { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
591     POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
592     POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
593     POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
594     POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
595     POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
596     POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
597     POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
598     POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
599
600     int nchange = sizeof( req_change ) / sizeof( POINT );
601
602     trace("testing SPI_{GET,SET}MOUSE\n");
603     SetLastError(0xdeadbeef);
604     rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
605     if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
606         return;
607
608     run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange );
609
610     /* acceleration change */
611     curr_val[2] = 2;
612     run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
613
614     /* acceleration change */
615     curr_val[2] = 3;
616     run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
617
618     /* acceleration change */
619     curr_val[2] = 0;
620     run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
621
622     /* threshold change */
623     curr_val[2] = 1;
624     curr_val[0] = 7;
625     run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
626
627     /* threshold change */
628     curr_val[2] = 2;
629     curr_val[0] = 6;
630     curr_val[1] = 6;
631     run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
632
633     /* threshold change */
634     curr_val[1] = 7;
635     run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
636
637     /* threshold change */
638     curr_val[1] = 5;
639     run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
640
641     rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
642     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
643 }
644
645 static void test_setborder(UINT curr_val, int usesetborder, int dpi)
646 {
647     BOOL rc;
648     UINT border, regval;
649     INT frame;
650     NONCLIENTMETRICSA ncm;
651
652     ncm.cbSize = sizeof( ncm);
653     rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
654     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
655     if( usesetborder) {
656             rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
657         ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
658         test_change_message( SPI_SETBORDER, 1 );
659     } else { /* set non client metrics */
660         ncm.iBorderWidth = curr_val;
661         rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
662                 SPIF_SENDCHANGE);
663         ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
664         test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
665     }
666     if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
667         regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
668         if( regval != curr_val)
669             regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
670         ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
671     }
672     /* minimum border width is 1 */
673     if (curr_val == 0) curr_val = 1;
674     /* should be the same as the non client metrics */
675     rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
676     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
677     eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
678     /* and from SPI_GETBORDER */ 
679     rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
680     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
681     eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
682     /* test some SystemMetrics */
683     frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
684     eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
685     eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
686     eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
687     eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
688 }
689
690 static void test_SPI_SETBORDER( void )                 /*      6 */
691 {
692     BOOL rc;
693     UINT old_border;
694     NONCLIENTMETRICSA ncmsave;
695     INT CaptionWidth;
696
697     ncmsave.cbSize = sizeof( ncmsave);
698     rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
699     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
700     /* CaptionWidth from the registry may have different value of iCaptionWidth
701      * from the non client metrics (observed on WinXP).
702      * Fix this so we can safely restore settings with the nonclientmetrics */
703     CaptionWidth = metricfromreg(
704             "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
705     ncmsave.iCaptionWidth = CaptionWidth;
706
707     /* These tests hang when XFree86 4.0 for Windows is running (tested on
708      *  WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
709      * running.
710      */
711     if (FindWindowA( NULL, "Cygwin/XFree86" ))
712         return;
713
714     trace("testing SPI_{GET,SET}BORDER\n");
715
716     SetLastError(0xdeadbeef);
717     rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 );
718     if (!test_error_msg(rc,"SPI_{GET,SET}BORDER"))
719         return;
720     /* This will restore sane values if the test hang previous run. */
721     if ( old_border == 7 || old_border == 20 )
722         old_border = 1;
723
724     /* The SPI_SETBORDER seems to be buggy on Win9x/ME (looks like you need to
725      * do it twice to make the intended change). So skip parts of the tests on
726      * those platforms */
727     if( !iswin9x) {
728         test_setborder(1,  1, dpi);
729         test_setborder(0,  1, dpi);
730         test_setborder(2,  1, dpi);
731     }
732     test_setborder(1, 0, dpi);
733     test_setborder(0, 0, dpi);
734     test_setborder(3, 0, dpi);
735
736     rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave,
737             SPIF_UPDATEINIFILE| SPIF_SENDCHANGE);
738     test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
739     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",
740         rc,GetLastError());
741 }
742
743 static void test_SPI_SETKEYBOARDSPEED( void )          /*     10 */
744 {
745     BOOL rc;
746     UINT old_speed;
747     const UINT vals[]={0,20,31};
748     unsigned int i;
749
750     trace("testing SPI_{GET,SET}KEYBOARDSPEED\n");
751     SetLastError(0xdeadbeef);
752     rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &old_speed, 0 );
753     if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDSPEED"))
754         return;
755
756     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
757     {
758         UINT v;
759         char buf[10];
760
761         rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, vals[i], 0,
762                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
763         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
764         test_change_message( SPI_SETKEYBOARDSPEED, 0 );
765         sprintf( buf, "%d", vals[i] );
766         test_reg_key( SPI_SETKEYBOARDSPEED_REGKEY, SPI_SETKEYBOARDSPEED_VALNAME, buf );
767
768         rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &v, 0 );
769         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
770         eq( v, vals[i], "SPI_{GET,SET}KEYBOARDSPEED", "%d" );
771     }
772
773     rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, old_speed, 0, SPIF_UPDATEINIFILE );
774     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
775 }
776
777 /* test_SPI_ICONHORIZONTALSPACING helper */
778 static void dotest_spi_iconhorizontalspacing( INT curr_val)
779 {
780     BOOL rc;
781     INT spacing, regval;
782     ICONMETRICSA im;
783
784     rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0,
785                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
786     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
787     test_change_message( SPI_ICONHORIZONTALSPACING, 0 );
788     if( curr_val < 32) curr_val = 32;
789     /* The registry keys depend on the Windows version and the values too
790      * let's test (works on win95,ME,NT4,2k,XP)
791      */
792     regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY2, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
793     if( regval != curr_val)
794         regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
795     ok( curr_val == regval,
796         "wrong value in registry %d, expected %d\n", regval, curr_val);
797     /* compare with what SPI_ICONHORIZONTALSPACING returns */
798     rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
799     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
800     eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d");
801     /* and with a system metrics */
802     eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" );
803     /* and with what SPI_GETICONMETRICS returns */
804     im.cbSize = sizeof(ICONMETRICSA);
805     rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
806     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
807     eq( im.iHorzSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
808 }
809
810 static void test_SPI_ICONHORIZONTALSPACING( void )     /*     13 */
811 {
812     BOOL rc;
813     INT old_spacing;
814
815     trace("testing SPI_ICONHORIZONTALSPACING\n");
816     SetLastError(0xdeadbeef);
817     /* default value: 75 */
818     rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &old_spacing, 0 );
819     if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING"))
820         return;
821     /* do not increase the value as it would upset the user's icon layout */
822     dotest_spi_iconhorizontalspacing( old_spacing - 1);
823     dotest_spi_iconhorizontalspacing( 10); /* minimum is 32 */
824     /* restore */
825     rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, old_spacing, 0, SPIF_UPDATEINIFILE );
826     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
827 }
828
829 static void test_SPI_SETSCREENSAVETIMEOUT( void )      /*     14 */
830 {
831     BOOL rc;
832     UINT old_timeout;
833     const UINT vals[]={0,32767};
834     unsigned int i;
835
836     trace("testing SPI_{GET,SET}SCREENSAVETIMEOUT\n");
837     SetLastError(0xdeadbeef);
838     rc=SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &old_timeout, 0 );
839     if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVETIMEOUT"))
840         return;
841
842     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
843     {
844         UINT v;
845         char buf[10];
846
847         rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, vals[i], 0,
848                                SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
849         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
850         test_change_message( SPI_SETSCREENSAVETIMEOUT, 0 );
851         sprintf( buf, "%d", vals[i] );
852         test_reg_key( SPI_SETSCREENSAVETIMEOUT_REGKEY,
853                       SPI_SETSCREENSAVETIMEOUT_VALNAME, buf );
854
855         SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &v, 0 );
856         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
857         eq( v, vals[i], "SPI_{GET,SET}SCREENSAVETIMEOUT", "%d" );
858     }
859
860     rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, old_timeout, 0,
861                               SPIF_UPDATEINIFILE );
862     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
863 }
864
865 static void test_SPI_SETSCREENSAVEACTIVE( void )       /*     17 */
866 {
867     BOOL rc;
868     BOOL old_b;
869     const UINT vals[]={TRUE,FALSE};
870     unsigned int i;
871
872     trace("testing SPI_{GET,SET}SCREENSAVEACTIVE\n");
873     SetLastError(0xdeadbeef);
874     rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &old_b, 0 );
875     if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVEACTIVE"))
876         return;
877
878     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
879     {
880         UINT v;
881
882         rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, vals[i], 0,
883                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
884         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
885         test_change_message( SPI_SETSCREENSAVEACTIVE, 0 );
886         test_reg_key( SPI_SETSCREENSAVEACTIVE_REGKEY,
887                       SPI_SETSCREENSAVEACTIVE_VALNAME,
888                       vals[i] ? "1" : "0" );
889
890         rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &v, 0 );
891         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
892         eq( v, vals[i], "SPI_{GET,SET}SCREENSAVEACTIVE", "%d" );
893     }
894
895     rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
896     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
897 }
898
899 static void test_SPI_SETGRIDGRANULARITY( void )        /*     19 */
900 {
901     /* ??? */;
902 }
903
904 static void test_SPI_SETKEYBOARDDELAY( void )          /*     23 */
905 {
906     BOOL rc;
907     UINT old_delay;
908     const UINT vals[]={0,3};
909     unsigned int i;
910
911     trace("testing SPI_{GET,SET}KEYBOARDDELAY\n");
912     SetLastError(0xdeadbeef);
913     rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &old_delay, 0 );
914     if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDDELAY"))
915         return;
916
917     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
918     {
919         UINT delay;
920         char buf[10];
921
922         rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, vals[i], 0,
923                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
924         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
925         test_change_message( SPI_SETKEYBOARDDELAY, 0 );
926         sprintf( buf, "%d", vals[i] );
927         test_reg_key( SPI_SETKEYBOARDDELAY_REGKEY,
928                       SPI_SETKEYBOARDDELAY_VALNAME, buf );
929
930         rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &delay, 0 );
931         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
932         eq( delay, vals[i], "SPI_{GET,SET}KEYBOARDDELAY", "%d" );
933     }
934
935     rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, old_delay, 0, SPIF_UPDATEINIFILE );
936     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
937 }
938
939
940 /* test_SPI_ICONVERTICALSPACING helper */
941 static void dotest_spi_iconverticalspacing( INT curr_val)
942 {
943     BOOL rc;
944     INT spacing, regval;
945     ICONMETRICSA im;
946
947     rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0,
948                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
949     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
950     test_change_message( SPI_ICONVERTICALSPACING, 0 );
951     if( curr_val < 32) curr_val = 32;
952     /* The registry keys depend on the Windows version and the values too
953      * let's test (works on win95,ME,NT4,2k,XP)
954      */
955     regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY2, SPI_ICONVERTICALSPACING_VALNAME, dpi);
956     if( regval != curr_val)
957         regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
958     ok( curr_val == regval,
959         "wrong value in registry %d, expected %d\n", regval, curr_val);
960     /* compare with what SPI_ICONVERTICALSPACING returns */
961     rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
962     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
963     eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" );
964     /* and with a system metrics */
965     eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" );
966     /* and with what SPI_GETICONMETRICS returns */
967     im.cbSize = sizeof(ICONMETRICSA);
968     rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
969     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
970     eq( im.iVertSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
971 }
972
973 static void test_SPI_ICONVERTICALSPACING( void )       /*     24 */
974 {
975     BOOL rc;
976     INT old_spacing;
977
978     trace("testing SPI_ICONVERTICALSPACING\n");
979     SetLastError(0xdeadbeef);
980     /* default value: 75 */
981     rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &old_spacing, 0 );
982     if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING"))
983         return;
984     /* do not increase the value as it would upset the user's icon layout */
985     dotest_spi_iconverticalspacing( old_spacing - 1);
986     /* same tests with a value less than the minimum 32 */
987     dotest_spi_iconverticalspacing( 10);
988     /* restore */
989     rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, old_spacing, 0,
990                               SPIF_UPDATEINIFILE );
991     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",
992         rc,GetLastError());
993 }
994
995 static void test_SPI_SETICONTITLEWRAP( void )          /*     26 */
996 {
997     BOOL rc;
998     BOOL old_b;
999     const UINT vals[]={TRUE,FALSE};
1000     unsigned int i;
1001     ICONMETRICSA im;
1002
1003     /* These tests hang when XFree86 4.0 for Windows is running (tested on
1004      * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
1005      * running.
1006      */
1007     if (FindWindowA( NULL, "Cygwin/XFree86" ))
1008         return;
1009
1010     trace("testing SPI_{GET,SET}ICONTITLEWRAP\n");
1011     SetLastError(0xdeadbeef);
1012     rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &old_b, 0 );
1013     if (!test_error_msg(rc,"SPI_{GET,SET}ICONTITLEWRAP"))
1014         return;
1015
1016     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1017     {
1018         UINT v;
1019         UINT regval;
1020
1021         rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, vals[i], 0,
1022                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1023         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1024         test_change_message( SPI_SETICONTITLEWRAP, 1 );
1025         regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2,
1026                 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1027         if( regval != vals[i])
1028             regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1,
1029                     SPI_SETICONTITLEWRAP_VALNAME, dpi);
1030         ok( regval == vals[i],
1031                 "wrong value in registry %d, expected %d\n", regval, vals[i] );
1032
1033         rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &v, 0 );
1034         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1035         eq( v, vals[i], "SPI_{GET,SET}ICONTITLEWRAP", "%d" );
1036         /* and test with what SPI_GETICONMETRICS returns */
1037         im.cbSize = sizeof(ICONMETRICSA);
1038         rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1039         ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1040         eq( im.iTitleWrap, (BOOL)vals[i], "SPI_GETICONMETRICS", "%d" );
1041     }
1042
1043     rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, old_b, 0, SPIF_UPDATEINIFILE );
1044     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1045 }
1046
1047 static void test_SPI_SETMENUDROPALIGNMENT( void )      /*     28 */
1048 {
1049     BOOL rc;
1050     BOOL old_b;
1051     const UINT vals[]={TRUE,FALSE};
1052     unsigned int i;
1053
1054     trace("testing SPI_{GET,SET}MENUDROPALIGNMENT\n");
1055     SetLastError(0xdeadbeef);
1056     rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &old_b, 0 );
1057     if (!test_error_msg(rc,"SPI_{GET,SET}MENUDROPALIGNMENT"))
1058         return;
1059
1060     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1061     {
1062         UINT v;
1063
1064         rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, vals[i], 0,
1065                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1066         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1067         test_change_message( SPI_SETMENUDROPALIGNMENT, 0 );
1068         test_reg_key_ex( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1069                          SPI_SETMENUDROPALIGNMENT_REGKEY2,
1070                          SPI_SETMENUDROPALIGNMENT_VALNAME,
1071                          vals[i] ? "1" : "0" );
1072
1073         rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &v, 0 );
1074         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1075         eq( v, vals[i], "SPI_{GET,SET}MENUDROPALIGNMENT", "%d" );
1076         eq( GetSystemMetrics( SM_MENUDROPALIGNMENT ), (int)vals[i],
1077             "SM_MENUDROPALIGNMENT", "%d" );
1078     }
1079
1080     rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, old_b, 0,
1081                               SPIF_UPDATEINIFILE );
1082     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1083 }
1084
1085 static void test_SPI_SETDOUBLECLKWIDTH( void )         /*     29 */
1086 {
1087     BOOL rc;
1088     INT old_width;
1089     const UINT vals[]={0,10000};
1090     unsigned int i;
1091
1092     trace("testing SPI_{GET,SET}DOUBLECLKWIDTH\n");
1093     old_width = GetSystemMetrics( SM_CXDOUBLECLK );
1094
1095     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1096     {
1097         char buf[10];
1098
1099         SetLastError(0xdeadbeef);
1100         rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, vals[i], 0,
1101                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1102         if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKWIDTH"))
1103             return;
1104
1105         test_change_message( SPI_SETDOUBLECLKWIDTH, 0 );
1106         sprintf( buf, "%d", vals[i] );
1107         test_reg_key_ex( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1108                          SPI_SETDOUBLECLKWIDTH_REGKEY2,
1109                          SPI_SETDOUBLECLKWIDTH_VALNAME, buf );
1110         eq( GetSystemMetrics( SM_CXDOUBLECLK ), (int)vals[i],
1111             "SM_CXDOUBLECLK", "%d" );
1112     }
1113
1114     rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, old_width, 0,
1115                               SPIF_UPDATEINIFILE );
1116     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1117 }
1118
1119 static void test_SPI_SETDOUBLECLKHEIGHT( void )        /*     30 */
1120 {
1121     BOOL rc;
1122     INT old_height;
1123     const UINT vals[]={0,10000};
1124     unsigned int i;
1125
1126     trace("testing SPI_{GET,SET}DOUBLECLKHEIGHT\n");
1127     old_height = GetSystemMetrics( SM_CYDOUBLECLK );
1128
1129     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1130     {
1131         char buf[10];
1132
1133         SetLastError(0xdeadbeef);
1134         rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, vals[i], 0,
1135                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1136         if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKHEIGHT"))
1137             return;
1138
1139         test_change_message( SPI_SETDOUBLECLKHEIGHT, 0 );
1140         sprintf( buf, "%d", vals[i] );
1141         test_reg_key_ex( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1142                          SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1143                          SPI_SETDOUBLECLKHEIGHT_VALNAME, buf );
1144         eq( GetSystemMetrics( SM_CYDOUBLECLK ), (int)vals[i],
1145             "SM_CYDOUBLECLK", "%d" );
1146     }
1147
1148     rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, old_height, 0,
1149                               SPIF_UPDATEINIFILE );
1150     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1151 }
1152
1153 static void test_SPI_SETDOUBLECLICKTIME( void )        /*     32 */
1154 {
1155     BOOL rc;
1156     UINT curr_val;
1157     UINT saved_val;
1158     UINT old_time;
1159     char buf[10];
1160
1161     trace("testing SPI_{GET,SET}DOUBLECLICKTIME\n");
1162     old_time = GetDoubleClickTime();
1163
1164     curr_val = 0;
1165     SetLastError(0xdeadbeef);
1166     rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1167                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1168     if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLICKTIME"))
1169         return;
1170
1171     test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1172     sprintf( buf, "%d", curr_val );
1173     test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1174                   SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1175     curr_val = 500; /* used value for 0 */
1176     eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1177
1178     curr_val = 1000;
1179     rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1180                              SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1181     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1182     test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1183     sprintf( buf, "%d", curr_val );
1184     test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1185                   SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1186     eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1187
1188     saved_val = curr_val;
1189
1190     curr_val = 0;
1191     SetDoubleClickTime( curr_val );
1192     sprintf( buf, "%d", saved_val );
1193     test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1194                   SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1195     curr_val = 500; /* used value for 0 */
1196     eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1197
1198     curr_val = 1000;
1199     SetDoubleClickTime( curr_val );
1200     sprintf( buf, "%d", saved_val );
1201     test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1202                   SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1203     eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1204
1205     rc=SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, old_time, 0, SPIF_UPDATEINIFILE);
1206     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1207 }
1208
1209 static void test_SPI_SETMOUSEBUTTONSWAP( void )        /*     33 */
1210 {
1211     BOOL rc;
1212     BOOL old_b;
1213     const UINT vals[]={TRUE,FALSE};
1214     unsigned int i;
1215
1216     trace("testing SPI_{GET,SET}MOUSEBUTTONSWAP\n");
1217     old_b = GetSystemMetrics( SM_SWAPBUTTON );
1218
1219     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1220     {
1221         SetLastError(0xdeadbeef);
1222         rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[i], 0,
1223                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1224         if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEBUTTONSWAP"))
1225             break;
1226             
1227         test_change_message( SPI_SETMOUSEBUTTONSWAP, 0 );
1228         test_reg_key( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1229                       SPI_SETMOUSEBUTTONSWAP_VALNAME,
1230                       vals[i] ? "1" : "0" );
1231         eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i],
1232             "SM_SWAPBUTTON", "%d" );
1233         rc=SwapMouseButton((BOOL)vals[i^1]);
1234         eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i^1],
1235             "SwapMouseButton", "%d" );
1236         ok( rc==(BOOL)vals[i], "SwapMouseButton does not return previous state (really %d)\n", rc );
1237     }
1238
1239     rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, old_b, 0,
1240                               SPIF_UPDATEINIFILE );
1241     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1242 }
1243
1244 static void test_SPI_SETFASTTASKSWITCH( void )         /*     36 */
1245 {
1246     BOOL rc;
1247     BOOL v;
1248
1249     trace("testing SPI_GETFASTTASKSWITCH\n");
1250     SetLastError(0xdeadbeef);
1251     rc=SystemParametersInfoA( SPI_GETFASTTASKSWITCH, 0, &v, 0 );
1252     if (!test_error_msg(rc,"SPI_{GET,SET}FASTTASKSWITCH"))
1253         return;
1254
1255     /* there is not a single Windows platform on which SPI_GETFASTTASKSWITCH
1256      * works. That sure simplifies testing!
1257      */
1258 }
1259
1260 static void test_SPI_SETDRAGFULLWINDOWS( void )        /*     37 */
1261 {
1262     BOOL rc;
1263     BOOL old_b;
1264     const UINT vals[]={TRUE,FALSE};
1265     unsigned int i;
1266
1267     trace("testing SPI_{GET,SET}DRAGFULLWINDOWS\n");
1268     SetLastError(0xdeadbeef);
1269     rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &old_b, 0 );
1270
1271     /* SPI_{GET,SET}DRAGFULLWINDOWS is not implemented on Win95 */
1272     if (!test_error_msg(rc,"SPI_{GET,SET}DRAGFULLWINDOWS"))
1273         return;
1274
1275     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1276     {
1277         UINT v;
1278
1279         rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, vals[i], 0,
1280                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1281         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1282         test_change_message( SPI_SETDRAGFULLWINDOWS, 0 );
1283         test_reg_key( SPI_SETDRAGFULLWINDOWS_REGKEY,
1284                       SPI_SETDRAGFULLWINDOWS_VALNAME,
1285                       vals[i] ? "1" : "0" );
1286
1287         rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &v, 0 );
1288         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1289         eq( v, vals[i], "SPI_{GET,SET}DRAGFULLWINDOWS", "%d" );
1290     }
1291
1292     rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, old_b, 0, SPIF_UPDATEINIFILE );
1293     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1294 }
1295
1296 #define test_reg_metric( KEY, VAL, val) \
1297 {   INT regval;\
1298     regval = metricfromreg( KEY, VAL, dpi);\
1299     ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1300 }
1301  
1302 #define test_reg_metric2( KEY1, KEY2, VAL, val) \
1303 {   INT regval;\
1304     regval = metricfromreg( KEY1, VAL, dpi);\
1305     if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\
1306     ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1307 }
1308
1309 #define test_reg_font( KEY, VAL, LF) \
1310 {   LOGFONTA lfreg;\
1311     lffromreg( KEY, VAL, &lfreg);\
1312     ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == lfreg.lfHeight :\
1313                 MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\
1314         (LF).lfWidth == lfreg.lfWidth &&\
1315         (LF).lfWeight == lfreg.lfWeight &&\
1316         !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\
1317         , "wrong value \"%s\" in registry %d, %d\n", VAL, (LF).lfHeight, lfreg.lfHeight);\
1318 }
1319
1320 #define TEST_NONCLIENTMETRICS_REG( ncm) \
1321 test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);\
1322 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\
1323 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\
1324 /*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\
1325 test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\
1326 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\
1327 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\
1328 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\
1329 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\
1330 test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\
1331 test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\
1332 test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\
1333 test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\
1334 test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont);
1335
1336 /* get text metric height value for the specified logfont */
1337 static int get_tmheight( LOGFONTA *plf, int flag)
1338 {
1339     TEXTMETRICA tm;
1340     HFONT hfont = CreateFontIndirectA( plf);
1341     hfont = SelectObject( hdc, hfont);
1342     GetTextMetricsA( hdc, &tm);
1343     hfont = SelectObject( hdc, hfont);
1344     return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1345 }
1346
1347 static void test_GetSystemMetrics( void);
1348
1349 static void test_SPI_SETNONCLIENTMETRICS( void )               /*     44 */
1350 {
1351     BOOL rc;
1352     INT expect;
1353     NONCLIENTMETRICSA Ncmorig;
1354     NONCLIENTMETRICSA Ncmnew;
1355     NONCLIENTMETRICSA Ncmcur;
1356     NONCLIENTMETRICSA Ncmstart;
1357
1358     Ncmorig.cbSize = sizeof(NONCLIENTMETRICSA);
1359     Ncmnew.cbSize = sizeof(NONCLIENTMETRICSA);
1360     Ncmcur.cbSize = sizeof(NONCLIENTMETRICSA);
1361     Ncmstart.cbSize = sizeof(NONCLIENTMETRICSA);
1362
1363     trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n");
1364     SetLastError(0xdeadbeef);
1365     rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmorig, FALSE );
1366     if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS"))
1367         return;
1368     Ncmstart = Ncmorig;
1369     /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if 
1370        the caption font height is higher than the CaptionHeight field,
1371        the latter is adjusted accordingly. To be able to restore these setting
1372        accurately be restore the raw values. */
1373     Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, dpi);
1374     Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi);
1375     Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi);
1376     Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi);
1377     /* test registry entries */
1378     TEST_NONCLIENTMETRICS_REG( Ncmorig)
1379     /* make small changes */
1380     Ncmnew = Ncmstart;
1381     Ncmnew.iBorderWidth += 1;
1382     Ncmnew.iScrollWidth += 1;
1383     Ncmnew.iScrollHeight -= 1;
1384     Ncmnew.iCaptionWidth -= 2;
1385     Ncmnew.iCaptionHeight += 2;
1386     Ncmnew.lfCaptionFont.lfHeight +=1;
1387     Ncmnew.lfCaptionFont.lfWidth +=2;
1388     Ncmnew.lfCaptionFont.lfWeight +=1;
1389     Ncmnew.iSmCaptionWidth += 1;
1390     Ncmnew.iSmCaptionHeight += 2;
1391     Ncmnew.lfSmCaptionFont.lfHeight +=3;
1392     Ncmnew.lfSmCaptionFont.lfWidth -=1;
1393     Ncmnew.lfSmCaptionFont.lfWeight +=3;
1394     Ncmnew.iMenuWidth += 1;
1395     Ncmnew.iMenuHeight += 2;
1396     Ncmnew.lfMenuFont.lfHeight +=1;
1397     Ncmnew.lfMenuFont.lfWidth +=1;
1398     Ncmnew.lfMenuFont.lfWeight +=2;
1399     Ncmnew.lfStatusFont.lfHeight -=1;
1400     Ncmnew.lfStatusFont.lfWidth -=1;
1401     Ncmnew.lfStatusFont.lfWeight +=3;
1402     Ncmnew.lfMessageFont.lfHeight -=2;
1403     Ncmnew.lfMessageFont.lfWidth -=1;
1404     Ncmnew.lfMessageFont.lfWeight +=4;
1405
1406     rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1407             SPIF_SENDCHANGE);
1408     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1409     test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1410     /* get them back */
1411     rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmcur, FALSE );
1412     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1413     /* test registry entries */
1414     TEST_NONCLIENTMETRICS_REG( Ncmcur)
1415     /* test the systemm metrics with these settings */
1416     test_GetSystemMetrics();
1417     /* now for something invalid: increase the {menu|caption|smcaption} fonts
1418        by a large amount will increase the {menu|caption|smcaption} height*/
1419     Ncmnew = Ncmstart;
1420     Ncmnew.lfMenuFont.lfHeight -= 8;
1421     Ncmnew.lfCaptionFont.lfHeight =-4;
1422     Ncmnew.lfSmCaptionFont.lfHeight -=10;
1423     /* also show that a few values are lo limited */
1424     Ncmnew.iCaptionWidth = 0;
1425     Ncmnew.iCaptionHeight = 0;
1426     Ncmnew.iScrollHeight = 0;
1427     Ncmnew.iScrollWidth  = 0;
1428
1429     rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1430             SPIF_SENDCHANGE);
1431     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1432     test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1433     /* raw values are in registry */
1434     TEST_NONCLIENTMETRICS_REG( Ncmnew)
1435     /* get them back */
1436     rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &Ncmcur, FALSE );
1437     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1438     /* cooked values are returned */
1439     expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1));
1440     ok( Ncmcur.iMenuHeight == expect,
1441         "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect);
1442     expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0));
1443     ok( Ncmcur.iCaptionHeight == expect,
1444         "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect);
1445     expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0));
1446     ok( Ncmcur.iSmCaptionHeight == expect,
1447         "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect);
1448
1449     ok( Ncmcur.iCaptionWidth == 8 ||
1450         Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme,  the value never changes */
1451         "CaptionWidth: %d expected 8\n", Ncmcur.iCaptionWidth);
1452     ok( Ncmcur.iScrollWidth == 8,
1453         "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth);
1454     ok( Ncmcur.iScrollHeight == 8,
1455         "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight);
1456     /* test the systemm metrics with these settings */
1457     test_GetSystemMetrics();
1458     /* restore */
1459     rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS),
1460         &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1461     test_change_message( SPI_SETNONCLIENTMETRICS, 0 );
1462     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1463 }
1464
1465 static void test_SPI_SETMINIMIZEDMETRICS( void )               /*     44 */
1466 {
1467     BOOL rc;
1468     INT regval;
1469     MINIMIZEDMETRICS lpMm_orig;
1470     MINIMIZEDMETRICS lpMm_new;
1471     MINIMIZEDMETRICS lpMm_cur;
1472
1473     lpMm_orig.cbSize = sizeof(MINIMIZEDMETRICS);
1474     lpMm_new.cbSize = sizeof(MINIMIZEDMETRICS);
1475     lpMm_cur.cbSize = sizeof(MINIMIZEDMETRICS);
1476
1477     trace("testing SPI_{GET,SET}MINIMIZEDMETRICS\n");
1478     SetLastError(0xdeadbeef);
1479     rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_orig, FALSE );
1480     if (!test_error_msg(rc,"SPI_{GET,SET}MINIMIZEDMETRICS"))
1481         return;
1482     /* Test registry. Note that it is perfectly valid for some fields to
1483      * not be set.
1484      */
1485     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1486     ok( regval == -1 || regval == lpMm_orig.iWidth, "wrong value in registry %d, expected %d\n",
1487         regval, lpMm_orig.iWidth);
1488     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1489     ok( regval == -1 || regval == lpMm_orig.iHorzGap, "wrong value in registry %d, expected %d\n",
1490         regval, lpMm_orig.iHorzGap);
1491     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1492     ok( regval == -1 || regval == lpMm_orig.iVertGap, "wrong value in registry %d, expected %d\n",
1493         regval, lpMm_orig.iVertGap);
1494     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1495     ok( regval == -1 || regval == lpMm_orig.iArrange, "wrong value in registry %d, expected %d\n",
1496         regval, lpMm_orig.iArrange);
1497     /* set some new values */
1498     lpMm_cur.iWidth = 180;
1499     lpMm_cur.iHorzGap = 1;
1500     lpMm_cur.iVertGap = 1;
1501     lpMm_cur.iArrange = 5;
1502     rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1503         &lpMm_cur, SPIF_UPDATEINIFILE );
1504     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1505     /* read them back */
1506     rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1507     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1508     /* and compare */
1509     eq( lpMm_new.iWidth,   lpMm_cur.iWidth,   "iWidth",   "%d" );
1510     eq( lpMm_new.iHorzGap, lpMm_cur.iHorzGap, "iHorzGap", "%d" );
1511     eq( lpMm_new.iVertGap, lpMm_cur.iVertGap, "iVertGap", "%d" );
1512     eq( lpMm_new.iArrange, lpMm_cur.iArrange, "iArrange", "%d" );
1513     /* test registry */
1514     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1515     ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1516         regval, lpMm_new.iWidth);
1517     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1518     ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1519         regval, lpMm_new.iHorzGap);
1520     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1521     ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1522         regval, lpMm_new.iVertGap);
1523     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1524     ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1525         regval, lpMm_new.iArrange);
1526     /* test some system metrics */
1527     eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1528         lpMm_new.iWidth,   "iWidth",   "%d" );
1529     eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1530         lpMm_new.iHorzGap, "iHorzGap", "%d" );
1531     eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1532         lpMm_new.iVertGap, "iVertGap", "%d" );
1533     eq( GetSystemMetrics( SM_ARRANGE ),
1534         lpMm_new.iArrange, "iArrange", "%d" );
1535     /* now some really invalid settings */
1536     lpMm_cur.iWidth = -1;
1537     lpMm_cur.iHorzGap = -1;
1538     lpMm_cur.iVertGap = -1;
1539     lpMm_cur.iArrange = - 1;
1540     rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1541         &lpMm_cur, SPIF_UPDATEINIFILE );
1542     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1543     /* read back */
1544     rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1545     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1546     /* the width and H/V gaps have minimum 0, arrange is and'd with 0xf */
1547     eq( lpMm_new.iWidth,   0,   "iWidth",   "%d" );
1548     eq( lpMm_new.iHorzGap, 0, "iHorzGap", "%d" );
1549     eq( lpMm_new.iVertGap, 0, "iVertGap", "%d" );
1550     eq( lpMm_new.iArrange, 0xf & lpMm_cur.iArrange, "iArrange", "%d" );
1551     /* test registry */
1552     if (0)
1553     {
1554     /* FIXME: cannot understand the results of this (11, 11, 11, 0) */
1555     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1556     ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1557         regval, lpMm_new.iWidth);
1558     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1559     ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1560         regval, lpMm_new.iHorzGap);
1561     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1562     ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1563         regval, lpMm_new.iVertGap);
1564     regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1565     ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1566         regval, lpMm_new.iArrange);
1567     }
1568     /* test some system metrics */
1569     eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1570         lpMm_new.iWidth,   "iWidth",   "%d" );
1571     eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1572         lpMm_new.iHorzGap, "iHorzGap", "%d" );
1573     eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1574         lpMm_new.iVertGap, "iVertGap", "%d" );
1575     eq( GetSystemMetrics( SM_ARRANGE ),
1576         lpMm_new.iArrange, "iArrange", "%d" );
1577     /* restore */
1578     rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1579         &lpMm_orig, SPIF_UPDATEINIFILE );
1580     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1581     /* check that */
1582     rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1583     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1584     eq( lpMm_new.iWidth,   lpMm_orig.iWidth,   "iWidth",   "%d" );
1585     eq( lpMm_new.iHorzGap, lpMm_orig.iHorzGap, "iHorzGap", "%d" );
1586     eq( lpMm_new.iVertGap, lpMm_orig.iVertGap, "iVertGap", "%d" );
1587     eq( lpMm_new.iArrange, lpMm_orig.iArrange, "iArrange", "%d" );
1588 }
1589
1590 static void test_SPI_SETICONMETRICS( void )               /*     46 */
1591 {
1592     BOOL rc, wrap;
1593     INT spacing;
1594     ICONMETRICSA im_orig;
1595     ICONMETRICSA im_new;
1596     ICONMETRICSA im_cur;
1597     INT regval;
1598         
1599     im_orig.cbSize = sizeof(ICONMETRICSA);
1600     im_new.cbSize = sizeof(ICONMETRICSA);
1601     im_cur.cbSize = sizeof(ICONMETRICSA);
1602
1603     trace("testing SPI_{GET,SET}ICONMETRICS\n");
1604     SetLastError(0xdeadbeef);
1605     rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE );
1606     if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS"))
1607         return;
1608    /* check some registry values */ 
1609     regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1610     ok( regval==im_orig.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing);
1611     regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1612     ok( regval==im_orig.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing);
1613     regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1614     if( regval != im_orig.iTitleWrap)
1615         regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1616     ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap);
1617
1618     /* change everything without creating something invalid ( Win9x would ignore
1619      * an invalid font for instance) */
1620     im_cur = im_orig;
1621     im_cur.iHorzSpacing += 10;
1622     im_cur.iVertSpacing += 6;
1623     im_cur.iTitleWrap = !im_cur.iTitleWrap;
1624     im_cur.lfFont.lfHeight += 1;
1625     im_cur.lfFont.lfWidth += 2;
1626     im_cur.lfFont.lfEscapement = 1;
1627     im_cur.lfFont.lfWeight = im_cur.lfFont.lfWeight > 100 ? 1 : 314;
1628     im_cur.lfFont.lfItalic = !im_cur.lfFont.lfItalic;
1629     im_cur.lfFont.lfStrikeOut = !im_cur.lfFont.lfStrikeOut;
1630     im_cur.lfFont.lfUnderline = !im_cur.lfFont.lfUnderline;
1631     im_cur.lfFont.lfCharSet = im_cur.lfFont.lfCharSet ? 0 : 1;
1632     im_cur.lfFont.lfOutPrecision = im_cur.lfFont.lfOutPrecision == OUT_DEFAULT_PRECIS ?
1633                                 OUT_TT_PRECIS : OUT_DEFAULT_PRECIS;
1634     im_cur.lfFont.lfClipPrecision ^= CLIP_LH_ANGLES;
1635     im_cur.lfFont.lfPitchAndFamily = im_cur.lfFont.lfPitchAndFamily ? 0 : 1;
1636     im_cur.lfFont.lfQuality = im_cur.lfFont.lfQuality == DEFAULT_QUALITY ? 
1637                                 DRAFT_QUALITY : DEFAULT_QUALITY;
1638     if( strcmp( im_cur.lfFont.lfFaceName, "MS Serif"))
1639         strcpy( im_cur.lfFont.lfFaceName, "MS Serif");
1640     else
1641         strcpy( im_cur.lfFont.lfFaceName, "MS Sans Serif");
1642
1643     rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, SPIF_UPDATEINIFILE );
1644     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1645
1646     rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1647     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1648     /* test GET <-> SETICONMETRICS */ 
1649     eq( im_new.iHorzSpacing, im_cur.iHorzSpacing, "iHorzSpacing", "%d" );
1650     eq( im_new.iVertSpacing, im_cur.iVertSpacing, "iVertSpacing", "%d" );
1651     eq( im_new.iTitleWrap,   im_cur.iTitleWrap,   "iTitleWrap",   "%d" );
1652     eq( im_new.lfFont.lfHeight,         im_cur.lfFont.lfHeight,         "lfHeight",         "%d" );
1653     eq( im_new.lfFont.lfWidth,          im_cur.lfFont.lfWidth,          "lfWidth",          "%d" );
1654     eq( im_new.lfFont.lfEscapement,     im_cur.lfFont.lfEscapement,     "lfEscapement",     "%d" );
1655     eq( im_new.lfFont.lfWeight,         im_cur.lfFont.lfWeight,         "lfWeight",         "%d" );
1656     eq( im_new.lfFont.lfItalic,         im_cur.lfFont.lfItalic,         "lfItalic",         "%d" );
1657     eq( im_new.lfFont.lfStrikeOut,      im_cur.lfFont.lfStrikeOut,      "lfStrikeOut",      "%d" );
1658     eq( im_new.lfFont.lfUnderline,      im_cur.lfFont.lfUnderline,      "lfUnderline",      "%d" );
1659     eq( im_new.lfFont.lfCharSet,        im_cur.lfFont.lfCharSet,        "lfCharSet",        "%d" );
1660     eq( im_new.lfFont.lfOutPrecision,   im_cur.lfFont.lfOutPrecision,   "lfOutPrecision",   "%d" );
1661     eq( im_new.lfFont.lfClipPrecision,  im_cur.lfFont.lfClipPrecision,  "lfClipPrecision",  "%d" );
1662     eq( im_new.lfFont.lfPitchAndFamily, im_cur.lfFont.lfPitchAndFamily, "lfPitchAndFamily", "%d" );
1663     eq( im_new.lfFont.lfQuality,        im_cur.lfFont.lfQuality,        "lfQuality",        "%d" );
1664     ok( !strcmp( im_new.lfFont.lfFaceName, im_cur.lfFont.lfFaceName),
1665         "wrong facename \"%s\", should be \"%s\"\n", im_new.lfFont.lfFaceName,
1666         im_cur.lfFont.lfFaceName);
1667     /* test some system metrics */
1668     eq( GetSystemMetrics( SM_CXICONSPACING ),
1669         im_new.iHorzSpacing, "iHorzSpacing", "%d" );
1670     eq( GetSystemMetrics( SM_CYICONSPACING ),
1671         im_new.iVertSpacing, "iVertSpacing", "%d" );
1672    /* check some registry values */ 
1673     regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1674     ok( regval==im_cur.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iHorzSpacing);
1675     regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1676     ok( regval==im_cur.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iVertSpacing);
1677     regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1678     if( regval != im_cur.iTitleWrap)
1679         regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1680     ok( regval==im_cur.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_cur.iTitleWrap);
1681     /* test some values from other SPI_GETxxx calls */
1682     rc = SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
1683     ok( rc && spacing == im_cur.iHorzSpacing,
1684         "SystemParametersInfoA( SPI_ICONHORIZONTALSPACING...) failed or returns wrong value %d instead of %d\n",
1685         spacing, im_cur.iHorzSpacing);
1686     rc = SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1687     ok( rc && spacing == im_cur.iVertSpacing,
1688         "SystemParametersInfoA( SPI_ICONVERTICALSPACING...) failed or returns wrong value %d instead of %d\n",
1689         spacing, im_cur.iVertSpacing);
1690     rc = SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &wrap, 0 );
1691     ok( rc && wrap == im_cur.iTitleWrap,
1692         "SystemParametersInfoA( SPI_GETICONTITLEWRAP...) failed or returns wrong value %d instead of %d\n",
1693         wrap, im_cur.iTitleWrap);
1694     /* restore old values */
1695     rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig,SPIF_UPDATEINIFILE );
1696     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1697     
1698     rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1699     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1700     
1701     eq( im_new.iHorzSpacing, im_orig.iHorzSpacing, "iHorzSpacing", "%d" );
1702     eq( im_new.iVertSpacing, im_orig.iVertSpacing, "iVertSpacing", "%d" );
1703     eq( im_new.iTitleWrap,   im_orig.iTitleWrap,   "iTitleWrap",   "%d" );
1704 }
1705
1706 static void test_SPI_SETWORKAREA( void )               /*     47 */
1707 {
1708     BOOL rc;
1709     RECT old_area;
1710     RECT area;
1711     RECT curr_val;
1712
1713     trace("testing SPI_{GET,SET}WORKAREA\n");
1714     SetLastError(0xdeadbeef);
1715     rc=SystemParametersInfoA(SPI_GETWORKAREA, 0, &old_area, 0);
1716     if (!test_error_msg(rc,"SPI_{GET,SET}WORKAREA"))
1717         return;
1718
1719     /* Modify the work area only minimally as this causes the icons that
1720      * fall outside it to be moved around thus requiring the user to
1721      * reposition them manually one by one.
1722      * Changing the work area by just one pixel should make this occurrence
1723      * reasonably unlikely.
1724      */
1725     curr_val.left = old_area.left;
1726     curr_val.top = old_area.top;
1727     curr_val.right = old_area.right-1;
1728     curr_val.bottom = old_area.bottom-1;
1729     rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &curr_val,
1730                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1731     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1732     test_change_message( SPI_SETWORKAREA, 0 );
1733     rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1734     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1735     eq( area.left,   curr_val.left,   "left",   "%d" );
1736     eq( area.top,    curr_val.top,    "top",    "%d" );
1737     eq( area.right,  curr_val.right,  "right",  "%d" );
1738     eq( area.bottom, curr_val.bottom, "bottom", "%d" );
1739
1740     rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &old_area,
1741                               SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1742     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1743     test_change_message( SPI_SETWORKAREA, 0 );
1744     rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1745     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
1746     eq( area.left,   old_area.left,   "left",   "%d" );
1747     eq( area.top,    old_area.top,    "top",    "%d" );
1748     eq( area.right,  old_area.right,  "right",  "%d" );
1749     eq( area.bottom, old_area.bottom, "bottom", "%d" );
1750 }
1751
1752 static void test_SPI_SETSHOWSOUNDS( void )             /*     57 */
1753 {
1754     BOOL rc;
1755     BOOL old_b;
1756     const UINT vals[]={TRUE,FALSE};
1757     unsigned int i;
1758
1759     trace("testing SPI_{GET,SET}SHOWSOUNDS\n");
1760     SetLastError(0xdeadbeef);
1761     rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &old_b, 0 );
1762     /* SPI_{GET,SET}SHOWSOUNDS is completely broken on Win9x */
1763     if (!test_error_msg(rc,"SPI_{GET,SET}SHOWSOUNDS"))
1764         return;
1765
1766     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1767     {
1768         UINT v;
1769
1770         rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0,
1771                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1772         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1773         test_change_message( SPI_SETSHOWSOUNDS, 0 );
1774         test_reg_key( SPI_SETSHOWSOUNDS_REGKEY,
1775                       SPI_SETSHOWSOUNDS_VALNAME,
1776                       vals[i] ? "1" : "0" );
1777
1778         rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &v, 0 );
1779         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1780         eq( v, vals[i], "SPI_GETSHOWSOUNDS", "%d" );
1781         eq( GetSystemMetrics( SM_SHOWSOUNDS ), (int)vals[i],
1782             "SM_SHOWSOUNDS", "%d" );
1783     }
1784
1785     rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, old_b, 0, SPIF_UPDATEINIFILE );
1786     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1787 }
1788
1789 static void test_SPI_SETKEYBOARDPREF( void )           /*     69 */
1790 {
1791     BOOL rc;
1792     BOOL old_b;
1793     const UINT vals[]={TRUE,FALSE};
1794     unsigned int i;
1795
1796     trace("testing SPI_{GET,SET}KEYBOARDPREF\n");
1797     SetLastError(0xdeadbeef);
1798     rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &old_b, 0 );
1799     if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDPREF"))
1800         return;
1801
1802     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1803     {
1804         BOOL v;
1805
1806         rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0,
1807                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1808         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1809         test_change_message( SPI_SETKEYBOARDPREF, 0 );
1810         test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY,
1811                           SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY,
1812                           vals[i] ? "1" : "0" );
1813
1814         rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &v, 0 );
1815         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1816         eq( v, (BOOL)vals[i], "SPI_GETKEYBOARDPREF", "%d" );
1817     }
1818
1819     rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, old_b, 0, SPIF_UPDATEINIFILE );
1820     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1821 }
1822
1823 static void test_SPI_SETSCREENREADER( void )           /*     71 */
1824 {
1825     BOOL rc;
1826     BOOL old_b;
1827     const UINT vals[]={TRUE,FALSE};
1828     unsigned int i;
1829
1830     trace("testing SPI_{GET,SET}SCREENREADER\n");
1831     SetLastError(0xdeadbeef);
1832     rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &old_b, 0 );
1833     if (!test_error_msg(rc,"SPI_{GET,SET}SCREENREADER"))
1834         return;
1835
1836     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1837     {
1838         BOOL v;
1839
1840         rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0,
1841                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1842         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1843         test_change_message( SPI_SETSCREENREADER, 0 );
1844         test_reg_key_ex2( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY,
1845                       SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY,
1846                       vals[i] ? "1" : "0" );
1847
1848         rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &v, 0 );
1849         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1850         eq( v, (BOOL)vals[i], "SPI_GETSCREENREADER", "%d" );
1851     }
1852
1853     rc=SystemParametersInfoA( SPI_SETSCREENREADER, old_b, 0, SPIF_UPDATEINIFILE );
1854     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1855 }
1856
1857 static void test_SPI_SETFONTSMOOTHING( void )         /*     75 */
1858 {
1859     BOOL rc;
1860     BOOL old_b;
1861     const UINT vals[]={0xffffffff,0,1,2};
1862     unsigned int i;
1863
1864     trace("testing SPI_{GET,SET}FONTSMOOTHING\n");
1865     if( iswin9x) return; /* 95/98/ME don't seem to implement this fully */ 
1866     SetLastError(0xdeadbeef);
1867     rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &old_b, 0 );
1868     if (!test_error_msg(rc,"SPI_{GET,SET}FONTSMOOTHING"))
1869         return;
1870
1871     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1872     {
1873         UINT v;
1874
1875         rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, vals[i], 0,
1876                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1877         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1878         test_change_message( SPI_SETFONTSMOOTHING, 0 );
1879         test_reg_key( SPI_SETFONTSMOOTHING_REGKEY,
1880                       SPI_SETFONTSMOOTHING_VALNAME,
1881                       vals[i] ? "2" : "0" );
1882
1883         rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &v, 0 );
1884         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1885         eq( v, vals[i] ? 1 : 0, "SPI_GETFONTSMOOTHING", "%d" );
1886     }
1887
1888     rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, old_b, 0, SPIF_UPDATEINIFILE );
1889     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1890 }
1891
1892 static void test_SPI_SETLOWPOWERACTIVE( void )         /*     85 */
1893 {
1894     BOOL rc;
1895     BOOL old_b;
1896     const UINT vals[]={TRUE,FALSE};
1897     unsigned int i;
1898
1899     trace("testing SPI_{GET,SET}LOWPOWERACTIVE\n");
1900     SetLastError(0xdeadbeef);
1901     rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &old_b, 0 );
1902     if (!test_error_msg(rc,"SPI_{GET,SET}LOWPOWERACTIVE"))
1903         return;
1904
1905     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1906     {
1907         UINT v;
1908
1909         rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0,
1910                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1911         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1912         test_change_message( SPI_SETLOWPOWERACTIVE, 0 );
1913         test_reg_key( SPI_SETLOWPOWERACTIVE_REGKEY,
1914                       SPI_SETLOWPOWERACTIVE_VALNAME,
1915                       vals[i] ? "1" : "0" );
1916
1917         rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 );
1918         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1919         eq( v, vals[i], "SPI_GETLOWPOWERACTIVE", "%d" );
1920     }
1921
1922     rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
1923     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1924 }
1925
1926 static void test_SPI_SETPOWEROFFACTIVE( void )         /*     86 */
1927 {
1928     BOOL rc;
1929     BOOL old_b;
1930     const UINT vals[]={TRUE,FALSE};
1931     unsigned int i;
1932
1933     trace("testing SPI_{GET,SET}POWEROFFACTIVE\n");
1934     SetLastError(0xdeadbeef);
1935     rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &old_b, 0 );
1936     if (!test_error_msg(rc,"SPI_{GET,SET}POWEROFFACTIVE"))
1937         return;
1938
1939     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1940     {
1941         UINT v;
1942
1943         rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0,
1944                                   SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1945         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1946         test_change_message( SPI_SETPOWEROFFACTIVE, 0 );
1947         test_reg_key( SPI_SETPOWEROFFACTIVE_REGKEY,
1948                       SPI_SETPOWEROFFACTIVE_VALNAME,
1949                       vals[i] ? "1" : "0" );
1950
1951         rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 );
1952         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1953         eq( v, vals[i], "SPI_GETPOWEROFFACTIVE", "%d" );
1954     }
1955
1956     rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
1957     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1958 }
1959
1960 static void test_SPI_SETMOUSEHOVERWIDTH( void )      /*     99 */
1961 {
1962     BOOL rc;
1963     UINT old_width;
1964     const UINT vals[]={0,32767};
1965     unsigned int i;
1966
1967     trace("testing SPI_{GET,SET}MOUSEHOVERWIDTH\n");
1968     SetLastError(0xdeadbeef);
1969     rc=SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &old_width, 0 );
1970     /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
1971     * what MSDN states (Verified on Win98SE)
1972     */
1973     if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERWIDTH"))
1974         return;
1975     
1976     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1977     {
1978         UINT v;
1979         char buf[10];
1980
1981         rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, vals[i], 0,
1982                                SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1983         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1984         test_change_message( SPI_SETMOUSEHOVERWIDTH, 0 );
1985         sprintf( buf, "%d", vals[i] );
1986         test_reg_key( SPI_SETMOUSEHOVERWIDTH_REGKEY,
1987                       SPI_SETMOUSEHOVERWIDTH_VALNAME, buf );
1988
1989         SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &v, 0 );
1990         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
1991         eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERWIDTH", "%d" );
1992     }
1993
1994     rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, old_width, 0,
1995                               SPIF_UPDATEINIFILE );
1996     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
1997 }
1998
1999 static void test_SPI_SETMOUSEHOVERHEIGHT( void )      /*     101 */
2000 {
2001     BOOL rc;
2002     UINT old_height;
2003     const UINT vals[]={0,32767};
2004     unsigned int i;
2005
2006     trace("testing SPI_{GET,SET}MOUSEHOVERHEIGHT\n");
2007     SetLastError(0xdeadbeef);
2008     rc=SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &old_height, 0 );
2009     /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2010      * what MSDN states (Verified on Win98SE)
2011      */
2012     if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERHEIGHT"))
2013         return;
2014     
2015     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2016     {
2017         UINT v;
2018         char buf[10];
2019
2020         rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, vals[i], 0,
2021                                SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2022         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2023         test_change_message( SPI_SETMOUSEHOVERHEIGHT, 0 );
2024         sprintf( buf, "%d", vals[i] );
2025         test_reg_key( SPI_SETMOUSEHOVERHEIGHT_REGKEY,
2026                       SPI_SETMOUSEHOVERHEIGHT_VALNAME, buf );
2027
2028         SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &v, 0 );
2029         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2030         eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERHEIGHT", "%d" );
2031     }
2032
2033     rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, old_height, 0,
2034                               SPIF_UPDATEINIFILE );
2035     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
2036 }
2037
2038 static void test_SPI_SETMOUSEHOVERTIME( void )      /*     103 */
2039 {
2040     BOOL rc;
2041     UINT old_time;
2042
2043     /* Windows XP accepts 10 as the minimum hover time. Any value below will be
2044      * defaulted to a value of 10 automatically.
2045      */
2046     const UINT vals[]={10,32767};
2047     unsigned int i;
2048
2049     trace("testing SPI_{GET,SET}MOUSEHOVERTIME\n");
2050     SetLastError(0xdeadbeef);
2051     rc=SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &old_time, 0 );
2052     /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2053      * what MSDN states (Verified on Win98SE)
2054      */    
2055     if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERTIME"))
2056         return;
2057     
2058     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2059     {
2060         UINT v;
2061         char buf[10];
2062
2063         rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, vals[i], 0,
2064                                SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2065         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2066         test_change_message( SPI_SETMOUSEHOVERTIME, 0 );
2067         sprintf( buf, "%d", vals[i] );
2068         test_reg_key( SPI_SETMOUSEHOVERTIME_REGKEY,
2069                       SPI_SETMOUSEHOVERTIME_VALNAME, buf );
2070
2071         SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &v, 0 );
2072         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2073         eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERTIME", "%d" );
2074     }
2075
2076     rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, old_time, 0,
2077                               SPIF_UPDATEINIFILE );
2078     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
2079 }
2080
2081 static void test_SPI_SETWHEELSCROLLLINES( void )      /*     105 */
2082 {
2083     BOOL rc;
2084     UINT old_lines;
2085     const UINT vals[]={0,32767};
2086     unsigned int i;
2087
2088     trace("testing SPI_{GET,SET}WHEELSCROLLLINES\n");
2089     SetLastError(0xdeadbeef);
2090     rc=SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &old_lines, 0 );
2091
2092     /* SPI_{GET,SET}WHEELSCROLLLINES not supported on Windows 95 */
2093     if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLLINES"))
2094         return;
2095
2096     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2097     {
2098         UINT v;
2099         char buf[10];
2100
2101         rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, vals[i], 0,
2102                                SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2103         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2104         test_change_message( SPI_SETWHEELSCROLLLINES, 0 );
2105         sprintf( buf, "%d", vals[i] );
2106         test_reg_key( SPI_SETMOUSESCROLLLINES_REGKEY,
2107                       SPI_SETMOUSESCROLLLINES_VALNAME, buf );
2108
2109         SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &v, 0 );
2110         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2111         eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLLINES", "%d" );
2112     }
2113
2114     rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, old_lines, 0,
2115                               SPIF_UPDATEINIFILE );
2116     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
2117 }
2118
2119 static void test_SPI_SETMENUSHOWDELAY( void )      /*     107 */
2120 {
2121     BOOL rc;
2122     UINT old_delay;
2123     const UINT vals[]={0,32767};
2124     unsigned int i;
2125
2126     trace("testing SPI_{GET,SET}MENUSHOWDELAY\n");
2127     SetLastError(0xdeadbeef);
2128     rc=SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &old_delay, 0 );
2129
2130     /* SPI_{GET,SET}MENUSHOWDELAY not supported on Windows 95 */
2131     if (!test_error_msg(rc,"SPI_{GET,SET}MENUSHOWDELAY"))
2132         return;
2133
2134     for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2135     {
2136         UINT v;
2137         char buf[10];
2138
2139         rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, vals[i], 0,
2140                                SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2141         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2142         test_change_message( SPI_SETMENUSHOWDELAY, 0 );
2143         sprintf( buf, "%d", vals[i] );
2144         test_reg_key( SPI_SETMENUSHOWDELAY_REGKEY,
2145                       SPI_SETMENUSHOWDELAY_VALNAME, buf );
2146
2147         SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &v, 0 );
2148         ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
2149         eq( v, vals[i], "SPI_{GET,SET}MENUSHOWDELAY", "%d" );
2150     }
2151
2152     rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, old_delay, 0,
2153                               SPIF_UPDATEINIFILE );
2154     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
2155 }
2156
2157 static void test_SPI_SETWALLPAPER( void )              /*   115 */
2158 {
2159     BOOL rc;
2160     char oldval[260];
2161     char newval[260];
2162
2163     trace("testing SPI_{GET,SET}DESKWALLPAPER\n");
2164     SetLastError(0xdeadbeef);
2165     rc=SystemParametersInfoA(SPI_GETDESKWALLPAPER, 260, oldval, 0);
2166     /* SPI_{GET,SET}DESKWALLPAPER is completely broken on Win9x and
2167      * unimplemented on NT4
2168      */
2169     if (!test_error_msg(rc,"SPI_{GET,SET}DESKWALLPAPER"))
2170         return;
2171
2172     strcpy(newval, "");
2173     rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, newval, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
2174     ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
2175     test_change_message(SPI_SETDESKWALLPAPER, 0);
2176
2177     rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, oldval, SPIF_UPDATEINIFILE);
2178     ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
2179
2180     test_reg_key(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, oldval);
2181 }
2182
2183 static void test_WM_DISPLAYCHANGE(void)
2184 {
2185     DEVMODE mode, startmode;
2186     int start_bpp, last_set_bpp = 0;
2187     int test_bpps[] = {8, 16, 24, 32}, i;
2188     LONG change_ret;
2189     DWORD wait_ret;
2190
2191     displaychange_test_active = TRUE;
2192
2193     memset(&startmode, 0, sizeof(startmode));
2194     startmode.dmSize = sizeof(startmode);
2195     EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &startmode);
2196     start_bpp = startmode.dmBitsPerPel;
2197
2198     displaychange_sem = CreateSemaphore(NULL, 0, 1, NULL);
2199
2200     for(i = 0; i < sizeof(test_bpps)/sizeof(test_bpps[0]); i++) {
2201         last_bpp = -1;
2202
2203         memset(&mode, 0, sizeof(mode));
2204         mode.dmSize = sizeof(mode);
2205         mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2206         mode.dmBitsPerPel = test_bpps[i];
2207         mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2208         mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2209
2210         change_counter = 0; /* This sends a SETTINGSCHANGE message as well in which we aren't interested */
2211         displaychange_ok = TRUE;
2212         change_ret = ChangeDisplaySettingsEx(NULL, &mode, NULL, 0, NULL);
2213         /* Wait quite long for the message, screen setting changes can take some time */
2214         if(change_ret == DISP_CHANGE_SUCCESSFUL) {
2215             wait_ret = WaitForSingleObject(displaychange_sem, 10000);
2216             ok(wait_ret == WAIT_OBJECT_0, "Waiting for the WM_DISPLAYCHANGE message timed out\n");
2217         }
2218         displaychange_ok = FALSE;
2219
2220         if(change_ret != DISP_CHANGE_SUCCESSFUL) {
2221             skip("Setting depth %d failed(ret = %d)\n", test_bpps[i], change_ret);
2222             ok(last_bpp == -1, "WM_DISPLAYCHANGE was sent with wParam %d despide mode change failure\n", last_bpp);
2223             continue;
2224         }
2225
2226         if((start_bpp != test_bpps[i] ||
2227            (test_bpps[i] == 32 && last_bpp == 24)) &&
2228             !(test_bpps[i] == 24 && start_bpp == 32)) {
2229             todo_wine ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
2230         } else {
2231             ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
2232         }
2233         last_set_bpp = test_bpps[i];
2234     }
2235
2236     if(start_bpp != last_set_bpp && last_set_bpp != 0) {
2237         memset(&mode, 0, sizeof(mode));
2238         mode.dmSize = sizeof(mode);
2239         mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2240         mode.dmBitsPerPel = start_bpp;
2241         mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2242         mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2243
2244         displaychange_ok = TRUE;
2245         change_ret = ChangeDisplaySettingsEx(NULL, &mode, NULL, 0, NULL);
2246         WaitForSingleObject(displaychange_sem, 10000);
2247         displaychange_ok = FALSE;
2248         CloseHandle(displaychange_sem);
2249         displaychange_sem = 0;
2250     }
2251
2252     displaychange_test_active = FALSE;
2253 }
2254
2255 /*
2256  * Registry entries for the system parameters.
2257  * Names are created by 'SET' flags names.
2258  * We assume that corresponding 'GET' entries use the same registry keys.
2259  */
2260 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
2261 {
2262     test_SPI_SETBEEP();                         /*      1 */
2263     test_SPI_SETMOUSE();                        /*      4 */
2264     test_SPI_SETBORDER();                       /*      6 */
2265     test_SPI_SETKEYBOARDSPEED();                /*     10 */
2266     test_SPI_ICONHORIZONTALSPACING();           /*     13 */
2267     test_SPI_SETSCREENSAVETIMEOUT();            /*     14 */
2268     test_SPI_SETSCREENSAVEACTIVE();             /*     17 */
2269     test_SPI_SETGRIDGRANULARITY();              /*     19 */
2270     test_SPI_SETKEYBOARDDELAY();                /*     23 */
2271     test_SPI_ICONVERTICALSPACING();             /*     24 */
2272     test_SPI_SETICONTITLEWRAP();                /*     26 */
2273     test_SPI_SETMENUDROPALIGNMENT();            /*     28 */
2274     test_SPI_SETDOUBLECLKWIDTH();               /*     29 */
2275     test_SPI_SETDOUBLECLKHEIGHT();              /*     30 */
2276     test_SPI_SETDOUBLECLICKTIME();              /*     32 */
2277     test_SPI_SETMOUSEBUTTONSWAP();              /*     33 */
2278     test_SPI_SETFASTTASKSWITCH();               /*     36 */
2279     test_SPI_SETDRAGFULLWINDOWS();              /*     37 */
2280     test_SPI_SETNONCLIENTMETRICS();             /*     42 */
2281     test_SPI_SETMINIMIZEDMETRICS();             /*     44 */
2282     test_SPI_SETICONMETRICS();                  /*     46 */
2283     test_SPI_SETWORKAREA();                     /*     47 */
2284     test_SPI_SETSHOWSOUNDS();                   /*     57 */
2285     test_SPI_SETKEYBOARDPREF();                 /*     69 */
2286     test_SPI_SETSCREENREADER();                 /*     71 */
2287     test_SPI_SETFONTSMOOTHING();                /*     75 */
2288     test_SPI_SETLOWPOWERACTIVE();               /*     85 */
2289     test_SPI_SETPOWEROFFACTIVE();               /*     86 */
2290     test_SPI_SETMOUSEHOVERWIDTH();              /*     99 */
2291     test_SPI_SETMOUSEHOVERHEIGHT();             /*    101 */
2292     test_SPI_SETMOUSEHOVERTIME();               /*    103 */
2293     test_SPI_SETWHEELSCROLLLINES();             /*    105 */
2294     test_SPI_SETMENUSHOWDELAY();                /*    107 */
2295     test_SPI_SETWALLPAPER();                    /*    115 */
2296
2297     test_WM_DISPLAYCHANGE();
2298
2299     SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
2300     return 0;
2301 }
2302
2303 /* test calculation of GetSystemMetrics values (mostly) from non client metrics,
2304  * icon metrics and minimized metrics. 
2305  */
2306
2307 /* copied from wine's GdiGetCharDimensions, which is not available on most
2308  * windows versions */
2309 static LONG _GdiGetCharDimensions(HDC hdc, LPTEXTMETRICA lptm, LONG *height)
2310 {
2311     SIZE sz;
2312     static const CHAR alphabet[] = {
2313         'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
2314         'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
2315         'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
2316
2317     if(lptm && !GetTextMetricsA(hdc, lptm)) return 0;
2318
2319     if(!GetTextExtentPointA(hdc, alphabet, 52, &sz)) return 0;
2320
2321     if (height) *height = sz.cy;
2322     return (sz.cx / 26 + 1) / 2;
2323 }
2324
2325 /* get text metrics and/or "average" char width of the specified logfont
2326  * for the specified dc */
2327 static void get_text_metr_size( HDC hdc, LOGFONTA *plf, TEXTMETRICA * ptm, UINT *psz)
2328 {
2329     HFONT hfont, hfontsav;
2330     TEXTMETRICA tm;
2331     if( !ptm) ptm = &tm;
2332     hfont = CreateFontIndirectA( plf);
2333     if( !hfont || ( hfontsav = SelectObject( hdc, hfont)) == NULL ) {
2334         ptm->tmHeight = -1;
2335         if( psz) *psz = 10;
2336         if( hfont) DeleteObject( hfont);
2337         return;
2338     }
2339     GetTextMetricsA( hdc, ptm);
2340     if( psz)
2341         if( !(*psz = _GdiGetCharDimensions( hdc, ptm, NULL)))
2342             *psz = 10;
2343     SelectObject( hdc, hfontsav);
2344     DeleteObject( hfont);
2345 }
2346
2347 static int gsm_error_ctr;
2348 static UINT smcxsmsize = 999999999;
2349
2350 #define ok_gsm( i, e)\
2351 {\
2352     int exp = (e);\
2353     int act = GetSystemMetrics( (i));\
2354     if( exp != act) gsm_error_ctr++;\
2355     ok( !( exp != act),"GetSystemMetrics(%s): expected %d actual %d\n", #i, exp,act);\
2356 }
2357 #define ok_gsm_2( i, e1, e2)\
2358 {\
2359     int exp1 = (e1);\
2360     int exp2 = (e2);\
2361     int act = GetSystemMetrics( (i));\
2362     if( exp1 != act && exp2 != act) gsm_error_ctr++;\
2363     ok( !( exp1 != act && exp2 != act), "GetSystemMetrics(%s): expected %d or %d actual %d\n", #i, exp1, exp2, act);\
2364 }
2365 #define ok_gsm_3( i, e1, e2, e3)\
2366 {\
2367     int exp1 = (e1);\
2368     int exp2 = (e2);\
2369     int exp3 = (e3);\
2370     int act = GetSystemMetrics( (i));\
2371     if( exp1 != act && exp2 != act && exp3 != act) gsm_error_ctr++;\
2372     ok( !( exp1 != act && exp2 != act && exp3 != act),"GetSystemMetrics(%s): expected %d or %d or %d actual %d\n", #i, exp1, exp2, exp3, act);\
2373 }
2374
2375 static void test_GetSystemMetrics( void)
2376 {
2377     TEXTMETRICA tmMenuFont;
2378     UINT IconSpacing, IconVerticalSpacing;
2379
2380     HDC hdc = CreateIC( "Display", 0, 0, 0);
2381     UINT avcwCaption;
2382     INT CaptionWidth;
2383     MINIMIZEDMETRICS minim;
2384     NONCLIENTMETRICS ncm;
2385     minim.cbSize = sizeof( minim);
2386     ncm.cbSize = sizeof( ncm);
2387     SystemParametersInfo( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0);
2388     SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2389
2390     /* CaptionWidth from the registry may have different value of iCaptionWidth
2391      * from the non client metrics (observed on WinXP) */
2392     CaptionWidth = metricfromreg(
2393             "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
2394     get_text_metr_size( hdc, &ncm.lfMenuFont, &tmMenuFont, NULL);
2395     get_text_metr_size( hdc, &ncm.lfCaptionFont, NULL, &avcwCaption);
2396     /* FIXME: use icon metric */
2397     if( !SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &IconVerticalSpacing, 0))
2398         IconVerticalSpacing = 0;
2399     if( !SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &IconSpacing, 0 ))
2400         IconSpacing = 0;
2401     /* reset error counters */
2402     gsm_error_ctr = 0;
2403
2404     /* the tests: */
2405
2406     /* SM_CXSCREEN, cannot test these two */
2407     /* SM_CYSCREEN */
2408     ok_gsm( SM_CXVSCROLL,  ncm.iScrollWidth);
2409     ok_gsm( SM_CYHSCROLL,  ncm.iScrollWidth);
2410     ok_gsm( SM_CYCAPTION, ncm.iCaptionHeight+1);
2411     ok_gsm( SM_CXBORDER, 1);
2412     ok_gsm( SM_CYBORDER, 1);
2413     ok_gsm( SM_CXDLGFRAME, 3);
2414     ok_gsm( SM_CYDLGFRAME, 3);
2415     ok_gsm( SM_CYVTHUMB,  ncm.iScrollHeight);
2416     ok_gsm( SM_CXHTHUMB,  ncm.iScrollHeight);
2417     /* SM_CXICON */
2418     /* SM_CYICON */
2419     /* SM_CXCURSOR */
2420     /* SM_CYCURSOR */
2421     ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1);
2422     ok_gsm( SM_CXFULLSCREEN,
2423             GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME));
2424     ok_gsm( SM_CYFULLSCREEN,
2425             GetSystemMetrics( SM_CYMAXIMIZED) - GetSystemMetrics( SM_CYMIN));
2426     /* SM_CYKANJIWINDOW */
2427     /* SM_MOUSEPRESENT */
2428     ok_gsm( SM_CYVSCROLL, ncm.iScrollHeight);
2429     ok_gsm( SM_CXHSCROLL, ncm.iScrollHeight);
2430     /* SM_DEBUG */
2431     /* SM_SWAPBUTTON */
2432     /* SM_RESERVED1 */
2433     /* SM_RESERVED2 */
2434     /* SM_RESERVED3 */
2435     /* SM_RESERVED4 */
2436     ok_gsm( SM_CXMIN, 3 * max( CaptionWidth, 8) + GetSystemMetrics( SM_CYSIZE) +
2437             4 + 4 * avcwCaption + 2 * GetSystemMetrics( SM_CXFRAME));
2438     ok_gsm( SM_CYMIN, GetSystemMetrics( SM_CYCAPTION) +
2439             2 * GetSystemMetrics( SM_CYFRAME));
2440     ok_gsm_2( SM_CXSIZE,
2441         ncm.iCaptionWidth,  /* classic/standard windows style */
2442         GetSystemMetrics( SM_CYCAPTION) - 1 /* WinXP style */
2443         );
2444     ok_gsm( SM_CYSIZE,  ncm.iCaptionHeight);
2445     ok_gsm( SM_CXFRAME, ncm.iBorderWidth + 3);
2446     ok_gsm( SM_CYFRAME, ncm.iBorderWidth + 3);
2447     ok_gsm( SM_CXMINTRACK,  GetSystemMetrics( SM_CXMIN));
2448     ok_gsm( SM_CYMINTRACK,  GetSystemMetrics( SM_CYMIN));
2449     /* SM_CXDOUBLECLK */
2450     /* SM_CYDOUBLECLK */
2451     if( IconSpacing) ok_gsm( SM_CXICONSPACING, IconSpacing);
2452     if( IconVerticalSpacing) ok_gsm( SM_CYICONSPACING, IconVerticalSpacing);
2453     /* SM_MENUDROPALIGNMENT */
2454     /* SM_PENWINDOWS */
2455     /* SM_DBCSENABLED */
2456     /* SM_CMOUSEBUTTONS */
2457     /* SM_SECURE */
2458     ok_gsm( SM_CXEDGE, 2);
2459     ok_gsm( SM_CYEDGE, 2);
2460     ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + minim.iHorzGap );
2461     ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + minim.iVertGap );
2462     /* SM_CXSMICON */
2463     /* SM_CYSMICON */
2464     ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1);
2465     ok_gsm_3( SM_CXSMSIZE,
2466         ncm.iSmCaptionWidth, /* classic/standard windows style */
2467         GetSystemMetrics( SM_CYSMCAPTION) - 1, /* WinXP style */
2468         smcxsmsize /* winXP seems to cache this value: setnonclientmetric
2469                       does not change it */
2470         );
2471     ok_gsm( SM_CYSMSIZE, GetSystemMetrics( SM_CYSMCAPTION) - 1);
2472     ok_gsm( SM_CXMENUSIZE, ncm.iMenuWidth);
2473     ok_gsm( SM_CYMENUSIZE, ncm.iMenuHeight);
2474     /* SM_ARRANGE */
2475     ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6);
2476     ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5);
2477     ok_gsm( SM_CXMAXTRACK, GetSystemMetrics( SM_CXVIRTUALSCREEN) +
2478             4 + 2 * GetSystemMetrics( SM_CXFRAME));
2479     ok_gsm( SM_CYMAXTRACK, GetSystemMetrics( SM_CYVIRTUALSCREEN) +
2480             4 + 2 * GetSystemMetrics( SM_CYFRAME));
2481     /* the next two cannot really be tested as they depend on (application)
2482      * toolbars */
2483     /* SM_CXMAXIMIZED */
2484     /* SM_CYMAXIMIZED */
2485     /* SM_NETWORK */
2486     /* */
2487     /* */
2488     /* */
2489     /* SM_CLEANBOOT */
2490     /* SM_CXDRAG */
2491     /* SM_CYDRAG */
2492     /* SM_SHOWSOUNDS */
2493     ok_gsm( SM_CXMENUCHECK,
2494             ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2495     ok_gsm( SM_CYMENUCHECK,
2496             ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2497     /* SM_SLOWMACHINE */
2498     /* SM_MIDEASTENABLED */
2499     /* SM_MOUSEWHEELPRESENT */
2500     /* SM_XVIRTUALSCREEN */
2501     /* SM_YVIRTUALSCREEN */
2502     /* SM_CXVIRTUALSCREEN */
2503     /* SM_CYVIRTUALSCREEN */
2504     /* SM_CMONITORS */
2505     /* SM_SAMEDISPLAYFORMAT */
2506     /* SM_IMMENABLED */
2507     /* SM_CXFOCUSBORDER */
2508     /* SM_CYFOCUSBORDER */
2509     /* SM_TABLETPC */
2510     /* SM_MEDIACENTER */
2511     /* SM_CMETRICS */
2512     /* end of tests */
2513     if( gsm_error_ctr ) { /* if any errors where found */
2514         trace( "BorderWidth %d CaptionWidth %d CaptionHeight %d IconSpacing %d IconVerticalSpacing %d\n",
2515                 ncm.iBorderWidth, ncm.iCaptionWidth, ncm.iCaptionHeight, IconSpacing, IconVerticalSpacing);
2516         trace( "MenuHeight %d MenuWidth %d ScrollHeight %d ScrollWidth %d SmCaptionHeight %d SmCaptionWidth %d\n",
2517                 ncm.iMenuHeight, ncm.iMenuWidth, ncm.iScrollHeight, ncm.iScrollWidth, ncm.iSmCaptionHeight, ncm.iSmCaptionWidth);
2518         trace( "Captionfontchar width %d  MenuFont %d,%d CaptionWidth from registry: %d\n",
2519                 avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidth);
2520     }
2521     ReleaseDC( 0, hdc);
2522 }
2523
2524 static void test_EnumDisplaySettings(void)
2525 {
2526     DEVMODE devmode;
2527     DWORD val;
2528     HDC hdc;
2529
2530     memset(&devmode, 0, sizeof(devmode));
2531     devmode.dmSize = sizeof(devmode);
2532     EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2533
2534     hdc = GetDC(0);
2535     val = GetDeviceCaps(hdc, BITSPIXEL);
2536     if(devmode.dmBitsPerPel == 32 && val == 24) {
2537         todo_wine ok(devmode.dmBitsPerPel == val, "GetDeviceCaps(BITSPIXEL) returned %d, EnumDisplaySettings returned %d\n",
2538                      val, devmode.dmBitsPerPel);
2539     } else {
2540         ok(devmode.dmBitsPerPel == val, "GetDeviceCaps(BITSPIXEL) returned %d, EnumDisplaySettings returned %d\n",
2541            val, devmode.dmBitsPerPel);
2542     }
2543
2544     val = GetDeviceCaps(hdc, NUMCOLORS);
2545     if(devmode.dmBitsPerPel <= 8) {
2546         ok(val == 256, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
2547     } else {
2548         ok(val == -1, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
2549     }
2550
2551     ReleaseDC(0, hdc);
2552 }
2553
2554 START_TEST(sysparams)
2555 {
2556     int argc;
2557     char** argv;
2558     WNDCLASSA wc;
2559     MSG msg;
2560     HANDLE hThread;
2561     DWORD dwThreadId;
2562     HANDLE hInstance = GetModuleHandleA( NULL );
2563
2564     hdc = GetDC(0);
2565     dpi = GetDeviceCaps( hdc, LOGPIXELSY);
2566     iswin9x = GetVersion() & 0x80000000;
2567
2568     /* This test requires interactivity, if we don't have it, give up */
2569     if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) &&
2570         GetLastError()==ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) return;
2571
2572     argc = winetest_get_mainargs(&argv);
2573     strict=(argc >= 3 && strcmp(argv[2],"strict")==0);
2574     trace("strict=%d\n",strict);
2575
2576     trace("testing GetSystemMetrics with your current desktop settings\n");
2577     test_GetSystemMetrics( );
2578     trace("testing EnumDisplaySettings vs GetDeviceCaps\n");
2579     test_EnumDisplaySettings( );
2580
2581     change_counter = 0;
2582     change_last_param = 0;
2583
2584     wc.lpszClassName = "SysParamsTestClass";
2585     wc.lpfnWndProc = SysParamsTestWndProc;
2586     wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
2587     wc.hInstance = hInstance;
2588     wc.hIcon = LoadIconA( 0, (LPSTR)IDI_APPLICATION );
2589     wc.hCursor = LoadCursorA( 0, (LPSTR)IDC_ARROW );
2590     wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1 );
2591     wc.lpszMenuName = 0;
2592     wc.cbClsExtra = 0;
2593     wc.cbWndExtra = 0;
2594     RegisterClassA( &wc );
2595
2596     ghTestWnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
2597                                WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, hInstance, NULL );
2598
2599     hThread = CreateThread( NULL, 0, SysParamsThreadFunc, 0, 0, &dwThreadId );
2600     assert( hThread );
2601     CloseHandle( hThread );
2602
2603     while( GetMessageA( &msg, 0, 0, 0 )) {
2604         TranslateMessage( &msg );
2605         DispatchMessageA( &msg );
2606     }
2607     ReleaseDC( 0, hdc);
2608
2609 }