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