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