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