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