1 /* Unit test suite for functions SystemParametersInfo and GetSystemMetrics.
2 *
3 * Copyright 2002 Andriy Palamarchuk
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #include <assert.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <stdio.h>
24
25 #undef _WIN32_WINNT
26 #define _WIN32_WINNT 0x0600 /* For SPI_GETMOUSEHOVERWIDTH and more */
27 #define _WIN32_IE 0x0700
28
29 #include "wine/test.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winreg.h"
34 #include "winuser.h"
35 #include "winnls.h"
36
37 #ifndef SPI_GETDESKWALLPAPER
38 # define SPI_GETDESKWALLPAPER 0x0073
39 #endif
40
41 static LONG (WINAPI *pChangeDisplaySettingsExA)(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);
42
43 static int strict;
44 static int dpi;
45 static int iswin9x;
46 static HDC hdc;
47
48 #define eq(received, expected, label, type) \
49 ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
50
51
52 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
53 #define SPI_SETBEEP_VALNAME "Beep"
54 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
55 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
56 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
57 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
58 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop\\WindowMetrics"
59 #define SPI_SETBORDER_REGKEY2 "Control Panel\\Desktop"
60 #define SPI_SETBORDER_VALNAME "BorderWidth"
61 #define SPI_METRIC_REGKEY "Control Panel\\Desktop\\WindowMetrics"
62 #define SPI_SCROLLWIDTH_VALNAME "ScrollWidth"
63 #define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight"
64 #define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth"
65 #define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight"
66 #define SPI_CAPTIONFONT_VALNAME "CaptionFont"
67 #define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth"
68 #define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight"
69 #define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont"
70 #define SPI_MENUWIDTH_VALNAME "MenuWidth"
71 #define SPI_MENUHEIGHT_VALNAME "MenuHeight"
72 #define SPI_MENUFONT_VALNAME "MenuFont"
73 #define SPI_STATUSFONT_VALNAME "StatusFont"
74 #define SPI_MESSAGEFONT_VALNAME "MessageFont"
75
76 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
77 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
78 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
79 #define SPI_ICONHORIZONTALSPACING_REGKEY2 "Control Panel\\Desktop"
80 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
81 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
82 #define SPI_ICONVERTICALSPACING_REGKEY2 "Control Panel\\Desktop"
83 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
84 #define SPI_MINIMIZEDMETRICS_REGKEY "Control Panel\\Desktop\\WindowMetrics"
85 #define SPI_MINWIDTH_VALNAME "MinWidth"
86 #define SPI_MINHORZGAP_VALNAME "MinHorzGap"
87 #define SPI_MINVERTGAP_VALNAME "MinVertGap"
88 #define SPI_MINARRANGE_VALNAME "MinArrange"
89 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
90 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
91 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
92 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
93 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
94 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
95 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
96 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
97 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
98 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
99 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
100 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
101 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
102 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
103 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
104 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
105 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
106 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
107 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
108 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
109 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
110 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
111 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
112 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
113 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
114 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
115 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
116 #define SPI_SETSHOWSOUNDS_VALNAME "On"
117 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Accessibility\\Keyboard Preference"
118 #define SPI_SETKEYBOARDPREF_VALNAME "On"
119 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY "Control Panel\\Accessibility"
120 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY "Keyboard Preference"
121 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Accessibility\\Blind Access"
122 #define SPI_SETSCREENREADER_VALNAME "On"
123 #define SPI_SETSCREENREADER_REGKEY_LEGACY "Control Panel\\Accessibility"
124 #define SPI_SETSCREENREADER_VALNAME_LEGACY "Blind Access"
125 #define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\\Desktop"
126 #define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing"
127 #define SPI_SETLOWPOWERACTIVE_REGKEY "Control Panel\\Desktop"
128 #define SPI_SETLOWPOWERACTIVE_VALNAME "LowPowerActive"
129 #define SPI_SETPOWEROFFACTIVE_REGKEY "Control Panel\\Desktop"
130 #define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive"
131 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
132 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
133 #define SPI_SETSNAPTODEFBUTTON_REGKEY "Control Panel\\Mouse"
134 #define SPI_SETSNAPTODEFBUTTON_VALNAME "SnapToDefaultButton"
135 #define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse"
136 #define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth"
137 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse"
138 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight"
139 #define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse"
140 #define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime"
141 #define SPI_SETMOUSESCROLLCHARS_REGKEY "Control Panel\\Desktop"
142 #define SPI_SETMOUSESCROLLCHARS_VALNAME "WheelScrollChars"
143 #define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop"
144 #define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines"
145 #define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop"
146 #define SPI_SETMENUSHOWDELAY_VALNAME "MenuShowDelay"
147 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
148 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
149
150 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
151 #define WINE_CURRENT_USER_REGKEY "Wine"
152
153 static HWND ghTestWnd;
154
155 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
156 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
157 LPARAM lParam );
158 static int change_counter;
159 static int change_last_param;
160 static int last_bpp;
161 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
162 static HANDLE displaychange_sem = 0;
163
164 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
165 LPARAM lParam )
166 {
167 switch (msg) {
168
169 case WM_DISPLAYCHANGE:
170 ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
171 last_bpp = wParam;
172 displaychange_ok = FALSE;
173 ReleaseSemaphore(displaychange_sem, 1, 0);
174 break;
175
176 case WM_SETTINGCHANGE:
177 if (change_counter>0) {
178 /* ignore these messages caused by resizing of toolbars */
179 if( wParam == SPI_SETWORKAREA || displaychange_test_active) break;
180 if( change_last_param == SPI_SETWORKAREA) {
181 change_last_param = wParam;
182 break;
183 }
184 ok(0,"too many changes counter=%d last change=%d\n",
185 change_counter,change_last_param);
186 }
187 change_counter++;
188 change_last_param = wParam;
189 break;
190
191 case WM_DESTROY:
192 PostQuitMessage( 0 );
193 break;
194
195 /* drop through */
196 default:
197 return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
198 }
199
200 return 0;
201 }
202
203 /*
204 Performs testing for system parameters messages
205 params:
206 - system parameter id
207 - supposed value of the registry key
208 */
209 static void test_change_message( int action, int optional )
210 {
211 if (change_counter==0 && optional==1)
212 return;
213 ok( 1 == change_counter,
214 "Missed a message: change_counter=%d\n", change_counter );
215 change_counter = 0;
216 ok( action == change_last_param,
217 "Wrong action got %d expected %d\n", change_last_param, action );
218 change_last_param = 0;
219 }
220
221 static BOOL test_error_msg ( int rc, const char *name )
222 {
223 DWORD last_error = GetLastError();
224
225 if (rc==0)
226 {
227 if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
228 {
229 trace("%s not supported on this platform. Skipping test\n", name);
230 }
231 else if (last_error==ERROR_ACCESS_DENIED)
232 {
233 trace("%s does not have privileges to run. Skipping test\n", name);
234 }
235 else
236 {
237 trace("%s failed for reason: %d. Indicating test failure and skipping remainder of test\n",name,last_error);
238 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
239 }
240 return FALSE;
241 }
242 else
243 {
244 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
245 return TRUE;
246 }
247 }
248
249 /*
250 * Tests the HKEY_CURRENT_USER subkey value.
251 * The value should contain string value.
252 *
253 * Params:
254 * lpsSubKey - subkey name
255 * lpsRegName - registry entry name
256 * lpsTestValue - value to test
257 */
258 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2, LPCSTR testValue )
259 {
260 CHAR value[MAX_PATH];
261 DWORD valueLen;
262 DWORD type;
263 HKEY hKey;
264 LONG rc;
265 int found=0;
266
267 *value='\0';
268 valueLen=sizeof(value);
269 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
270 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
271 RegCloseKey( hKey );
272 if (rc==ERROR_SUCCESS)
273 {
274 ok( !strcmp( testValue, value ),
275 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
276 subKey1, valName1, testValue, value );
277 found++;
278 }
279 else if (strict)
280 {
281 ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
282 subKey1, valName1);
283 }
284 if (valName2)
285 {
286 *value='\0';
287 valueLen=sizeof(value);
288 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
289 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
290 RegCloseKey( hKey );
291 if (rc==ERROR_SUCCESS)
292 {
293 ok( !strcmp( testValue, value ),
294 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
295 subKey1, valName2, testValue, value );
296 found++;
297 }
298 else if (strict)
299 {
300 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
301 subKey1, valName2 );
302 }
303 }
304 if (subKey2 && !strict)
305 {
306 *value='\0';
307 valueLen=sizeof(value);
308 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
309 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
310 RegCloseKey( hKey );
311 if (rc==ERROR_SUCCESS)
312 {
313 ok( !strcmp( testValue, value ),
314 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
315 subKey2, valName1, testValue, value );
316 found++;
317 }
318 else if (strict)
319 {
320 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
321 subKey2, valName1 );
322 }
323 if (valName2)
324 {
325 *value='\0';
326 valueLen=sizeof(value);
327 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
328 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
329 RegCloseKey( hKey );
330 if (rc==ERROR_SUCCESS)
331 {
332 ok( !strcmp( testValue, value ),
333 "Wrong value in registry: subKey=%s, valName=%s, testValue=%s, value=%s\n",
334 subKey2, valName2, testValue, value );
335 found++;
336 }
337 else if (strict)
338 {
339 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
340 subKey2, valName2 );
341 }
342 }
343 }
344 ok(found,"Missing registry values: %s or %s in keys: %s or %s\n",
345 valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
346 }
347
348 #define test_reg_key( subKey, valName, testValue ) \
349 _test_reg_key( subKey, NULL, valName, NULL, testValue )
350 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
351 _test_reg_key( subKey1, subKey2, valName, NULL, testValue )
352 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
353 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue )
354
355 /* get a metric from the registry. If the value is negative
356 * it is assumed to be in twips and converted to pixels */
357 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
358 {
359 HKEY hkey;
360 char buf[64];
361 DWORD ret;
362 DWORD size, type;
363 int value;
364
365 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
366 size = sizeof(buf);
367 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
368 RegCloseKey( hkey );
369 if( ret != ERROR_SUCCESS) return -1;
370 value = atoi( buf);
371 if( value < 0)
372 value = ( -value * dpi + 720) / 1440;
373 return value;
374 }
375
376 typedef struct
377 {
378 INT16 lfHeight;
379 INT16 lfWidth;
380 INT16 lfEscapement;
381 INT16 lfOrientation;
382 INT16 lfWeight;
383 BYTE lfItalic;
384 BYTE lfUnderline;
385 BYTE lfStrikeOut;
386 BYTE lfCharSet;
387 BYTE lfOutPrecision;
388 BYTE lfClipPrecision;
389 BYTE lfQuality;
390 BYTE lfPitchAndFamily;
391 CHAR lfFaceName[LF_FACESIZE];
392 } LOGFONT16, *LPLOGFONT16;
393
394 /* get logfont from the registry */
395 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
396 {
397 HKEY hkey;
398 LOGFONTW lfw;
399 DWORD ret, size, type;
400
401 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
402 size = sizeof( lfw);
403 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
404 RegCloseKey( hkey );
405 ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
406 if( ret != ERROR_SUCCESS)
407 return FALSE;
408 if( size <= sizeof( LOGFONT16)) {
409 LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
410 plf->lfHeight = plf16->lfHeight;
411 plf->lfWidth = plf16->lfWidth;
412 plf->lfEscapement = plf16->lfEscapement;
413 plf->lfOrientation = plf16->lfOrientation;
414 plf->lfWeight = plf16->lfWeight;
415 plf->lfItalic = plf16->lfItalic;
416 plf->lfUnderline = plf16->lfUnderline;
417 plf->lfStrikeOut = plf16->lfStrikeOut;
418 plf->lfCharSet = plf16->lfCharSet;
419 plf->lfOutPrecision = plf16->lfOutPrecision;
420 plf->lfClipPrecision = plf16->lfClipPrecision;
421 plf->lfQuality = plf16->lfQuality;
422 plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
423 memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
424 } else if( size <= sizeof( LOGFONTA)) {
425 plf = (LOGFONTA*) &lfw;
426 } else {
427 plf->lfHeight = lfw.lfHeight;
428 plf->lfWidth = lfw.lfWidth;
429 plf->lfEscapement = lfw.lfEscapement;
430 plf->lfOrientation = lfw.lfOrientation;
431 plf->lfWeight = lfw.lfWeight;
432 plf->lfItalic = lfw.lfItalic;
433 plf->lfUnderline = lfw.lfUnderline;
434 plf->lfStrikeOut = lfw.lfStrikeOut;
435 plf->lfCharSet = lfw.lfCharSet;
436 plf->lfOutPrecision = lfw.lfOutPrecision;
437 plf->lfClipPrecision = lfw.lfClipPrecision;
438 plf->lfQuality = lfw.lfQuality;
439 plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
440 WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
441 LF_FACESIZE, NULL, NULL);
442
443 }
444 return TRUE;
445 }
446
447 static void test_SPI_SETBEEP( void ) /* 2 */
448 {
449 BOOL rc;
450 BOOL old_b;
451 BOOL b;
452 BOOL curr_val;
453
454 trace("testing SPI_{GET,SET}BEEP\n");
455 SetLastError(0xdeadbeef);
456 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
457 if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
458 return;
459
460 curr_val = TRUE;
461 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
462 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
463 test_change_message( SPI_SETBEEP, 0 );
464 test_reg_key( SPI_SETBEEP_REGKEY,
465 SPI_SETBEEP_VALNAME,
466 curr_val ? "Yes" : "No" );
467 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
468 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
469 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
470 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
471 if (rc!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED)
472 {
473 ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
474 eq( b, curr_val, "SystemParametersInfoW", "%d" );
475 }
476
477 /* is a message sent for the second change? */
478 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
479 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
480 test_change_message( SPI_SETBEEP, 0 );
481
482 curr_val = FALSE;
483 rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
484 if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
485 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
486 ok(rc!=0,"SystemParametersInfo: rc=%d err=%d\n",rc,GetLastError());
487 test_change_message( SPI_SETBEEP, 0 );
488 test_reg_key( SPI_SETBEEP_REGKEY,
489 SPI_SETBEEP_VALNAME,
490 curr_val ? "Yes" : "No" );
491 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
492 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
493 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
494 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
495 if (rc!=0 || GetLastError()!=ERROR_CALL_NOT_IMPLEMENTED)
496 {
497 ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
498 eq( b, curr_val, "SystemParametersInfoW", "%d" );
499 }
500 ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
501
502 rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
503 ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
504 }
505
506 static const char *setmouse_valuenames[3] = {
507 SPI_SETMOUSE_VALNAME1,
508 SPI_SETMOUSE_VALNAME2,
509 SPI_SETMOUSE_VALNAME3
510 };
511
512 /*
513 * Runs check for one setting of spi_setmouse.
514 */
515 static void run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change,
516 int nchange )
517 {
518 BOOL rc;
519 INT mi[3];
520 static int aw_turn = 0;
521 static BOOL w_implemented = 1;
522
523 char buf[20];
524 int i;
525
526 aw_turn++;
527 rc=0;
528 if ((aw_turn % 2!=0) && (w_implemented))
529 {
530 /* call unicode on odd (non even) calls */
531 SetLastError(0xdeadbeef);
532 rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
533 if (rc==0 && GetLastError()==ERROR_CALL_NOT_IMPLEMENTED)
534 {
535 w_implemented = 0;
536 trace("SystemParametersInfoW not supported on this platform\n");
537 }
538 }
539
540 if ((aw_turn % 2==0) || (!w_implemented))
541 {
542 /* call ascii version on even calls or if unicode is not available */
543 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
544 }
545
546 ok(rc!=0,"SystemParametersInfo: rc=%d err=%d\n",rc,GetLastError());
547 test_change_message( SPI_SETMOUSE, 0 );
548 for (i = 0; i < 3; i++)
549 {
550 sprintf( buf, "%d", curr_val[i] );
551 test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
552 }
553
554 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
555 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
556 for (i = 0; i < 3; i++)
557 {
558 ok(mi[i] == curr_val[i],
559 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
560 }
561
562 if (w_implemented)
563 {
564 rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
565 ok(rc!=0,"SystemParametersInfoW: rc=%d err=%d\n",rc,GetLastError());
566 for (i = 0; i < 3; i++)
567 {
568 ok(mi[i] == curr_val[i],
569 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
570 }
571 }
572
573 if (0)
574 {
575 /* FIXME: this always fails for me - AJ */
576 for (i = 0; i < nchange; i++)
577 {
578 POINT mv;
579 mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
580 mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
581 GetCursorPos( &mv );
582 ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
583 ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
584 }
585 }
586 }
587
588 static void test_SPI_SETMOUSE( void ) /* 4 */
589 {
590 BOOL rc;
591 INT old_mi[3];
592
593 /* win nt default values - 6, 10, 1 */
594 INT curr_val[3] = {6, 10, 1};
595
596 /* requested and projected mouse movements */
597 POINT req_change[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
598 POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
599 POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
600 POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
601 POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
602 POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
603 POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
604 POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
605 POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
606
607 int nchange = sizeof( req_change ) / sizeof( POINT );
608
609 trace("testing SPI_{GET,SET}MOUSE\n");
610 SetLastError(0xdeadbeef);
611 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
612 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
613 return;
614
615 run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange );
616
617 /* acceleration change */
618 curr_val[2] = 2;
619 run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
620
621 /* acceleration change */
622 curr_val[2] = 3;
623 run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
624
625 /* acceleration change */
626 curr_val[2] = 0;
627 run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
628
629 /* threshold change */
630 curr_val[2] = 1;
631 curr_val[0] = 7;
632 run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
633
634 /* threshold change */
635 curr_val[2] = 2;
636 curr_val[0] = 6;
637 curr_val[1] = 6;
638 run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
639
640 /* threshold change */
641 curr_val[1] = 7;
642 run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
643
644 /* threshold change */
645 curr_val[1] = 5;
646 run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
647
648 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
649 ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
650 }
651
652 static void test_setborder(UINT curr_val, int usesetborder, int dpi)
653 {
654 BOOL rc;
655 UINT border, regval;
656 INT frame;
657 NONCLIENTMETRICSA ncm;
658
659 ncm.cbSize = sizeof( ncm);
660 rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
661 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
662 if( usesetborder) {
663 rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
664 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
665 test_change_message( SPI_SETBORDER, 1 );
666 } else { /* set non client metrics */
667 ncm.iBorderWidth = curr_val;
668 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
669 SPIF_SENDCHANGE);
670 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
671 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
672 }
673 if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
674 regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
675 if( regval != curr_val)
676 regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
677 ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
678 }
679 /* minimum border width is 1 */
680 if (curr_val == 0) curr_val = 1;
681 /* should be the same as the non client metrics */
682 rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
683 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
684 eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
685 /* and from SPI_GETBORDER */
686 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
687 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
688 eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
689 /* test some SystemMetrics */
690 frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
691 eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
692 eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
693 eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
694 eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
695 }
696
697 static void test_SPI_SETBORDER( void ) /* 6 */
698 {
699 BOOL rc;
700 UINT old_border;
701 NONCLIENTMETRICSA ncmsave;
702 INT CaptionWidth;
703
704 ncmsave.cbSize = sizeof( ncmsave);
705 rc=SystemParametersInfo( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
706 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,GetLastError());
707 /* CaptionWidth from the registry may have different value of iCaptionWidth
708 * from the non client metrics (observed on WinXP).
709 * Fix this so we can safely restore settings with the nonclientmetrics */
710 CaptionWidth = metricfromreg(
711 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
712 ncmsave.iCaptionWidth = CaptionWidth;
713
714 /* These tests hang when XFree86 4.0 for Windows is running (tested on
715 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
716 * running.
717 */
718 if (FindWindowA( NULL, "Cygwin/XFree86" ))
719 return;
720
721 trace("testing SPI_{GET,SET}BORDER\n");
722
723 SetLastError(0xdeadbeef);
724 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 );
725 if (!test_error_msg(rc,"SPI_{GET,SET}BORDER"))
726 return;
727 /* This will restore sane values if the test hang previous run. */
728 if ( old_border == 7 || old_border == 20 )
729 old_border = 1;
730
731 /* The SPI_SETBORDER seems to be buggy on Win9x/ME (looks like you need to
732 * do it twice to make the intended change). So skip parts of the tests on
733 * those platforms */
734 if( !iswin9x) {
735 /* win2k3 fails if you set the same border twice, or if size is 0 */
736 test_setborder(2, 1, dpi);
737 test_setborder(1, 1, dpi);
738 test_setborder(3, 1, dpi);
739 }
740 test_setborder(1, 0, dpi);
741 test_setborder(0, 0, dpi);
742 test_setborder(3, 0, dpi);
743
744 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave,
745 SPIF_UPDATEINIFILE| SPIF_SENDCHANGE);
746 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
747 ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",
748 rc,GetLastError());
749 }
750
751 static void test_SPI_SETKEYBOARDSPEED( void ) /* 10 */
752 {
753 BOOL rc;
754 UINT old_speed;
755 const UINT vals[]={0,20,31};
756 unsigned int i;
757
758 trace("testing SPI_{GET,SET}KEYBOARDSPEED\n");
759 SetLastError(0xdeadbeef);
760 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &old_speed, 0 );
761 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDSPEED"))
762 return;
763
764 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
765 {
766 UINT v;
767 char buf[10];
768
769 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, vals[i], 0,
770 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
771 ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
772 test_change_message( SPI_SETKEYBOARDSPEED, 0 );
773 sprintf( buf, "%d", vals[i] );
774 test_reg_key( SPI_SETKEYBOARDSPEED_REGKEY, SPI_SETKEYBOARDSPEED_VALNAME, buf );
775
776 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &v, 0 );
777 ok(rc!=0,"%d: rc=%d err=%d\n",i,rc,GetLastError());
778 eq( v, vals[i], "SPI_{GET,SET}KEYBOARDSPEED", "%d" );
779 }
780
781 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, old_speed, 0, SPIF_UPDATEINIFILE );
782 ok(rc!=0,"***warning*** failed to restore the original value: rc=%d err=%d\n",rc,GetLastError());
783 }
784
785 /* test_SPI_ICONHORIZONTALSPACING helper */
786 static void dotest_spi_