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