user32/tests: Add tests for GetDpiForSystem().
[wine.git] / dlls / user32 / tests / sysparams.c
blob5b185b9792e20fb0af3a62a9a03e1b08a9496f51
1 /* Unit test suite for functions SystemParametersInfo and GetSystemMetrics.
3 * Copyright 2002 Andriy Palamarchuk
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.
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.
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
20 #define _WIN32_WINNT 0x0600 /* For SPI_GETMOUSEHOVERWIDTH and more */
21 #define _WIN32_IE 0x0700
22 #define WINVER 0x0600 /* For COLOR_MENUBAR, NONCLIENTMETRICS with padding */
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <stdio.h>
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"
37 #ifndef SPI_GETDESKWALLPAPER
38 # define SPI_GETDESKWALLPAPER 0x0073
39 #endif
41 static LONG (WINAPI *pChangeDisplaySettingsExA)(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);
42 static BOOL (WINAPI *pIsProcessDPIAware)(void);
43 static BOOL (WINAPI *pSetProcessDPIAware)(void);
44 static BOOL (WINAPI *pSetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
45 static BOOL (WINAPI *pGetProcessDpiAwarenessInternal)(HANDLE,DPI_AWARENESS*);
46 static BOOL (WINAPI *pSetProcessDpiAwarenessInternal)(DPI_AWARENESS);
47 static UINT (WINAPI *pGetDpiForSystem)(void);
48 static DPI_AWARENESS_CONTEXT (WINAPI *pGetThreadDpiAwarenessContext)(void);
49 static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
50 static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
51 static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
52 static BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
54 static BOOL strict;
55 static int dpi, real_dpi;
56 static BOOL iswin9x;
57 static HDC hdc;
59 #define eq(received, expected, label, type) \
60 ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
63 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
64 #define SPI_SETBEEP_VALNAME "Beep"
65 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
66 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
67 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
68 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
69 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop\\WindowMetrics"
70 #define SPI_SETBORDER_REGKEY2 "Control Panel\\Desktop"
71 #define SPI_SETBORDER_VALNAME "BorderWidth"
72 #define SPI_METRIC_REGKEY "Control Panel\\Desktop\\WindowMetrics"
73 #define SPI_SCROLLWIDTH_VALNAME "ScrollWidth"
74 #define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight"
75 #define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth"
76 #define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight"
77 #define SPI_CAPTIONFONT_VALNAME "CaptionFont"
78 #define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth"
79 #define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight"
80 #define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont"
81 #define SPI_MENUWIDTH_VALNAME "MenuWidth"
82 #define SPI_MENUHEIGHT_VALNAME "MenuHeight"
83 #define SPI_MENUFONT_VALNAME "MenuFont"
84 #define SPI_STATUSFONT_VALNAME "StatusFont"
85 #define SPI_MESSAGEFONT_VALNAME "MessageFont"
87 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
88 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
89 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
90 #define SPI_ICONHORIZONTALSPACING_REGKEY2 "Control Panel\\Desktop"
91 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
92 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
93 #define SPI_ICONVERTICALSPACING_REGKEY2 "Control Panel\\Desktop"
94 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
95 #define SPI_MINIMIZEDMETRICS_REGKEY "Control Panel\\Desktop\\WindowMetrics"
96 #define SPI_MINWIDTH_VALNAME "MinWidth"
97 #define SPI_MINHORZGAP_VALNAME "MinHorzGap"
98 #define SPI_MINVERTGAP_VALNAME "MinVertGap"
99 #define SPI_MINARRANGE_VALNAME "MinArrange"
100 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
101 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
102 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
103 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
104 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
105 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
106 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
107 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
108 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
109 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
110 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
111 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
112 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
113 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
114 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
115 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
116 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
117 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
118 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
119 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
120 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
121 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
122 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
123 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
124 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
125 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
126 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
127 #define SPI_SETSHOWSOUNDS_VALNAME "On"
128 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Accessibility\\Keyboard Preference"
129 #define SPI_SETKEYBOARDPREF_VALNAME "On"
130 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY "Control Panel\\Accessibility"
131 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY "Keyboard Preference"
132 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Accessibility\\Blind Access"
133 #define SPI_SETSCREENREADER_VALNAME "On"
134 #define SPI_SETSCREENREADER_REGKEY_LEGACY "Control Panel\\Accessibility"
135 #define SPI_SETSCREENREADER_VALNAME_LEGACY "Blind Access"
136 #define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\\Desktop"
137 #define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing"
138 #define SPI_SETFONTSMOOTHINGTYPE_VALNAME "FontSmoothingType"
139 #define SPI_SETFONTSMOOTHINGCONTRAST_VALNAME "FontSmoothingGamma"
140 #define SPI_SETFONTSMOOTHINGORIENTATION_VALNAME "FontSmoothingOrientation"
141 #define SPI_SETLOWPOWERACTIVE_REGKEY "Control Panel\\Desktop"
142 #define SPI_SETLOWPOWERACTIVE_VALNAME "LowPowerActive"
143 #define SPI_SETPOWEROFFACTIVE_REGKEY "Control Panel\\Desktop"
144 #define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive"
145 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
146 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
147 #define SPI_SETSNAPTODEFBUTTON_REGKEY "Control Panel\\Mouse"
148 #define SPI_SETSNAPTODEFBUTTON_VALNAME "SnapToDefaultButton"
149 #define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse"
150 #define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth"
151 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse"
152 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight"
153 #define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse"
154 #define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime"
155 #define SPI_SETMOUSESCROLLCHARS_REGKEY "Control Panel\\Desktop"
156 #define SPI_SETMOUSESCROLLCHARS_VALNAME "WheelScrollChars"
157 #define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop"
158 #define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines"
159 #define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop"
160 #define SPI_SETMENUSHOWDELAY_VALNAME "MenuShowDelay"
161 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
162 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
164 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
165 #define WINE_CURRENT_USER_REGKEY "Wine"
167 static HWND ghTestWnd;
169 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
170 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
171 LPARAM lParam );
172 static int change_counter;
173 static int change_setworkarea_param, change_iconverticalspacing_param;
174 static int change_last_param;
175 static int last_bpp;
176 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
177 static HANDLE displaychange_sem = 0;
179 static BOOL get_reg_dword(HKEY base, const char *key_name, const char *value_name, DWORD *value)
181 HKEY key;
182 DWORD type, data, size = sizeof(data);
183 BOOL ret = FALSE;
185 if (RegOpenKeyA(base, key_name, &key) == ERROR_SUCCESS)
187 if (RegQueryValueExA(key, value_name, NULL, &type, (void *)&data, &size) == ERROR_SUCCESS &&
188 type == REG_DWORD)
190 *value = data;
191 ret = TRUE;
193 RegCloseKey(key);
195 return ret;
198 static DWORD get_real_dpi(void)
200 DWORD dpi;
202 if (pSetThreadDpiAwarenessContext)
204 DPI_AWARENESS_CONTEXT context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
205 dpi = pGetDpiForSystem();
206 pSetThreadDpiAwarenessContext( context );
207 return dpi;
209 if (get_reg_dword(HKEY_CURRENT_USER, "Control Panel\\Desktop", "LogPixels", &dpi))
210 return dpi;
211 if (get_reg_dword(HKEY_CURRENT_CONFIG, "Software\\Fonts", "LogPixels", &dpi))
212 return dpi;
213 return USER_DEFAULT_SCREEN_DPI;
216 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
217 LPARAM lParam )
219 switch (msg) {
221 case WM_DISPLAYCHANGE:
222 ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
223 last_bpp = wParam;
224 displaychange_ok = FALSE;
225 ReleaseSemaphore(displaychange_sem, 1, 0);
226 break;
228 case WM_SETTINGCHANGE:
229 if (change_counter>0) {
230 /* ignore these messages caused by resizing of toolbars */
231 if( wParam == SPI_SETWORKAREA){
232 change_setworkarea_param = 1;
233 break;
234 } else if( wParam == SPI_ICONVERTICALSPACING) {
235 change_iconverticalspacing_param = 1;
236 break;
237 } else if( displaychange_test_active)
238 break;
239 if( !change_last_param){
240 change_last_param = wParam;
241 break;
243 ok(0,"too many changes counter=%d last change=%d\n",
244 change_counter,change_last_param);
245 change_counter++;
246 change_last_param = wParam;
247 break;
249 change_counter++;
250 change_last_param = change_setworkarea_param = change_iconverticalspacing_param =0;
251 if( wParam == SPI_SETWORKAREA)
252 change_setworkarea_param = 1;
253 else if( wParam == SPI_ICONVERTICALSPACING)
254 change_iconverticalspacing_param = 1;
255 else
256 change_last_param = wParam;
257 break;
259 case WM_DESTROY:
260 PostQuitMessage( 0 );
261 break;
263 /* drop through */
264 default:
265 return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
268 return 0;
272 Performs testing for system parameters messages
273 params:
274 - system parameter id
275 - supposed value of the registry key
277 static void test_change_message( int action, int optional )
279 if (change_counter==0 && optional==1)
280 return;
281 ok( 1 == change_counter,
282 "Missed a message: change_counter=%d\n", change_counter );
283 change_counter = 0;
284 ok( action == change_last_param ||
285 ( change_setworkarea_param && action == SPI_SETWORKAREA) ||
286 ( change_iconverticalspacing_param && action == SPI_ICONVERTICALSPACING),
287 "Wrong action got %d expected %d\n", change_last_param, action );
288 change_last_param = 0;
291 static BOOL test_error_msg ( int rc, const char *name )
293 DWORD last_error = GetLastError();
295 if (rc==0)
297 if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
299 skip("%s not supported on this platform\n", name);
301 else if (last_error==ERROR_ACCESS_DENIED)
303 skip("%s does not have privileges to run\n", name);
305 else
307 trace("%s failed for reason: %d. Indicating test failure and skipping remainder of test\n",name,last_error);
308 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
310 return FALSE;
312 else
314 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
315 return TRUE;
320 * Tests the HKEY_CURRENT_USER subkey value.
321 * The value should contain string value.
323 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2,
324 const void *exp_value, DWORD exp_type, BOOL optional )
326 CHAR value[MAX_PATH];
327 DWORD valueLen;
328 DWORD type;
329 HKEY hKey;
330 LONG rc;
331 int found=0;
333 *value='\0';
334 valueLen=sizeof(value);
335 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
336 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
337 RegCloseKey( hKey );
338 if (rc==ERROR_SUCCESS)
340 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
341 switch (exp_type)
343 case REG_DWORD:
344 ok( *(DWORD *)value == *(DWORD *)exp_value,
345 "Wrong value in registry: %s %s %08x/%08x\n",
346 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
347 break;
348 case REG_SZ:
349 ok( !strcmp( exp_value, value ),
350 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
351 subKey1, valName1, value, (const char *)exp_value );
352 break;
354 found++;
356 else if (strict)
358 ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
359 subKey1, valName1);
361 if (valName2)
363 *value='\0';
364 valueLen=sizeof(value);
365 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
366 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
367 RegCloseKey( hKey );
368 if (rc==ERROR_SUCCESS)
370 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
371 switch (exp_type)
373 case REG_DWORD:
374 ok( *(DWORD *)value == *(DWORD *)exp_value,
375 "Wrong value in registry: %s %s %08x/%08x\n",
376 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
377 break;
378 case REG_SZ:
379 ok( !strcmp( exp_value, value ),
380 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
381 subKey1, valName1, value, (const char *)exp_value );
382 break;
384 found++;
386 else if (strict)
388 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
389 subKey1, valName2 );
392 if (subKey2 && !strict)
394 *value='\0';
395 valueLen=sizeof(value);
396 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
397 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
398 RegCloseKey( hKey );
399 if (rc==ERROR_SUCCESS)
401 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
402 switch (exp_type)
404 case REG_DWORD:
405 ok( *(DWORD *)value == *(DWORD *)exp_value,
406 "Wrong value in registry: %s %s %08x/%08x\n",
407 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
408 break;
409 case REG_SZ:
410 ok( !strcmp( exp_value, value ),
411 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
412 subKey1, valName1, value, (const char *)exp_value );
413 break;
415 found++;
417 else if (strict)
419 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
420 subKey2, valName1 );
422 if (valName2)
424 *value='\0';
425 valueLen=sizeof(value);
426 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
427 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
428 RegCloseKey( hKey );
429 if (rc==ERROR_SUCCESS)
431 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
432 switch (exp_type)
434 case REG_DWORD:
435 ok( *(DWORD *)value == *(DWORD *)exp_value,
436 "Wrong value in registry: %s %s %08x/%08x\n",
437 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
438 break;
439 case REG_SZ:
440 ok( !strcmp( exp_value, value ),
441 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
442 subKey1, valName1, value, (const char *)exp_value );
443 break;
445 found++;
447 else if (strict)
449 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
450 subKey2, valName2 );
454 ok(found || optional,
455 "Missing registry values: %s or %s in keys: %s or %s\n",
456 valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
459 #define test_reg_key( subKey, valName, testValue ) \
460 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, FALSE )
461 #define test_reg_key_optional( subKey, valName, testValue ) \
462 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, TRUE )
463 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
464 _test_reg_key( subKey1, subKey2, valName, NULL, testValue, REG_SZ, FALSE )
465 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
466 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, FALSE )
467 #define test_reg_key_ex2_optional( subKey1, subKey2, valName1, valName2, testValue ) \
468 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, TRUE )
469 #define test_reg_key_dword( subKey, valName, testValue ) \
470 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_DWORD, FALSE )
472 /* get a metric from the registry. If the value is negative
473 * it is assumed to be in twips and converted to pixels */
474 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
476 HKEY hkey;
477 char buf[64];
478 DWORD ret;
479 DWORD size, type;
480 int value;
482 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
483 size = sizeof(buf);
484 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
485 RegCloseKey( hkey );
486 if( ret != ERROR_SUCCESS) return -1;
487 value = atoi( buf);
488 if( value < 0)
489 value = ( -value * dpi + 720) / 1440;
490 return value;
493 typedef struct
495 INT16 lfHeight;
496 INT16 lfWidth;
497 INT16 lfEscapement;
498 INT16 lfOrientation;
499 INT16 lfWeight;
500 BYTE lfItalic;
501 BYTE lfUnderline;
502 BYTE lfStrikeOut;
503 BYTE lfCharSet;
504 BYTE lfOutPrecision;
505 BYTE lfClipPrecision;
506 BYTE lfQuality;
507 BYTE lfPitchAndFamily;
508 CHAR lfFaceName[LF_FACESIZE];
509 } LOGFONT16, *LPLOGFONT16;
511 /* get logfont from the registry */
512 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
514 HKEY hkey;
515 LOGFONTW lfw;
516 DWORD ret, size, type;
518 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
519 size = sizeof( lfw);
520 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
521 RegCloseKey( hkey );
522 ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
523 if( ret != ERROR_SUCCESS)
524 return FALSE;
525 if( size <= sizeof( LOGFONT16)) {
526 LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
527 plf->lfHeight = plf16->lfHeight;
528 plf->lfWidth = plf16->lfWidth;
529 plf->lfEscapement = plf16->lfEscapement;
530 plf->lfOrientation = plf16->lfOrientation;
531 plf->lfWeight = plf16->lfWeight;
532 plf->lfItalic = plf16->lfItalic;
533 plf->lfUnderline = plf16->lfUnderline;
534 plf->lfStrikeOut = plf16->lfStrikeOut;
535 plf->lfCharSet = plf16->lfCharSet;
536 plf->lfOutPrecision = plf16->lfOutPrecision;
537 plf->lfClipPrecision = plf16->lfClipPrecision;
538 plf->lfQuality = plf16->lfQuality;
539 plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
540 memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
541 } else if( size <= sizeof( LOGFONTA)) {
542 plf = (LOGFONTA*) &lfw;
543 } else {
544 plf->lfHeight = lfw.lfHeight;
545 plf->lfWidth = lfw.lfWidth;
546 plf->lfEscapement = lfw.lfEscapement;
547 plf->lfOrientation = lfw.lfOrientation;
548 plf->lfWeight = lfw.lfWeight;
549 plf->lfItalic = lfw.lfItalic;
550 plf->lfUnderline = lfw.lfUnderline;
551 plf->lfStrikeOut = lfw.lfStrikeOut;
552 plf->lfCharSet = lfw.lfCharSet;
553 plf->lfOutPrecision = lfw.lfOutPrecision;
554 plf->lfClipPrecision = lfw.lfClipPrecision;
555 plf->lfQuality = lfw.lfQuality;
556 plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
557 WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
558 LF_FACESIZE, NULL, NULL);
561 return TRUE;
564 static void test_SPI_SETBEEP( void ) /* 2 */
566 BOOL rc;
567 BOOL old_b;
568 BOOL b;
569 BOOL curr_val;
571 trace("testing SPI_{GET,SET}BEEP\n");
572 SetLastError(0xdeadbeef);
573 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
574 if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
575 return;
577 curr_val = TRUE;
578 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
579 if (!test_error_msg(rc,"SPI_SETBEEP")) return;
580 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
581 test_change_message( SPI_SETBEEP, 0 );
582 test_reg_key( SPI_SETBEEP_REGKEY,
583 SPI_SETBEEP_VALNAME,
584 curr_val ? "Yes" : "No" );
585 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
586 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
587 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
588 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
589 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
591 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
592 eq( b, curr_val, "SystemParametersInfoW", "%d" );
595 /* is a message sent for the second change? */
596 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
597 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
598 test_change_message( SPI_SETBEEP, 0 );
600 curr_val = FALSE;
601 rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
602 if (rc == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
603 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
604 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
605 test_change_message( SPI_SETBEEP, 0 );
606 test_reg_key( SPI_SETBEEP_REGKEY,
607 SPI_SETBEEP_VALNAME,
608 curr_val ? "Yes" : "No" );
609 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
610 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
611 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
612 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
613 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
615 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
616 eq( b, curr_val, "SystemParametersInfoW", "%d" );
618 ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
620 rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
621 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
624 static const char *setmouse_valuenames[3] = {
625 SPI_SETMOUSE_VALNAME1,
626 SPI_SETMOUSE_VALNAME2,
627 SPI_SETMOUSE_VALNAME3
631 * Runs check for one setting of spi_setmouse.
633 static BOOL run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change, int nchange )
635 BOOL rc;
636 INT mi[3];
637 static int aw_turn = 0;
638 static BOOL w_implemented = TRUE;
640 char buf[20];
641 int i;
643 aw_turn++;
644 rc = FALSE;
645 if ((aw_turn % 2!=0) && (w_implemented))
647 /* call unicode on odd (non even) calls */
648 SetLastError(0xdeadbeef);
649 rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
650 if (rc == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
652 w_implemented = FALSE;
653 trace("SystemParametersInfoW not supported on this platform\n");
657 if ((aw_turn % 2==0) || (!w_implemented))
659 /* call ascii version on even calls or if unicode is not available */
660 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
662 if (!test_error_msg(rc,"SPI_SETMOUSE")) return FALSE;
664 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
665 test_change_message( SPI_SETMOUSE, 0 );
666 for (i = 0; i < 3; i++)
668 sprintf( buf, "%d", curr_val[i] );
669 test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
672 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
673 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
674 for (i = 0; i < 3; i++)
676 ok(mi[i] == curr_val[i],
677 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
680 if (w_implemented)
682 rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
683 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
684 for (i = 0; i < 3; i++)
686 ok(mi[i] == curr_val[i],
687 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
691 if (0)
693 /* FIXME: this always fails for me - AJ */
694 for (i = 0; i < nchange; i++)
696 POINT mv;
697 mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
698 mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
699 GetCursorPos( &mv );
700 ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
701 ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
704 return TRUE;
707 static void test_SPI_SETMOUSE( void ) /* 4 */
709 BOOL rc;
710 INT old_mi[3];
712 /* win nt default values - 6, 10, 1 */
713 INT curr_val[3] = {6, 10, 1};
715 /* requested and projected mouse movements */
716 POINT req_change[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
717 POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
718 POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
719 POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
720 POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
721 POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
722 POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
723 POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
724 POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
726 int nchange = sizeof( req_change ) / sizeof( POINT );
728 trace("testing SPI_{GET,SET}MOUSE\n");
729 SetLastError(0xdeadbeef);
730 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
731 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
732 return;
734 if (!run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange )) return;
736 /* acceleration change */
737 curr_val[2] = 2;
738 run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
740 /* acceleration change */
741 curr_val[2] = 3;
742 run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
744 /* acceleration change */
745 curr_val[2] = 0;
746 run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
748 /* threshold change */
749 curr_val[2] = 1;
750 curr_val[0] = 7;
751 run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
753 /* threshold change */
754 curr_val[2] = 2;
755 curr_val[0] = 6;
756 curr_val[1] = 6;
757 run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
759 /* threshold change */
760 curr_val[1] = 7;
761 run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
763 /* threshold change */
764 curr_val[1] = 5;
765 run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
767 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
768 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
771 static BOOL test_setborder(UINT curr_val, int usesetborder, int dpi)
773 BOOL rc;
774 UINT border, regval;
775 INT frame;
776 NONCLIENTMETRICSA ncm;
778 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
779 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
780 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
781 if( usesetborder) {
782 rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
783 if (!test_error_msg(rc,"SPI_SETBORDER")) return FALSE;
784 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
785 test_change_message( SPI_SETBORDER, 1 );
786 } else { /* set non client metrics */
787 ncm.iBorderWidth = curr_val;
788 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
789 SPIF_SENDCHANGE);
790 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return FALSE;
791 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
792 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
794 if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
795 regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
796 if( regval != curr_val)
797 regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
798 ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
800 /* minimum border width is 1 */
801 if (curr_val == 0) curr_val = 1;
802 /* should be the same as the non client metrics */
803 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
804 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
805 eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
806 /* and from SPI_GETBORDER */
807 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
808 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
809 eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
810 /* test some SystemMetrics */
811 frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
812 eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
813 eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
814 eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
815 eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
816 return TRUE;
819 static void test_SPI_SETBORDER( void ) /* 6 */
821 BOOL rc;
822 UINT old_border;
823 NONCLIENTMETRICSA ncmsave;
824 INT CaptionWidth,
825 PaddedBorderWidth;
827 ncmsave.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
828 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
829 if( !rc) {
830 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
831 return;
833 /* CaptionWidth from the registry may have different value of iCaptionWidth
834 * from the non client metrics (observed on WinXP).
835 * Fix this so we can safely restore settings with the nonclientmetrics */
836 CaptionWidth = metricfromreg(
837 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
838 ncmsave.iCaptionWidth = CaptionWidth;
840 /* These tests hang when XFree86 4.0 for Windows is running (tested on
841 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
842 * running.
844 if (FindWindowA( NULL, "Cygwin/XFree86" ))
845 return;
847 trace("testing SPI_{GET,SET}BORDER\n");
849 SetLastError(0xdeadbeef);
850 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 );
851 if (!test_error_msg(rc,"SPI_{GET,SET}BORDER"))
852 return;
853 /* FIXME: include new PaddedBorderWidth parameter */
854 PaddedBorderWidth = ncmsave.iBorderWidth - old_border;
855 if( PaddedBorderWidth){
856 win_skip( "Cannot reliably restore border width yet (PaddedBorderWidth = %d)\n",
857 PaddedBorderWidth);
858 return;
860 /* This will restore sane values if the test hang previous run. */
861 if ( old_border == 7 || old_border == 20 )
862 old_border = 1;
864 /* The SPI_SETBORDER seems to be buggy on Win9x/ME (looks like you need to
865 * do it twice to make the intended change). So skip parts of the tests on
866 * those platforms */
867 if( !iswin9x) {
868 /* win2k3 fails if you set the same border twice, or if size is 0 */
869 if (!test_setborder(2, 1, dpi)) return;
870 test_setborder(1, 1, dpi);
871 test_setborder(3, 1, dpi);
873 if (!test_setborder(1, 0, dpi)) return;
874 test_setborder(0, 0, dpi);
875 test_setborder(3, 0, dpi);
877 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave,
878 SPIF_UPDATEINIFILE| SPIF_SENDCHANGE);
879 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
880 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
883 static void test_SPI_SETKEYBOARDSPEED( void ) /* 10 */
885 BOOL rc;
886 UINT old_speed;
887 const UINT vals[]={0,20,31};
888 unsigned int i;
890 trace("testing SPI_{GET,SET}KEYBOARDSPEED\n");
891 SetLastError(0xdeadbeef);
892 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &old_speed, 0 );
893 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDSPEED"))
894 return;
896 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
898 UINT v;
899 char buf[10];
901 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, vals[i], 0,
902 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
903 if (!test_error_msg(rc,"SPI_SETKEYBOARDSPEED")) return;
904 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
905 test_change_message( SPI_SETKEYBOARDSPEED, 0 );
906 sprintf( buf, "%d", vals[i] );
907 test_reg_key( SPI_SETKEYBOARDSPEED_REGKEY, SPI_SETKEYBOARDSPEED_VALNAME, buf );
909 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &v, 0 );
910 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
911 eq( v, vals[i], "SPI_{GET,SET}KEYBOARDSPEED", "%d" );
914 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, old_speed, 0, SPIF_UPDATEINIFILE );
915 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
918 /* test_SPI_ICONHORIZONTALSPACING helper */
919 static BOOL dotest_spi_iconhorizontalspacing( INT curr_val)
921 BOOL rc;
922 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
923 ICONMETRICSA im;
925 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0,
926 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
927 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING")) return FALSE;
928 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
929 test_change_message( SPI_ICONHORIZONTALSPACING, 0 );
930 curr_val = max( curr_val, min_val );
931 /* The registry keys depend on the Windows version and the values too
932 * let's test (works on win95,ME,NT4,2k,XP)
934 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY2, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
935 if( regval != curr_val)
936 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
937 ok( curr_val == regval,
938 "wrong value in registry %d, expected %d\n", regval, curr_val);
939 /* compare with what SPI_ICONHORIZONTALSPACING returns */
940 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
941 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
942 eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d");
943 /* and with a system metrics */
944 eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" );
945 /* and with what SPI_GETICONMETRICS returns */
946 im.cbSize = sizeof(ICONMETRICSA);
947 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
948 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
949 eq( im.iHorzSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
950 return TRUE;
953 static void test_SPI_ICONHORIZONTALSPACING( void ) /* 13 */
955 BOOL rc;
956 INT old_spacing;
958 trace("testing SPI_ICONHORIZONTALSPACING\n");
959 SetLastError(0xdeadbeef);
960 /* default value: 75 */
961 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &old_spacing, 0 );
962 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING"))
963 return;
964 /* do not increase the value as it would upset the user's icon layout */
965 if (!dotest_spi_iconhorizontalspacing( old_spacing - 1)) return;
966 dotest_spi_iconhorizontalspacing( 10); /* minimum is 32 */
967 /* restore */
968 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, old_spacing, 0, SPIF_UPDATEINIFILE );
969 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
972 static void test_SPI_SETSCREENSAVETIMEOUT( void ) /* 14 */
974 BOOL rc;
975 UINT old_timeout;
976 const UINT vals[]={0,32767};
977 unsigned int i;
979 trace("testing SPI_{GET,SET}SCREENSAVETIMEOUT\n");
980 SetLastError(0xdeadbeef);
981 rc=SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &old_timeout, 0 );
982 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVETIMEOUT"))
983 return;
985 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
987 UINT v;
988 char buf[10];
990 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, vals[i], 0,
991 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
992 if (!test_error_msg(rc,"SPI_SETSCREENSAVETIMEOUT")) return;
993 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
994 test_change_message( SPI_SETSCREENSAVETIMEOUT, 0 );
995 sprintf( buf, "%d", vals[i] );
996 test_reg_key( SPI_SETSCREENSAVETIMEOUT_REGKEY,
997 SPI_SETSCREENSAVETIMEOUT_VALNAME, buf );
999 rc = SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &v, 0 );
1000 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1001 eq( v, vals[i], "SPI_{GET,SET}SCREENSAVETIMEOUT", "%d" );
1004 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, old_timeout, 0,
1005 SPIF_UPDATEINIFILE );
1006 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1009 static void test_SPI_SETSCREENSAVEACTIVE( void ) /* 17 */
1011 BOOL rc;
1012 BOOL old_b;
1013 const UINT vals[]={TRUE,FALSE};
1014 unsigned int i;
1016 trace("testing SPI_{GET,SET}SCREENSAVEACTIVE\n");
1017 SetLastError(0xdeadbeef);
1018 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &old_b, 0 );
1019 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVEACTIVE"))
1020 return;
1022 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1024 UINT v;
1026 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, vals[i], 0,
1027 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1028 if (!test_error_msg(rc,"SPI_SETSCREENSAVEACTIVE")) return;
1029 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1030 test_change_message( SPI_SETSCREENSAVEACTIVE, 0 );
1031 test_reg_key( SPI_SETSCREENSAVEACTIVE_REGKEY,
1032 SPI_SETSCREENSAVEACTIVE_VALNAME,
1033 vals[i] ? "1" : "0" );
1035 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &v, 0 );
1036 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1037 ok(v == vals[i] || broken(! v) /* Win 7 */,
1038 "SPI_{GET,SET}SCREENSAVEACTIVE: got %d instead of %d\n", v, vals[i]);
1041 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
1042 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1045 static void test_SPI_SETGRIDGRANULARITY( void ) /* 19 */
1047 /* ??? */;
1050 static void test_SPI_SETKEYBOARDDELAY( void ) /* 23 */
1052 BOOL rc;
1053 UINT old_delay;
1054 const UINT vals[]={0,3};
1055 unsigned int i;
1057 trace("testing SPI_{GET,SET}KEYBOARDDELAY\n");
1058 SetLastError(0xdeadbeef);
1059 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &old_delay, 0 );
1060 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDDELAY"))
1061 return;
1063 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1065 UINT delay;
1066 char buf[10];
1068 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, vals[i], 0,
1069 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1070 if (!test_error_msg(rc,"SPI_SETKEYBOARDDELAY")) return;
1071 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1072 test_change_message( SPI_SETKEYBOARDDELAY, 0 );
1073 sprintf( buf, "%d", vals[i] );
1074 test_reg_key( SPI_SETKEYBOARDDELAY_REGKEY,
1075 SPI_SETKEYBOARDDELAY_VALNAME, buf );
1077 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &delay, 0 );
1078 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1079 eq( delay, vals[i], "SPI_{GET,SET}KEYBOARDDELAY", "%d" );
1082 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, old_delay, 0, SPIF_UPDATEINIFILE );
1083 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1087 /* test_SPI_ICONVERTICALSPACING helper */
1088 static BOOL dotest_spi_iconverticalspacing( INT curr_val)
1090 BOOL rc;
1091 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
1092 ICONMETRICSA im;
1094 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0,
1095 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1096 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING")) return FALSE;
1097 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1098 test_change_message( SPI_ICONVERTICALSPACING, 0 );
1099 curr_val = max( curr_val, min_val );
1100 /* The registry keys depend on the Windows version and the values too
1101 * let's test (works on win95,ME,NT4,2k,XP)
1103 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY2, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1104 if( regval != curr_val)
1105 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1106 ok( curr_val == regval,
1107 "wrong value in registry %d, expected %d\n", regval, curr_val);
1108 /* compare with what SPI_ICONVERTICALSPACING returns */
1109 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1110 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1111 eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" );
1112 /* and with a system metrics */
1113 eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" );
1114 /* and with what SPI_GETICONMETRICS returns */
1115 im.cbSize = sizeof(ICONMETRICSA);
1116 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1117 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1118 eq( im.iVertSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
1119 return TRUE;
1122 static void test_SPI_ICONVERTICALSPACING( void ) /* 24 */
1124 BOOL rc;
1125 INT old_spacing;
1127 trace("testing SPI_ICONVERTICALSPACING\n");
1128 SetLastError(0xdeadbeef);
1129 /* default value: 75 */
1130 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &old_spacing, 0 );
1131 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING"))
1132 return;
1133 /* do not increase the value as it would upset the user's icon layout */
1134 if (!dotest_spi_iconverticalspacing( old_spacing - 1)) return;
1135 /* same tests with a value less than the minimum 32 */
1136 dotest_spi_iconverticalspacing( 10);
1137 /* restore */
1138 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, old_spacing, 0,
1139 SPIF_UPDATEINIFILE );
1140 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1143 static void test_SPI_SETICONTITLEWRAP( void ) /* 26 */
1145 BOOL rc;
1146 BOOL old_b;
1147 const UINT vals[]={TRUE,FALSE};
1148 unsigned int i;
1149 ICONMETRICSA im;
1151 /* These tests hang when XFree86 4.0 for Windows is running (tested on
1152 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
1153 * running.
1155 if (FindWindowA( NULL, "Cygwin/XFree86" ))
1156 return;
1158 trace("testing SPI_{GET,SET}ICONTITLEWRAP\n");
1159 SetLastError(0xdeadbeef);
1160 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &old_b, 0 );
1161 if (!test_error_msg(rc,"SPI_{GET,SET}ICONTITLEWRAP"))
1162 return;
1164 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1166 UINT v;
1167 UINT regval;
1169 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, vals[i], 0,
1170 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1171 if (!test_error_msg(rc,"SPI_SETICONTITLEWRAP")) return;
1172 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1173 test_change_message( SPI_SETICONTITLEWRAP, 1 );
1174 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2,
1175 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1176 if( regval != vals[i])
1177 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1,
1178 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1179 ok( regval == vals[i] || broken(regval == -1), /* win9x */
1180 "wrong value in registry %d, expected %d\n", regval, vals[i] );
1182 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &v, 0 );
1183 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1184 eq( v, vals[i], "SPI_{GET,SET}ICONTITLEWRAP", "%d" );
1185 /* and test with what SPI_GETICONMETRICS returns */
1186 im.cbSize = sizeof(ICONMETRICSA);
1187 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1188 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1189 eq( im.iTitleWrap, (BOOL)vals[i], "SPI_GETICONMETRICS", "%d" );
1192 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, old_b, 0, SPIF_UPDATEINIFILE );
1193 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1196 static void test_SPI_SETMENUDROPALIGNMENT( void ) /* 28 */
1198 BOOL rc;
1199 BOOL old_b;
1200 const UINT vals[]={TRUE,FALSE};
1201 unsigned int i;
1203 trace("testing SPI_{GET,SET}MENUDROPALIGNMENT\n");
1204 SetLastError(0xdeadbeef);
1205 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &old_b, 0 );
1206 if (!test_error_msg(rc,"SPI_{GET,SET}MENUDROPALIGNMENT"))
1207 return;
1209 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1211 UINT v;
1213 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, vals[i], 0,
1214 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1215 if (!test_error_msg(rc,"SPI_SETMENUDROPALIGNMENT")) return;
1216 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1217 test_change_message( SPI_SETMENUDROPALIGNMENT, 0 );
1218 test_reg_key_ex( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1219 SPI_SETMENUDROPALIGNMENT_REGKEY2,
1220 SPI_SETMENUDROPALIGNMENT_VALNAME,
1221 vals[i] ? "1" : "0" );
1223 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &v, 0 );
1224 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1225 eq( v, vals[i], "SPI_{GET,SET}MENUDROPALIGNMENT", "%d" );
1226 eq( GetSystemMetrics( SM_MENUDROPALIGNMENT ), (int)vals[i],
1227 "SM_MENUDROPALIGNMENT", "%d" );
1230 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, old_b, 0,
1231 SPIF_UPDATEINIFILE );
1232 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1235 static void test_SPI_SETDOUBLECLKWIDTH( void ) /* 29 */
1237 BOOL rc;
1238 INT old_width;
1239 const UINT vals[]={0,10000};
1240 unsigned int i;
1242 trace("testing SPI_{GET,SET}DOUBLECLKWIDTH\n");
1243 old_width = GetSystemMetrics( SM_CXDOUBLECLK );
1245 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1247 char buf[10];
1249 SetLastError(0xdeadbeef);
1250 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, vals[i], 0,
1251 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1252 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKWIDTH"))
1253 return;
1255 test_change_message( SPI_SETDOUBLECLKWIDTH, 0 );
1256 sprintf( buf, "%d", vals[i] );
1257 test_reg_key_ex( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1258 SPI_SETDOUBLECLKWIDTH_REGKEY2,
1259 SPI_SETDOUBLECLKWIDTH_VALNAME, buf );
1260 eq( GetSystemMetrics( SM_CXDOUBLECLK ), (int)vals[i],
1261 "SM_CXDOUBLECLK", "%d" );
1264 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, old_width, 0,
1265 SPIF_UPDATEINIFILE );
1266 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1269 static void test_SPI_SETDOUBLECLKHEIGHT( void ) /* 30 */
1271 BOOL rc;
1272 INT old_height;
1273 const UINT vals[]={0,10000};
1274 unsigned int i;
1276 trace("testing SPI_{GET,SET}DOUBLECLKHEIGHT\n");
1277 old_height = GetSystemMetrics( SM_CYDOUBLECLK );
1279 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1281 char buf[10];
1283 SetLastError(0xdeadbeef);
1284 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, vals[i], 0,
1285 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1286 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKHEIGHT"))
1287 return;
1289 test_change_message( SPI_SETDOUBLECLKHEIGHT, 0 );
1290 sprintf( buf, "%d", vals[i] );
1291 test_reg_key_ex( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1292 SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1293 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf );
1294 eq( GetSystemMetrics( SM_CYDOUBLECLK ), (int)vals[i],
1295 "SM_CYDOUBLECLK", "%d" );
1298 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, old_height, 0,
1299 SPIF_UPDATEINIFILE );
1300 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1303 static void test_SPI_SETDOUBLECLICKTIME( void ) /* 32 */
1305 BOOL rc;
1306 UINT curr_val;
1307 UINT saved_val;
1308 UINT old_time;
1309 char buf[10];
1311 trace("testing SPI_{GET,SET}DOUBLECLICKTIME\n");
1312 old_time = GetDoubleClickTime();
1314 curr_val = 0;
1315 SetLastError(0xdeadbeef);
1316 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1317 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1318 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLICKTIME"))
1319 return;
1321 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1322 sprintf( buf, "%d", curr_val );
1323 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1324 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1325 curr_val = 500; /* used value for 0 */
1326 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1328 curr_val = 1000;
1329 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1330 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1331 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1332 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1333 sprintf( buf, "%d", curr_val );
1334 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1335 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1336 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1338 saved_val = curr_val;
1340 curr_val = 0;
1341 SetDoubleClickTime( curr_val );
1342 sprintf( buf, "%d", saved_val );
1343 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1344 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1345 curr_val = 500; /* used value for 0 */
1346 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1348 curr_val = 1000;
1349 SetDoubleClickTime( curr_val );
1350 sprintf( buf, "%d", saved_val );
1351 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1352 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1353 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1355 rc=SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, old_time, 0, SPIF_UPDATEINIFILE);
1356 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1359 static void test_SPI_SETMOUSEBUTTONSWAP( void ) /* 33 */
1361 BOOL rc;
1362 BOOL old_b;
1363 const UINT vals[]={TRUE,FALSE};
1364 unsigned int i;
1366 trace("testing SPI_{GET,SET}MOUSEBUTTONSWAP\n");
1367 old_b = GetSystemMetrics( SM_SWAPBUTTON );
1369 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1371 SetLastError(0xdeadbeef);
1372 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[i], 0,
1373 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1374 if (!test_error_msg(rc,"SPI_SETMOUSEBUTTONSWAP")) return;
1376 test_change_message( SPI_SETMOUSEBUTTONSWAP, 0 );
1377 test_reg_key( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1378 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1379 vals[i] ? "1" : "0" );
1380 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i],
1381 "SM_SWAPBUTTON", "%d" );
1382 rc=SwapMouseButton((BOOL)vals[i^1]);
1383 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i^1],
1384 "SwapMouseButton", "%d" );
1385 ok( rc==(BOOL)vals[i], "SwapMouseButton does not return previous state (really %d)\n", rc );
1388 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, old_b, 0,
1389 SPIF_UPDATEINIFILE );
1390 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1393 static void test_SPI_SETFASTTASKSWITCH( void ) /* 36 */
1395 BOOL rc;
1396 BOOL v;
1398 trace("testing SPI_GETFASTTASKSWITCH\n");
1399 SetLastError(0xdeadbeef);
1400 rc=SystemParametersInfoA( SPI_GETFASTTASKSWITCH, 0, &v, 0 );
1401 if (!test_error_msg(rc,"SPI_{GET,SET}FASTTASKSWITCH"))
1402 return;
1404 /* there is not a single Windows platform on which SPI_GETFASTTASKSWITCH
1405 * works. That sure simplifies testing!
1409 static void test_SPI_SETDRAGFULLWINDOWS( void ) /* 37 */
1411 BOOL rc;
1412 BOOL old_b;
1413 const UINT vals[]={TRUE,FALSE};
1414 unsigned int i;
1416 trace("testing SPI_{GET,SET}DRAGFULLWINDOWS\n");
1417 SetLastError(0xdeadbeef);
1418 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &old_b, 0 );
1420 /* SPI_{GET,SET}DRAGFULLWINDOWS is not implemented on Win95 */
1421 if (!test_error_msg(rc,"SPI_{GET,SET}DRAGFULLWINDOWS"))
1422 return;
1424 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1426 UINT v;
1428 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, vals[i], 0,
1429 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1430 if (!test_error_msg(rc,"SPI_SETDRAGFULLWINDOWS")) return;
1431 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1432 test_change_message( SPI_SETDRAGFULLWINDOWS, 0 );
1433 test_reg_key( SPI_SETDRAGFULLWINDOWS_REGKEY,
1434 SPI_SETDRAGFULLWINDOWS_VALNAME,
1435 vals[i] ? "1" : "0" );
1437 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &v, 0 );
1438 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1439 eq( v, vals[i], "SPI_{GET,SET}DRAGFULLWINDOWS", "%d" );
1442 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, old_b, 0, SPIF_UPDATEINIFILE );
1443 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1446 #define test_reg_metric( KEY, VAL, val) \
1447 { INT regval;\
1448 regval = metricfromreg( KEY, VAL, dpi);\
1449 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1452 #define test_reg_metric2( KEY1, KEY2, VAL, val) \
1453 { INT regval;\
1454 regval = metricfromreg( KEY1, VAL, dpi);\
1455 if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\
1456 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1459 #define test_reg_font( KEY, VAL, LF) \
1460 { LOGFONTA lfreg;\
1461 lffromreg( KEY, VAL, &lfreg);\
1462 ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == MulDiv( lfreg.lfHeight, dpi, real_dpi ) : \
1463 MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\
1464 (LF).lfWidth == lfreg.lfWidth &&\
1465 (LF).lfWeight == lfreg.lfWeight &&\
1466 !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\
1467 , "wrong value \"%s\" in registry %d, %d\n", VAL, (LF).lfHeight, lfreg.lfHeight);\
1470 #define TEST_NONCLIENTMETRICS_REG( ncm) \
1471 /*FIXME: test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);*/\
1472 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\
1473 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\
1474 /*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\
1475 test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\
1476 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\
1477 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\
1478 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\
1479 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\
1480 test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\
1481 test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\
1482 test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\
1483 test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\
1484 test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont);
1486 /* get text metric height value for the specified logfont */
1487 static int get_tmheight( LOGFONTA *plf, int flag)
1489 TEXTMETRICA tm;
1490 HFONT hfont = CreateFontIndirectA( plf);
1491 hfont = SelectObject( hdc, hfont);
1492 GetTextMetricsA( hdc, &tm);
1493 hfont = SelectObject( hdc, hfont);
1494 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1497 static void test_GetSystemMetrics( void);
1498 static UINT smcxsmsize = 999999999;
1500 static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */
1502 BOOL rc;
1503 INT expect;
1504 NONCLIENTMETRICSA Ncmorig;
1505 NONCLIENTMETRICSA Ncmnew;
1506 NONCLIENTMETRICSA Ncmcur;
1507 NONCLIENTMETRICSA Ncmstart;
1509 Ncmorig.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1510 Ncmnew.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1511 Ncmcur.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1512 Ncmstart.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1514 trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n");
1515 change_counter = 0;
1516 SetLastError(0xdeadbeef);
1517 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmorig, FALSE );
1518 if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS"))
1519 return;
1520 Ncmstart = Ncmorig;
1521 smcxsmsize = Ncmstart.iSmCaptionWidth;
1522 /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if
1523 the caption font height is higher than the CaptionHeight field,
1524 the latter is adjusted accordingly. To be able to restore these setting
1525 accurately be restore the raw values. */
1526 Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, real_dpi);
1527 Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi);
1528 Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi);
1529 Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi);
1530 /* test registry entries */
1531 TEST_NONCLIENTMETRICS_REG( Ncmorig)
1532 Ncmorig.lfCaptionFont.lfHeight = MulDiv( Ncmorig.lfCaptionFont.lfHeight, real_dpi, dpi );
1534 /* make small changes */
1535 Ncmnew = Ncmstart;
1536 Ncmnew.iBorderWidth += 1;
1537 Ncmnew.iScrollWidth += 1;
1538 Ncmnew.iScrollHeight -= 1;
1539 Ncmnew.iCaptionWidth -= 2;
1540 Ncmnew.iCaptionHeight += 2;
1541 Ncmnew.lfCaptionFont.lfHeight +=1;
1542 Ncmnew.lfCaptionFont.lfWidth +=2;
1543 Ncmnew.lfCaptionFont.lfWeight +=1;
1544 Ncmnew.iSmCaptionWidth += 1;
1545 Ncmnew.iSmCaptionHeight += 2;
1546 Ncmnew.lfSmCaptionFont.lfHeight +=3;
1547 Ncmnew.lfSmCaptionFont.lfWidth -=1;
1548 Ncmnew.lfSmCaptionFont.lfWeight +=3;
1549 Ncmnew.iMenuWidth += 1;
1550 Ncmnew.iMenuHeight += 2;
1551 Ncmnew.lfMenuFont.lfHeight +=1;
1552 Ncmnew.lfMenuFont.lfWidth +=1;
1553 Ncmnew.lfMenuFont.lfWeight +=2;
1554 Ncmnew.lfStatusFont.lfHeight -=1;
1555 Ncmnew.lfStatusFont.lfWidth -=1;
1556 Ncmnew.lfStatusFont.lfWeight +=3;
1557 Ncmnew.lfMessageFont.lfHeight -=2;
1558 Ncmnew.lfMessageFont.lfWidth -=1;
1559 Ncmnew.lfMessageFont.lfWeight +=4;
1561 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1562 SPIF_SENDCHANGE);
1563 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return;
1564 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1565 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1566 /* get them back */
1567 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1568 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1569 /* test registry entries */
1570 TEST_NONCLIENTMETRICS_REG( Ncmcur)
1571 /* test the system metrics with these settings */
1572 test_GetSystemMetrics();
1573 /* now for something invalid: increase the {menu|caption|smcaption} fonts
1574 by a large amount will increase the {menu|caption|smcaption} height*/
1575 Ncmnew = Ncmstart;
1576 Ncmnew.lfMenuFont.lfHeight -= 8;
1577 Ncmnew.lfCaptionFont.lfHeight =-4;
1578 Ncmnew.lfSmCaptionFont.lfHeight -=10;
1579 /* also show that a few values are lo limited */
1580 Ncmnew.iCaptionWidth = 0;
1581 Ncmnew.iCaptionHeight = 0;
1582 Ncmnew.iScrollHeight = 0;
1583 Ncmnew.iScrollWidth = 0;
1585 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1586 SPIF_SENDCHANGE);
1587 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1588 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1589 /* raw values are in registry */
1590 TEST_NONCLIENTMETRICS_REG( Ncmnew)
1591 /* get them back */
1592 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1593 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1594 /* cooked values are returned */
1595 expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1));
1596 ok( Ncmcur.iMenuHeight == expect,
1597 "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect);
1598 expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0));
1599 ok( Ncmcur.iCaptionHeight == expect,
1600 "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect);
1601 expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0));
1602 ok( Ncmcur.iSmCaptionHeight == expect,
1603 "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect);
1605 /* iCaptionWidth depends on a version, could be 8, 12 (Vista, Win7), 13 */
1606 ok( (Ncmcur.iCaptionWidth >= 8 && Ncmcur.iCaptionWidth <= 13) ||
1607 Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */
1608 "CaptionWidth: %d expected from [8, 13] or %d\n", Ncmcur.iCaptionWidth, Ncmstart.iCaptionWidth);
1609 ok( Ncmcur.iScrollWidth == 8,
1610 "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth);
1611 ok( Ncmcur.iScrollHeight == 8,
1612 "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight);
1613 /* test the system metrics with these settings */
1614 test_GetSystemMetrics();
1615 /* restore */
1616 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA),
1617 &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1618 test_change_message( SPI_SETNONCLIENTMETRICS, 0 );
1619 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1620 /* test the system metrics with these settings */
1621 test_GetSystemMetrics();
1624 static void test_SPI_SETMINIMIZEDMETRICS( void ) /* 44 */
1626 BOOL rc;
1627 INT regval;
1628 MINIMIZEDMETRICS lpMm_orig;
1629 MINIMIZEDMETRICS lpMm_new;
1630 MINIMIZEDMETRICS lpMm_cur;
1632 lpMm_orig.cbSize = sizeof(MINIMIZEDMETRICS);
1633 lpMm_new.cbSize = sizeof(MINIMIZEDMETRICS);
1634 lpMm_cur.cbSize = sizeof(MINIMIZEDMETRICS);
1636 trace("testing SPI_{GET,SET}MINIMIZEDMETRICS\n");
1637 SetLastError(0xdeadbeef);
1638 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_orig, FALSE );
1639 if (!test_error_msg(rc,"SPI_{GET,SET}MINIMIZEDMETRICS"))
1640 return;
1641 /* Test registry. Note that it is perfectly valid for some fields to
1642 * not be set.
1644 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1645 ok( regval == -1 || regval == lpMm_orig.iWidth, "wrong value in registry %d, expected %d\n",
1646 regval, lpMm_orig.iWidth);
1647 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1648 ok( regval == -1 || regval == lpMm_orig.iHorzGap, "wrong value in registry %d, expected %d\n",
1649 regval, lpMm_orig.iHorzGap);
1650 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1651 ok( regval == -1 || regval == lpMm_orig.iVertGap, "wrong value in registry %d, expected %d\n",
1652 regval, lpMm_orig.iVertGap);
1653 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1654 ok( regval == -1 || regval == lpMm_orig.iArrange, "wrong value in registry %d, expected %d\n",
1655 regval, lpMm_orig.iArrange);
1656 /* set some new values */
1657 lpMm_cur.iWidth = 180;
1658 lpMm_cur.iHorzGap = 1;
1659 lpMm_cur.iVertGap = 1;
1660 lpMm_cur.iArrange = 5;
1661 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1662 &lpMm_cur, SPIF_UPDATEINIFILE );
1663 if (!test_error_msg(rc,"SPI_SETMINIMIZEDMETRICS")) return;
1664 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1665 /* read them back */
1666 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1667 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1668 /* and compare */
1669 eq( lpMm_new.iWidth, lpMm_cur.iWidth, "iWidth", "%d" );
1670 eq( lpMm_new.iHorzGap, lpMm_cur.iHorzGap, "iHorzGap", "%d" );
1671 eq( lpMm_new.iVertGap, lpMm_cur.iVertGap, "iVertGap", "%d" );
1672 eq( lpMm_new.iArrange, lpMm_cur.iArrange, "iArrange", "%d" );
1673 /* test registry */
1674 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1675 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1676 regval, lpMm_new.iWidth);
1677 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1678 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1679 regval, lpMm_new.iHorzGap);
1680 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1681 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1682 regval, lpMm_new.iVertGap);
1683 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1684 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1685 regval, lpMm_new.iArrange);
1686 /* test some system metrics */
1687 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1688 lpMm_new.iWidth, "iWidth", "%d" );
1689 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1690 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1691 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1692 lpMm_new.iVertGap, "iVertGap", "%d" );
1693 eq( GetSystemMetrics( SM_ARRANGE ),
1694 lpMm_new.iArrange, "iArrange", "%d" );
1695 /* now some really invalid settings */
1696 lpMm_cur.iWidth = -1;
1697 lpMm_cur.iHorzGap = -1;
1698 lpMm_cur.iVertGap = -1;
1699 lpMm_cur.iArrange = - 1;
1700 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1701 &lpMm_cur, SPIF_UPDATEINIFILE );
1702 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1703 /* read back */
1704 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1705 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1706 /* the width and H/V gaps have minimum 0, arrange is and'd with 0xf */
1707 eq( lpMm_new.iWidth, 0, "iWidth", "%d" );
1708 eq( lpMm_new.iHorzGap, 0, "iHorzGap", "%d" );
1709 eq( lpMm_new.iVertGap, 0, "iVertGap", "%d" );
1710 eq( lpMm_new.iArrange, 0xf & lpMm_cur.iArrange, "iArrange", "%d" );
1711 /* test registry */
1712 if (0)
1714 /* FIXME: cannot understand the results of this (11, 11, 11, 0) */
1715 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1716 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1717 regval, lpMm_new.iWidth);
1718 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1719 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1720 regval, lpMm_new.iHorzGap);
1721 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1722 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1723 regval, lpMm_new.iVertGap);
1724 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1725 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1726 regval, lpMm_new.iArrange);
1728 /* test some system metrics */
1729 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1730 lpMm_new.iWidth, "iWidth", "%d" );
1731 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1732 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1733 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1734 lpMm_new.iVertGap, "iVertGap", "%d" );
1735 eq( GetSystemMetrics( SM_ARRANGE ),
1736 lpMm_new.iArrange, "iArrange", "%d" );
1737 /* restore */
1738 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1739 &lpMm_orig, SPIF_UPDATEINIFILE );
1740 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1741 /* check that */
1742 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1743 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1744 eq( lpMm_new.iWidth, lpMm_orig.iWidth, "iWidth", "%d" );
1745 eq( lpMm_new.iHorzGap, lpMm_orig.iHorzGap, "iHorzGap", "%d" );
1746 eq( lpMm_new.iVertGap, lpMm_orig.iVertGap, "iVertGap", "%d" );
1747 eq( lpMm_new.iArrange, lpMm_orig.iArrange, "iArrange", "%d" );
1750 static void test_SPI_SETICONMETRICS( void ) /* 46 */
1752 BOOL rc, wrap;
1753 INT spacing;
1754 ICONMETRICSA im_orig;
1755 ICONMETRICSA im_new;
1756 ICONMETRICSA im_cur;
1757 INT regval;
1759 im_orig.cbSize = sizeof(ICONMETRICSA);
1760 im_new.cbSize = sizeof(ICONMETRICSA);
1761 im_cur.cbSize = sizeof(ICONMETRICSA);
1763 trace("testing SPI_{GET,SET}ICONMETRICS\n");
1764 SetLastError(0xdeadbeef);
1765 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE );
1766 if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS"))
1767 return;
1768 /* check some registry values */
1769 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1770 ok( regval==im_orig.iHorzSpacing || broken(regval == -1), /* nt4 */
1771 "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing);
1772 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1773 ok( regval==im_orig.iVertSpacing || broken(regval == -1), /* nt4 */
1774 "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing);
1775 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1776 if( regval != im_orig.iTitleWrap)
1777 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1778 ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap);
1780 /* change everything without creating something invalid ( Win9x would ignore
1781 * an invalid font for instance) */
1782 im_cur = im_orig;
1783 im_cur.iHorzSpacing += 10;
1784 im_cur.iVertSpacing += 6;
1785 im_cur.iTitleWrap = !im_cur.iTitleWrap;
1786 im_cur.lfFont.lfHeight += 1;
1787 im_cur.lfFont.lfWidth += 2;
1788 im_cur.lfFont.lfEscapement = 1;
1789 im_cur.lfFont.lfWeight = im_cur.lfFont.lfWeight > 100 ? 1 : 314;
1790 im_cur.lfFont.lfItalic = !im_cur.lfFont.lfItalic;
1791 im_cur.lfFont.lfStrikeOut = !im_cur.lfFont.lfStrikeOut;
1792 im_cur.lfFont.lfUnderline = !im_cur.lfFont.lfUnderline;
1793 im_cur.lfFont.lfCharSet = im_cur.lfFont.lfCharSet ? 0 : 1;
1794 im_cur.lfFont.lfOutPrecision = im_cur.lfFont.lfOutPrecision == OUT_DEFAULT_PRECIS ?
1795 OUT_TT_PRECIS : OUT_DEFAULT_PRECIS;
1796 im_cur.lfFont.lfClipPrecision ^= CLIP_LH_ANGLES;
1797 im_cur.lfFont.lfPitchAndFamily = im_cur.lfFont.lfPitchAndFamily ? 0 : 1;
1798 im_cur.lfFont.lfQuality = im_cur.lfFont.lfQuality == DEFAULT_QUALITY ?
1799 DRAFT_QUALITY : DEFAULT_QUALITY;
1800 if( strcmp( im_cur.lfFont.lfFaceName, "MS Serif"))
1801 strcpy( im_cur.lfFont.lfFaceName, "MS Serif");
1802 else
1803 strcpy( im_cur.lfFont.lfFaceName, "MS Sans Serif");
1805 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, SPIF_UPDATEINIFILE );
1806 if (!test_error_msg(rc,"SPI_SETICONMETRICS")) return;
1807 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1809 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1810 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1811 /* test GET <-> SETICONMETRICS */
1812 eq( im_new.iHorzSpacing, im_cur.iHorzSpacing, "iHorzSpacing", "%d" );
1813 eq( im_new.iVertSpacing, im_cur.iVertSpacing, "iVertSpacing", "%d" );
1814 eq( im_new.iTitleWrap, im_cur.iTitleWrap, "iTitleWrap", "%d" );
1815 eq( im_new.lfFont.lfHeight, im_cur.lfFont.lfHeight, "lfHeight", "%d" );
1816 eq( im_new.lfFont.lfWidth, im_cur.lfFont.lfWidth, "lfWidth", "%d" );
1817 eq( im_new.lfFont.lfEscapement, im_cur.lfFont.lfEscapement, "lfEscapement", "%d" );
1818 eq( im_new.lfFont.lfWeight, im_cur.lfFont.lfWeight, "lfWeight", "%d" );
1819 eq( im_new.lfFont.lfItalic, im_cur.lfFont.lfItalic, "lfItalic", "%d" );
1820 eq( im_new.lfFont.lfStrikeOut, im_cur.lfFont.lfStrikeOut, "lfStrikeOut", "%d" );
1821 eq( im_new.lfFont.lfUnderline, im_cur.lfFont.lfUnderline, "lfUnderline", "%d" );
1822 eq( im_new.lfFont.lfCharSet, im_cur.lfFont.lfCharSet, "lfCharSet", "%d" );
1823 eq( im_new.lfFont.lfOutPrecision, im_cur.lfFont.lfOutPrecision, "lfOutPrecision", "%d" );
1824 eq( im_new.lfFont.lfClipPrecision, im_cur.lfFont.lfClipPrecision, "lfClipPrecision", "%d" );
1825 eq( im_new.lfFont.lfPitchAndFamily, im_cur.lfFont.lfPitchAndFamily, "lfPitchAndFamily", "%d" );
1826 eq( im_new.lfFont.lfQuality, im_cur.lfFont.lfQuality, "lfQuality", "%d" );
1827 ok( !strcmp( im_new.lfFont.lfFaceName, im_cur.lfFont.lfFaceName),
1828 "wrong facename \"%s\", should be \"%s\"\n", im_new.lfFont.lfFaceName,
1829 im_cur.lfFont.lfFaceName);
1830 /* test some system metrics */
1831 eq( GetSystemMetrics( SM_CXICONSPACING ),
1832 im_new.iHorzSpacing, "iHorzSpacing", "%d" );
1833 eq( GetSystemMetrics( SM_CYICONSPACING ),
1834 im_new.iVertSpacing, "iVertSpacing", "%d" );
1835 /* check some registry values */
1836 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1837 ok( regval==im_cur.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iHorzSpacing);
1838 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1839 ok( regval==im_cur.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iVertSpacing);
1840 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1841 if( regval != im_cur.iTitleWrap)
1842 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1843 ok( regval==im_cur.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_cur.iTitleWrap);
1844 /* test some values from other SPI_GETxxx calls */
1845 rc = SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
1846 ok( rc && spacing == im_cur.iHorzSpacing,
1847 "SystemParametersInfoA( SPI_ICONHORIZONTALSPACING...) failed or returns wrong value %d instead of %d\n",
1848 spacing, im_cur.iHorzSpacing);
1849 rc = SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1850 ok( rc && spacing == im_cur.iVertSpacing,
1851 "SystemParametersInfoA( SPI_ICONVERTICALSPACING...) failed or returns wrong value %d instead of %d\n",
1852 spacing, im_cur.iVertSpacing);
1853 rc = SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &wrap, 0 );
1854 ok( rc && wrap == im_cur.iTitleWrap,
1855 "SystemParametersInfoA( SPI_GETICONTITLEWRAP...) failed or returns wrong value %d instead of %d\n",
1856 wrap, im_cur.iTitleWrap);
1857 /* restore old values */
1858 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig,SPIF_UPDATEINIFILE );
1859 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1861 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1862 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1864 eq( im_new.iHorzSpacing, im_orig.iHorzSpacing, "iHorzSpacing", "%d" );
1865 eq( im_new.iVertSpacing, im_orig.iVertSpacing, "iVertSpacing", "%d" );
1866 eq( im_new.iTitleWrap, im_orig.iTitleWrap, "iTitleWrap", "%d" );
1869 static void test_SPI_SETWORKAREA( void ) /* 47 */
1871 BOOL rc;
1872 RECT old_area;
1873 RECT area;
1874 RECT curr_val;
1876 trace("testing SPI_{GET,SET}WORKAREA\n");
1877 SetLastError(0xdeadbeef);
1878 rc=SystemParametersInfoA(SPI_GETWORKAREA, 0, &old_area, 0);
1879 if (!test_error_msg(rc,"SPI_{GET,SET}WORKAREA"))
1880 return;
1882 /* Modify the work area only minimally as this causes the icons that
1883 * fall outside it to be moved around thus requiring the user to
1884 * reposition them manually one by one.
1885 * Changing the work area by just one pixel should make this occurrence
1886 * reasonably unlikely.
1888 SetRect(&curr_val, old_area.left, old_area.top, old_area.right - 1, old_area.bottom - 1);
1889 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &curr_val,
1890 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1891 if (!test_error_msg(rc,"SPI_SETWORKAREA")) return;
1892 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1893 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1894 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1895 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1896 test_change_message( SPI_SETWORKAREA, 0);
1897 eq( area.left, curr_val.left, "left", "%d" );
1898 eq( area.top, curr_val.top, "top", "%d" );
1899 /* size may be rounded */
1900 ok( area.right >= curr_val.right - 16 && area.right < curr_val.right + 16,
1901 "right: got %d instead of %d\n", area.right, curr_val.right );
1902 ok( area.bottom >= curr_val.bottom - 16 && area.bottom < curr_val.bottom + 16,
1903 "bottom: got %d instead of %d\n", area.bottom, curr_val.bottom );
1904 curr_val = area;
1905 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &old_area,
1906 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1907 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1908 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1909 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1910 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1911 test_change_message( SPI_SETWORKAREA, 0 );
1912 eq( area.left, old_area.left, "left", "%d" );
1913 eq( area.top, old_area.top, "top", "%d" );
1914 /* size may be rounded */
1915 ok( area.right >= old_area.right - 16 && area.right < old_area.right + 16,
1916 "right: got %d instead of %d\n", area.right, old_area.right );
1917 ok( area.bottom >= old_area.bottom - 16 && area.bottom < old_area.bottom + 16,
1918 "bottom: got %d instead of %d\n", area.bottom, old_area.bottom );
1921 static void test_SPI_SETSHOWSOUNDS( void ) /* 57 */
1923 BOOL rc;
1924 BOOL old_b;
1925 const UINT vals[]={TRUE,FALSE};
1926 unsigned int i;
1928 trace("testing SPI_{GET,SET}SHOWSOUNDS\n");
1929 SetLastError(0xdeadbeef);
1930 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &old_b, 0 );
1931 /* SPI_{GET,SET}SHOWSOUNDS is completely broken on Win9x */
1932 if (!test_error_msg(rc,"SPI_{GET,SET}SHOWSOUNDS"))
1933 return;
1935 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1937 UINT v;
1939 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0,
1940 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1941 if (!test_error_msg(rc,"SPI_SETSHOWSOUNDS")) return;
1942 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1943 test_change_message( SPI_SETSHOWSOUNDS, 1 );
1944 test_reg_key( SPI_SETSHOWSOUNDS_REGKEY,
1945 SPI_SETSHOWSOUNDS_VALNAME,
1946 vals[i] ? "1" : "0" );
1948 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &v, 0 );
1949 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1950 eq( v, vals[i], "SPI_GETSHOWSOUNDS", "%d" );
1951 eq( GetSystemMetrics( SM_SHOWSOUNDS ), (int)vals[i],
1952 "SM_SHOWSOUNDS", "%d" );
1955 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, old_b, 0, SPIF_UPDATEINIFILE );
1956 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1959 static void test_SPI_SETKEYBOARDPREF( void ) /* 69 */
1961 BOOL rc;
1962 BOOL old_b;
1963 const UINT vals[]={TRUE,FALSE};
1964 unsigned int i;
1966 trace("testing SPI_{GET,SET}KEYBOARDPREF\n");
1967 SetLastError(0xdeadbeef);
1968 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &old_b, 0 );
1969 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDPREF"))
1970 return;
1972 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1974 BOOL v;
1976 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0,
1977 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1978 if (!test_error_msg(rc,"SPI_SETKEYBOARDPREF")) return;
1979 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1980 test_change_message( SPI_SETKEYBOARDPREF, 1 );
1981 test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY,
1982 SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY,
1983 vals[i] ? "1" : "0" );
1985 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &v, 0 );
1986 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1987 eq( v, (BOOL)vals[i], "SPI_GETKEYBOARDPREF", "%d" );
1990 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, old_b, 0, SPIF_UPDATEINIFILE );
1991 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1994 static void test_SPI_SETSCREENREADER( void ) /* 71 */
1996 BOOL rc;
1997 BOOL old_b;
1998 const UINT vals[]={TRUE,FALSE};
1999 unsigned int i;
2001 trace("testing SPI_{GET,SET}SCREENREADER\n");
2002 SetLastError(0xdeadbeef);
2003 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &old_b, 0 );
2004 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENREADER"))
2005 return;
2007 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2009 BOOL v;
2011 rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0,
2012 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2013 if (!test_error_msg(rc,"SPI_SETSCREENREADER")) return;
2014 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2015 test_change_message( SPI_SETSCREENREADER, 1 );
2016 test_reg_key_ex2_optional( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY,
2017 SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY,
2018 vals[i] ? "1" : "0" );
2020 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &v, 0 );
2021 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2022 eq( v, (BOOL)vals[i], "SPI_GETSCREENREADER", "%d" );
2025 rc=SystemParametersInfoA( SPI_SETSCREENREADER, old_b, 0, SPIF_UPDATEINIFILE );
2026 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2029 static void test_SPI_SETFONTSMOOTHING( void ) /* 75 */
2031 BOOL rc;
2032 BOOL old_b;
2033 DWORD old_type, old_contrast, old_orient;
2034 const UINT vals[]={0xffffffff,0,1,2};
2035 unsigned int i;
2037 trace("testing SPI_{GET,SET}FONTSMOOTHING\n");
2038 if( iswin9x) return; /* 95/98/ME don't seem to implement this fully */
2039 SetLastError(0xdeadbeef);
2040 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &old_b, 0 );
2041 if (!test_error_msg(rc,"SPI_{GET,SET}FONTSMOOTHING"))
2042 return;
2043 SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &old_type, 0 );
2044 SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &old_contrast, 0 );
2045 SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &old_orient, 0 );
2047 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2049 UINT v;
2051 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, vals[i], 0,
2052 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2053 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHING")) return;
2054 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2055 test_change_message( SPI_SETFONTSMOOTHING, 0 );
2056 test_reg_key( SPI_SETFONTSMOOTHING_REGKEY,
2057 SPI_SETFONTSMOOTHING_VALNAME,
2058 vals[i] ? "2" : "0" );
2060 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, 0, UlongToPtr(vals[i]),
2061 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2062 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGTYPE")) return;
2063 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2064 test_change_message( SPI_SETFONTSMOOTHINGTYPE, 0 );
2065 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2066 SPI_SETFONTSMOOTHINGTYPE_VALNAME, &vals[i] );
2068 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, 0, UlongToPtr(vals[i]),
2069 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2070 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGCONTRAST")) return;
2071 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2072 test_change_message( SPI_SETFONTSMOOTHINGCONTRAST, 0 );
2073 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2074 SPI_SETFONTSMOOTHINGCONTRAST_VALNAME, &vals[i] );
2076 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, 0, UlongToPtr(vals[i]),
2077 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2078 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGORIENTATION")) return;
2079 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2080 test_change_message( SPI_SETFONTSMOOTHINGORIENTATION, 0 );
2081 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2082 SPI_SETFONTSMOOTHINGORIENTATION_VALNAME, &vals[i] );
2084 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &v, 0 );
2085 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2086 eq( v, vals[i] ? 1 : 0, "SPI_GETFONTSMOOTHING", "%d" );
2088 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &v, 0 );
2089 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2090 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2092 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &v, 0 );
2093 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2094 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2096 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &v, 0 );
2097 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2098 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2101 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, old_b, 0, SPIF_UPDATEINIFILE );
2102 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2103 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, old_type, 0, SPIF_UPDATEINIFILE );
2104 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2105 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, old_contrast, 0, SPIF_UPDATEINIFILE );
2106 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2107 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, old_orient, 0, SPIF_UPDATEINIFILE );
2108 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2111 static void test_SPI_SETLOWPOWERACTIVE( void ) /* 85 */
2113 BOOL rc;
2114 BOOL old_b;
2115 const UINT vals[]={TRUE,FALSE};
2116 unsigned int i;
2118 trace("testing SPI_{GET,SET}LOWPOWERACTIVE\n");
2119 SetLastError(0xdeadbeef);
2120 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &old_b, 0 );
2121 if (!test_error_msg(rc,"SPI_{GET,SET}LOWPOWERACTIVE"))
2122 return;
2124 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2126 UINT v;
2128 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0,
2129 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2130 if (!test_error_msg(rc,"SPI_SETLOWPOWERACTIVE")) return;
2131 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2132 test_change_message( SPI_SETLOWPOWERACTIVE, 1 );
2133 test_reg_key_optional( SPI_SETLOWPOWERACTIVE_REGKEY,
2134 SPI_SETLOWPOWERACTIVE_VALNAME,
2135 vals[i] ? "1" : "0" );
2137 /* SPI_SETLOWPOWERACTIVE is not persistent in win2k3 and above */
2138 v = 0xdeadbeef;
2139 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 );
2140 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2141 ok(v == vals[i] ||
2142 broken(v == (0xdead0000 | vals[i])) || /* win98 only sets the low word */
2143 v == 0, /* win2k3 */
2144 "SPI_GETLOWPOWERACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2147 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2148 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2151 static void test_SPI_SETPOWEROFFACTIVE( void ) /* 86 */
2153 BOOL rc;
2154 BOOL old_b;
2155 const UINT vals[]={TRUE,FALSE};
2156 unsigned int i;
2158 trace("testing SPI_{GET,SET}POWEROFFACTIVE\n");
2159 SetLastError(0xdeadbeef);
2160 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &old_b, 0 );
2161 if (!test_error_msg(rc,"SPI_{GET,SET}POWEROFFACTIVE"))
2162 return;
2164 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2166 UINT v;
2168 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0,
2169 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2170 if (!test_error_msg(rc,"SPI_SETPOWEROFFACTIVE")) return;
2171 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2172 test_change_message( SPI_SETPOWEROFFACTIVE, 1 );
2173 test_reg_key_optional( SPI_SETPOWEROFFACTIVE_REGKEY,
2174 SPI_SETPOWEROFFACTIVE_VALNAME,
2175 vals[i] ? "1" : "0" );
2177 /* SPI_SETPOWEROFFACTIVE is not persistent in win2k3 and above */
2178 v = 0xdeadbeef;
2179 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 );
2180 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2181 ok(v == vals[i] ||
2182 broken(v == (0xdead0000 | vals[i])) || /* win98 only sets the low word */
2183 v == 0, /* win2k3 */
2184 "SPI_GETPOWEROFFACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2187 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2188 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2191 static void test_SPI_SETSNAPTODEFBUTTON( void ) /* 95 */
2193 BOOL rc;
2194 BOOL old_b;
2195 const UINT vals[]={TRUE,FALSE};
2196 unsigned int i;
2198 trace("testing SPI_{GET,SET}SNAPTODEFBUTTON\n");
2199 SetLastError(0xdeadbeef);
2200 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &old_b, 0 );
2201 if (!test_error_msg(rc,"SPI_GETSNAPTODEFBUTTON"))
2202 return;
2204 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2206 UINT v;
2208 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, vals[i], 0,
2209 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2210 if (!test_error_msg(rc,"SPI_SETSNAPTODEFBUTTON")) return;
2211 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2212 test_change_message( SPI_SETSNAPTODEFBUTTON, 0 );
2213 test_reg_key_optional( SPI_SETSNAPTODEFBUTTON_REGKEY,
2214 SPI_SETSNAPTODEFBUTTON_VALNAME,
2215 vals[i] ? "1" : "0" );
2217 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &v, 0 );
2218 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2219 eq( v, vals[i], "SPI_GETSNAPTODEFBUTTON", "%d" );
2222 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, old_b, 0, SPIF_UPDATEINIFILE );
2223 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2226 static void test_SPI_SETMOUSEHOVERWIDTH( void ) /* 99 */
2228 BOOL rc;
2229 UINT old_width;
2230 const UINT vals[]={0,32767};
2231 unsigned int i;
2233 trace("testing SPI_{GET,SET}MOUSEHOVERWIDTH\n");
2234 SetLastError(0xdeadbeef);
2235 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &old_width, 0 );
2236 /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2237 * what MSDN states (Verified on Win98SE)
2239 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERWIDTH"))
2240 return;
2242 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2244 UINT v;
2245 char buf[10];
2247 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, vals[i], 0,
2248 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2249 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERWIDTH")) return;
2250 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2251 test_change_message( SPI_SETMOUSEHOVERWIDTH, 0 );
2252 sprintf( buf, "%d", vals[i] );
2253 test_reg_key( SPI_SETMOUSEHOVERWIDTH_REGKEY,
2254 SPI_SETMOUSEHOVERWIDTH_VALNAME, buf );
2256 SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &v, 0 );
2257 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2258 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERWIDTH", "%d" );
2261 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, old_width, 0,
2262 SPIF_UPDATEINIFILE );
2263 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2266 static void test_SPI_SETMOUSEHOVERHEIGHT( void ) /* 101 */
2268 BOOL rc;
2269 UINT old_height;
2270 const UINT vals[]={0,32767};
2271 unsigned int i;
2273 trace("testing SPI_{GET,SET}MOUSEHOVERHEIGHT\n");
2274 SetLastError(0xdeadbeef);
2275 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &old_height, 0 );
2276 /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2277 * what MSDN states (Verified on Win98SE)
2279 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERHEIGHT"))
2280 return;
2282 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2284 UINT v;
2285 char buf[10];
2287 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, vals[i], 0,
2288 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2289 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERHEIGHT")) return;
2290 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2291 test_change_message( SPI_SETMOUSEHOVERHEIGHT, 0 );
2292 sprintf( buf, "%d", vals[i] );
2293 test_reg_key( SPI_SETMOUSEHOVERHEIGHT_REGKEY,
2294 SPI_SETMOUSEHOVERHEIGHT_VALNAME, buf );
2296 SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &v, 0 );
2297 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2298 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERHEIGHT", "%d" );
2301 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, old_height, 0,
2302 SPIF_UPDATEINIFILE );
2303 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2306 static void test_SPI_SETMOUSEHOVERTIME( void ) /* 103 */
2308 BOOL rc;
2309 UINT old_time;
2311 /* Windows XP accepts 10 as the minimum hover time. Any value below will be
2312 * defaulted to a value of 10 automatically.
2314 const UINT vals[]={10,32767};
2315 unsigned int i;
2317 trace("testing SPI_{GET,SET}MOUSEHOVERTIME\n");
2318 SetLastError(0xdeadbeef);
2319 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &old_time, 0 );
2320 /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2321 * what MSDN states (Verified on Win98SE)
2323 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERTIME"))
2324 return;
2326 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2328 UINT v;
2329 char buf[10];
2331 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, vals[i], 0,
2332 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2333 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERTIME")) return;
2334 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2335 test_change_message( SPI_SETMOUSEHOVERTIME, 0 );
2336 sprintf( buf, "%d", vals[i] );
2337 test_reg_key( SPI_SETMOUSEHOVERTIME_REGKEY,
2338 SPI_SETMOUSEHOVERTIME_VALNAME, buf );
2340 SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &v, 0 );
2341 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2342 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERTIME", "%d" );
2345 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, old_time, 0,
2346 SPIF_UPDATEINIFILE );
2347 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2350 static void test_SPI_SETWHEELSCROLLLINES( void ) /* 105 */
2352 BOOL rc;
2353 UINT old_lines;
2354 const UINT vals[]={0,32767};
2355 unsigned int i;
2357 trace("testing SPI_{GET,SET}WHEELSCROLLLINES\n");
2358 SetLastError(0xdeadbeef);
2359 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &old_lines, 0 );
2361 /* SPI_{GET,SET}WHEELSCROLLLINES not supported on Windows 95 */
2362 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLLINES"))
2363 return;
2365 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2367 UINT v;
2368 char buf[10];
2370 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, vals[i], 0,
2371 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2372 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLLINES")) return;
2373 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2374 test_change_message( SPI_SETWHEELSCROLLLINES, 0 );
2375 sprintf( buf, "%d", vals[i] );
2376 test_reg_key( SPI_SETMOUSESCROLLLINES_REGKEY,
2377 SPI_SETMOUSESCROLLLINES_VALNAME, buf );
2379 SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &v, 0 );
2380 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2381 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLLINES", "%d" );
2384 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, old_lines, 0,
2385 SPIF_UPDATEINIFILE );
2386 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2389 static void test_SPI_SETMENUSHOWDELAY( void ) /* 107 */
2391 BOOL rc;
2392 UINT old_delay;
2393 const UINT vals[]={0,32767};
2394 unsigned int i;
2396 trace("testing SPI_{GET,SET}MENUSHOWDELAY\n");
2397 SetLastError(0xdeadbeef);
2398 rc=SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &old_delay, 0 );
2400 /* SPI_{GET,SET}MENUSHOWDELAY not supported on Windows 95 */
2401 if (!test_error_msg(rc,"SPI_{GET,SET}MENUSHOWDELAY"))
2402 return;
2404 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2406 UINT v;
2407 char buf[10];
2409 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, vals[i], 0,
2410 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2411 if (!test_error_msg(rc,"SPI_SETMENUSHOWDELAY")) return;
2412 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2413 test_change_message( SPI_SETMENUSHOWDELAY, 0 );
2414 sprintf( buf, "%d", vals[i] );
2415 test_reg_key( SPI_SETMENUSHOWDELAY_REGKEY,
2416 SPI_SETMENUSHOWDELAY_VALNAME, buf );
2418 SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &v, 0 );
2419 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2420 eq( v, vals[i], "SPI_{GET,SET}MENUSHOWDELAY", "%d" );
2423 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, old_delay, 0,
2424 SPIF_UPDATEINIFILE );
2425 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2428 static void test_SPI_SETWHEELSCROLLCHARS( void ) /* 108 */
2430 BOOL rc;
2431 UINT old_chars;
2432 const UINT vals[]={32767,0};
2433 unsigned int i;
2435 trace("testing SPI_{GET,SET}WHEELSCROLLCHARS\n");
2436 SetLastError(0xdeadbeef);
2437 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &old_chars, 0 );
2439 /* SPI_{GET,SET}WHEELSCROLLCHARS not supported on Windows 95 */
2440 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLCHARS"))
2441 return;
2443 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2445 UINT v;
2446 char buf[10];
2448 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, vals[i], 0,
2449 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2450 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLCHARS")) return;
2451 test_change_message( SPI_SETWHEELSCROLLCHARS, 0 );
2452 sprintf( buf, "%d", vals[i] );
2453 test_reg_key( SPI_SETMOUSESCROLLCHARS_REGKEY,
2454 SPI_SETMOUSESCROLLCHARS_VALNAME, buf );
2456 SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &v, 0 );
2457 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2458 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLCHARS", "%d" );
2461 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, old_chars, 0,
2462 SPIF_UPDATEINIFILE );
2463 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2466 static void test_SPI_SETWALLPAPER( void ) /* 115 */
2468 BOOL rc;
2469 char oldval[260];
2470 char newval[260];
2472 trace("testing SPI_{GET,SET}DESKWALLPAPER\n");
2473 SetLastError(0xdeadbeef);
2474 rc=SystemParametersInfoA(SPI_GETDESKWALLPAPER, 260, oldval, 0);
2475 /* SPI_{GET,SET}DESKWALLPAPER is completely broken on Win9x and
2476 * unimplemented on NT4
2478 if (!test_error_msg(rc,"SPI_{GET,SET}DESKWALLPAPER"))
2479 return;
2481 strcpy(newval, "");
2482 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, newval, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
2483 if (!test_error_msg(rc,"SPI_SETDESKWALLPAPER")) return;
2484 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
2485 test_change_message(SPI_SETDESKWALLPAPER, 0);
2487 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, oldval, SPIF_UPDATEINIFILE);
2488 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2490 test_reg_key(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, oldval);
2493 static void test_WM_DISPLAYCHANGE(void)
2495 DEVMODEA mode, startmode;
2496 int start_bpp, last_set_bpp = 0;
2497 int test_bpps[] = {8, 16, 24, 32}, i;
2498 LONG change_ret;
2499 DWORD wait_ret;
2501 if (!pChangeDisplaySettingsExA)
2503 win_skip("ChangeDisplaySettingsExA is not available\n");
2504 return;
2507 displaychange_test_active = TRUE;
2509 memset(&startmode, 0, sizeof(startmode));
2510 startmode.dmSize = sizeof(startmode);
2511 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &startmode);
2512 start_bpp = startmode.dmBitsPerPel;
2514 displaychange_sem = CreateSemaphoreW(NULL, 0, 1, NULL);
2516 for(i = 0; i < sizeof(test_bpps)/sizeof(test_bpps[0]); i++) {
2517 last_bpp = -1;
2519 memset(&mode, 0, sizeof(mode));
2520 mode.dmSize = sizeof(mode);
2521 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2522 mode.dmBitsPerPel = test_bpps[i];
2523 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2524 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2526 change_counter = 0; /* This sends a SETTINGSCHANGE message as well in which we aren't interested */
2527 displaychange_ok = TRUE;
2528 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2529 /* Wait quite long for the message, screen setting changes can take some time */
2530 if(change_ret == DISP_CHANGE_SUCCESSFUL) {
2531 wait_ret = WaitForSingleObject(displaychange_sem, 10000);
2532 /* we may not get a notification if nothing changed */
2533 if (wait_ret == WAIT_TIMEOUT && !last_set_bpp && start_bpp == test_bpps[i])
2534 continue;
2535 ok(wait_ret == WAIT_OBJECT_0, "Waiting for the WM_DISPLAYCHANGE message timed out\n");
2537 displaychange_ok = FALSE;
2539 if(change_ret != DISP_CHANGE_SUCCESSFUL) {
2540 skip("Setting depth %d failed(ret = %d)\n", test_bpps[i], change_ret);
2541 ok(last_bpp == -1, "WM_DISPLAYCHANGE was sent with wParam %d despite mode change failure\n", last_bpp);
2542 continue;
2545 todo_wine_if(start_bpp != test_bpps[i]) {
2546 ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
2548 last_set_bpp = test_bpps[i];
2551 if(start_bpp != last_set_bpp && last_set_bpp != 0) {
2552 memset(&mode, 0, sizeof(mode));
2553 mode.dmSize = sizeof(mode);
2554 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2555 mode.dmBitsPerPel = start_bpp;
2556 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2557 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2559 displaychange_ok = TRUE;
2560 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2561 WaitForSingleObject(displaychange_sem, 10000);
2562 displaychange_ok = FALSE;
2563 CloseHandle(displaychange_sem);
2564 displaychange_sem = 0;
2567 displaychange_test_active = FALSE;
2571 * Registry entries for the system parameters.
2572 * Names are created by 'SET' flags names.
2573 * We assume that corresponding 'GET' entries use the same registry keys.
2575 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
2577 test_SPI_SETBEEP(); /* 1 */
2578 test_SPI_SETMOUSE(); /* 4 */
2579 test_SPI_SETBORDER(); /* 6 */
2580 test_SPI_SETKEYBOARDSPEED(); /* 10 */
2581 test_SPI_ICONHORIZONTALSPACING(); /* 13 */
2582 test_SPI_SETSCREENSAVETIMEOUT(); /* 14 */
2583 test_SPI_SETSCREENSAVEACTIVE(); /* 17 */
2584 test_SPI_SETGRIDGRANULARITY(); /* 19 */
2585 test_SPI_SETKEYBOARDDELAY(); /* 23 */
2586 test_SPI_ICONVERTICALSPACING(); /* 24 */
2587 test_SPI_SETICONTITLEWRAP(); /* 26 */
2588 test_SPI_SETMENUDROPALIGNMENT(); /* 28 */
2589 test_SPI_SETDOUBLECLKWIDTH(); /* 29 */
2590 test_SPI_SETDOUBLECLKHEIGHT(); /* 30 */
2591 test_SPI_SETDOUBLECLICKTIME(); /* 32 */
2592 test_SPI_SETMOUSEBUTTONSWAP(); /* 33 */
2593 test_SPI_SETFASTTASKSWITCH(); /* 36 */
2594 test_SPI_SETDRAGFULLWINDOWS(); /* 37 */
2595 /* test_WM_DISPLAYCHANGE seems to be somewhat buggy on
2596 * some versions of Windows (Vista, Win2k8, Win7B) in that
2597 * not all metrics are properly restored. Problems are
2598 * SM_CXMAXTRACK, SM_CYMAXTRACK
2599 * Fortunately setting the Non-Client metrics like in
2600 * test_SPI_SETNONCLIENTMETRICS will correct this. That is why
2601 * we do the DISPLAY change now... */
2602 test_WM_DISPLAYCHANGE();
2603 test_SPI_SETNONCLIENTMETRICS(); /* 42 */
2604 test_SPI_SETMINIMIZEDMETRICS(); /* 44 */
2605 test_SPI_SETICONMETRICS(); /* 46 */
2606 test_SPI_SETWORKAREA(); /* 47 */
2607 test_SPI_SETSHOWSOUNDS(); /* 57 */
2608 test_SPI_SETKEYBOARDPREF(); /* 69 */
2609 test_SPI_SETSCREENREADER(); /* 71 */
2610 test_SPI_SETFONTSMOOTHING(); /* 75 */
2611 test_SPI_SETLOWPOWERACTIVE(); /* 85 */
2612 test_SPI_SETPOWEROFFACTIVE(); /* 86 */
2613 test_SPI_SETSNAPTODEFBUTTON(); /* 95 */
2614 test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */
2615 test_SPI_SETMOUSEHOVERHEIGHT(); /* 101 */
2616 test_SPI_SETMOUSEHOVERTIME(); /* 103 */
2617 test_SPI_SETWHEELSCROLLLINES(); /* 105 */
2618 test_SPI_SETMENUSHOWDELAY(); /* 107 */
2619 test_SPI_SETWHEELSCROLLCHARS(); /* 108 */
2620 test_SPI_SETWALLPAPER(); /* 115 */
2623 SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
2624 return 0;
2627 /* test calculation of GetSystemMetrics values (mostly) from non client metrics,
2628 * icon metrics and minimized metrics.
2631 /* copied from wine's GdiGetCharDimensions, which is not available on most
2632 * windows versions */
2633 static LONG _GdiGetCharDimensions(HDC hdc, LPTEXTMETRICA lptm, LONG *height)
2635 SIZE sz;
2636 static const CHAR alphabet[] = {
2637 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
2638 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
2639 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
2641 if(lptm && !GetTextMetricsA(hdc, lptm)) return 0;
2643 if(!GetTextExtentPointA(hdc, alphabet, 52, &sz)) return 0;
2645 if (height) *height = sz.cy;
2646 return (sz.cx / 26 + 1) / 2;
2649 /* get text metrics and/or "average" char width of the specified logfont
2650 * for the specified dc */
2651 static void get_text_metr_size( HDC hdc, LOGFONTA *plf, TEXTMETRICA * ptm, UINT *psz)
2653 HFONT hfont, hfontsav;
2654 TEXTMETRICA tm;
2655 if( !ptm) ptm = &tm;
2656 hfont = CreateFontIndirectA( plf);
2657 if( !hfont || ( hfontsav = SelectObject( hdc, hfont)) == NULL ) {
2658 ptm->tmHeight = -1;
2659 if( psz) *psz = 10;
2660 if( hfont) DeleteObject( hfont);
2661 return;
2663 GetTextMetricsA( hdc, ptm);
2664 if( psz)
2665 if( !(*psz = _GdiGetCharDimensions( hdc, ptm, NULL)))
2666 *psz = 10;
2667 SelectObject( hdc, hfontsav);
2668 DeleteObject( hfont);
2671 static int gsm_error_ctr;
2673 #define ok_gsm( i, e)\
2675 int exp = (e);\
2676 int act = GetSystemMetrics( (i));\
2677 if( exp != act) gsm_error_ctr++;\
2678 ok( !( exp != act),"GetSystemMetrics(%s): expected %d actual %d\n", #i, exp,act);\
2680 #define ok_gsm_2( i, e1, e2)\
2682 int exp1 = (e1);\
2683 int exp2 = (e2);\
2684 int act = GetSystemMetrics( (i));\
2685 if( exp1 != act && exp2 != act) gsm_error_ctr++;\
2686 ok( !( exp1 != act && exp2 != act), "GetSystemMetrics(%s): expected %d or %d actual %d\n", #i, exp1, exp2, act);\
2688 #define ok_gsm_3( i, e1, e2, e3)\
2690 int exp1 = (e1);\
2691 int exp2 = (e2);\
2692 int exp3 = (e3);\
2693 int act = GetSystemMetrics( (i));\
2694 if( exp1 != act && exp2 != act && exp3 != act) gsm_error_ctr++;\
2695 ok( !( exp1 != act && exp2 != act && exp3 != act),"GetSystemMetrics(%s): expected %d or %d or %d actual %d\n", #i, exp1, exp2, exp3, act);\
2698 static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
2700 return lstrcmpiA(elf->lfFaceName, (const char *)lparam);
2703 static BOOL is_font_enumerated(const char *name)
2705 HDC hdc = CreateCompatibleDC(0);
2706 BOOL ret = FALSE;
2708 if (!EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)name))
2709 ret = TRUE;
2711 DeleteDC(hdc);
2712 return ret;
2715 static int get_cursor_size( int size )
2717 /* only certain sizes are allowed for cursors */
2718 if (size >= 64) return 64;
2719 if (size >= 48) return 48;
2720 return 32;
2723 static void test_GetSystemMetrics( void)
2725 TEXTMETRICA tmMenuFont;
2726 UINT IconSpacing, IconVerticalSpacing;
2727 BOOL rc;
2729 HDC hdc = CreateICA( "Display", 0, 0, 0);
2730 UINT avcwCaption;
2731 INT CaptionWidthfromreg, smicon, broken_val;
2732 MINIMIZEDMETRICS minim;
2733 NONCLIENTMETRICSA ncm;
2734 SIZE screen;
2736 assert(sizeof(ncm) == 344);
2738 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2739 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2740 ok(rc, "SystemParametersInfoA failed\n");
2742 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) - 1;
2743 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2744 ok(!rc, "SystemParametersInfoA should fail\n");
2746 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) + 1;
2747 SetLastError(0xdeadbeef);
2748 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2749 ok(!rc, "SystemParametersInfoA should fail\n");
2751 ncm.cbSize = sizeof(ncm); /* Vista added padding */
2752 SetLastError(0xdeadbeef);
2753 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2754 ok(rc || broken(!rc) /* before Vista */, "SystemParametersInfoA failed\n");
2756 minim.cbSize = sizeof( minim);
2757 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2758 SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0);
2759 rc = SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2760 if( !rc) {
2761 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
2762 return;
2765 ok(is_font_enumerated(ncm.lfCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfCaptionFont.lfFaceName);
2766 ok(is_font_enumerated(ncm.lfSmCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfSmCaptionFont.lfFaceName);
2767 ok(is_font_enumerated(ncm.lfMenuFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMenuFont.lfFaceName);
2768 ok(is_font_enumerated(ncm.lfStatusFont.lfFaceName), "font %s should be enumerated\n", ncm.lfStatusFont.lfFaceName);
2769 ok(is_font_enumerated(ncm.lfMessageFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMessageFont.lfFaceName);
2771 /* CaptionWidth from the registry may have different value of iCaptionWidth
2772 * from the non client metrics (observed on WinXP) */
2773 CaptionWidthfromreg = metricfromreg(
2774 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
2775 get_text_metr_size( hdc, &ncm.lfMenuFont, &tmMenuFont, NULL);
2776 get_text_metr_size( hdc, &ncm.lfCaptionFont, NULL, &avcwCaption);
2777 /* FIXME: use icon metric */
2778 if( !SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &IconVerticalSpacing, 0))
2779 IconVerticalSpacing = 0;
2780 if( !SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &IconSpacing, 0 ))
2781 IconSpacing = 0;
2782 /* reset error counters */
2783 gsm_error_ctr = 0;
2785 /* the tests: */
2787 /* SM_CXSCREEN, cannot test these two */
2788 /* SM_CYSCREEN */
2789 ok_gsm( SM_CXVSCROLL, ncm.iScrollWidth);
2790 ok_gsm( SM_CYHSCROLL, ncm.iScrollWidth);
2791 ok_gsm( SM_CYCAPTION, ncm.iCaptionHeight+1);
2792 ok_gsm( SM_CXBORDER, 1);
2793 ok_gsm( SM_CYBORDER, 1);
2794 ok_gsm( SM_CXDLGFRAME, 3);
2795 ok_gsm( SM_CYDLGFRAME, 3);
2796 ok_gsm( SM_CYVTHUMB, ncm.iScrollHeight);
2797 ok_gsm( SM_CXHTHUMB, ncm.iScrollHeight);
2798 /* These don't depend on the Shell Icon Size registry value */
2799 ok_gsm( SM_CXICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2800 ok_gsm( SM_CYICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2801 ok_gsm( SM_CXCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2802 ok_gsm( SM_CYCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2803 ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1);
2804 ok_gsm( SM_CXFULLSCREEN,
2805 GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME));
2806 ok_gsm( SM_CYFULLSCREEN,
2807 GetSystemMetrics( SM_CYMAXIMIZED) - GetSystemMetrics( SM_CYMIN));
2808 /* SM_CYKANJIWINDOW */
2809 /* SM_MOUSEPRESENT */
2810 ok_gsm( SM_CYVSCROLL, ncm.iScrollHeight);
2811 ok_gsm( SM_CXHSCROLL, ncm.iScrollHeight);
2812 /* SM_DEBUG */
2813 /* SM_SWAPBUTTON */
2814 /* SM_RESERVED1 */
2815 /* SM_RESERVED2 */
2816 /* SM_RESERVED3 */
2817 /* SM_RESERVED4 */
2818 ok_gsm( SM_CXMIN, 3 * max( CaptionWidthfromreg >= 0 ? CaptionWidthfromreg : ncm.iCaptionWidth, 8) +
2819 GetSystemMetrics( SM_CYSIZE) + 4 + 4 * avcwCaption + 2 * GetSystemMetrics( SM_CXFRAME));
2820 ok_gsm( SM_CYMIN, GetSystemMetrics( SM_CYCAPTION) +
2821 2 * GetSystemMetrics( SM_CYFRAME));
2822 ok_gsm_2( SM_CXSIZE,
2823 ncm.iCaptionWidth, /* classic/standard windows style */
2824 GetSystemMetrics( SM_CYCAPTION) - 1 /* WinXP style */
2826 ok_gsm( SM_CYSIZE, ncm.iCaptionHeight);
2827 ok_gsm( SM_CXFRAME, ncm.iBorderWidth + 3);
2828 ok_gsm( SM_CYFRAME, ncm.iBorderWidth + 3);
2829 ok_gsm( SM_CXMINTRACK, GetSystemMetrics( SM_CXMIN));
2830 ok_gsm( SM_CYMINTRACK, GetSystemMetrics( SM_CYMIN));
2831 /* SM_CXDOUBLECLK */
2832 /* SM_CYDOUBLECLK */
2833 if( IconSpacing) ok_gsm( SM_CXICONSPACING, IconSpacing);
2834 if( IconVerticalSpacing) ok_gsm( SM_CYICONSPACING, IconVerticalSpacing);
2835 /* SM_MENUDROPALIGNMENT */
2836 /* SM_PENWINDOWS */
2837 /* SM_DBCSENABLED */
2838 /* SM_CMOUSEBUTTONS */
2839 /* SM_SECURE */
2840 ok_gsm( SM_CXEDGE, 2);
2841 ok_gsm( SM_CYEDGE, 2);
2842 /* sign-extension for iHorzGap/iVertGap is broken on Win9x */
2843 ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + (short)minim.iHorzGap );
2844 ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + (short)minim.iVertGap );
2846 smicon = MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI );
2847 if (!pIsProcessDPIAware || pIsProcessDPIAware())
2848 smicon = max( min( smicon, CaptionWidthfromreg - 2), 4 ) & ~1;
2849 todo_wine_if( real_dpi == dpi && smicon != (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI) & ~1) )
2851 broken_val = (min( ncm.iCaptionHeight, CaptionWidthfromreg ) - 2) & ~1;
2852 broken_val = min( broken_val, 20 );
2854 if (smicon == 4)
2856 ok_gsm_2( SM_CXSMICON, smicon, 6 );
2857 ok_gsm_2( SM_CYSMICON, smicon, 6 );
2859 else if (smicon < broken_val)
2861 ok_gsm_2( SM_CXSMICON, smicon, broken_val );
2862 ok_gsm_2( SM_CYSMICON, smicon, broken_val );
2864 else
2866 ok_gsm( SM_CXSMICON, smicon );
2867 ok_gsm( SM_CYSMICON, smicon );
2871 ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1);
2872 ok_gsm_3( SM_CXSMSIZE,
2873 ncm.iSmCaptionWidth, /* classic/standard windows style */
2874 GetSystemMetrics( SM_CYSMCAPTION) - 1, /* WinXP style */
2875 smcxsmsize /* winXP seems to cache this value: setnonclientmetric
2876 does not change it */
2878 ok_gsm( SM_CYSMSIZE, GetSystemMetrics( SM_CYSMCAPTION) - 1);
2879 ok_gsm( SM_CXMENUSIZE, ncm.iMenuWidth);
2880 ok_gsm( SM_CYMENUSIZE, ncm.iMenuHeight);
2881 /* SM_ARRANGE */
2882 ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6);
2883 ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5);
2884 screen.cx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
2885 screen.cy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
2886 if (!screen.cx || !screen.cy) /* not supported on NT4 */
2888 screen.cx = GetSystemMetrics( SM_CXSCREEN );
2889 screen.cy = GetSystemMetrics( SM_CYSCREEN );
2891 ok_gsm_3( SM_CXMAXTRACK, screen.cx + 4 + 2 * GetSystemMetrics(SM_CXFRAME),
2892 screen.cx - 4 + 2 * GetSystemMetrics(SM_CXFRAME), /* Vista */
2893 screen.cx + 2 * GetSystemMetrics(SM_CXFRAME)); /* Win8 */
2894 ok_gsm_3( SM_CYMAXTRACK, screen.cy + 4 + 2 * GetSystemMetrics(SM_CYFRAME),
2895 screen.cy - 4 + 2 * GetSystemMetrics(SM_CYFRAME), /* Vista */
2896 screen.cy + 2 * GetSystemMetrics(SM_CYFRAME)); /* Win8 */
2897 /* the next two cannot really be tested as they depend on (application)
2898 * toolbars */
2899 /* SM_CXMAXIMIZED */
2900 /* SM_CYMAXIMIZED */
2901 /* SM_NETWORK */
2902 /* */
2903 /* */
2904 /* */
2905 /* SM_CLEANBOOT */
2906 /* SM_CXDRAG */
2907 /* SM_CYDRAG */
2908 /* SM_SHOWSOUNDS */
2909 ok_gsm( SM_CXMENUCHECK,
2910 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2911 ok_gsm( SM_CYMENUCHECK,
2912 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2913 /* SM_SLOWMACHINE */
2914 /* SM_MIDEASTENABLED */
2915 /* SM_MOUSEWHEELPRESENT */
2916 /* SM_XVIRTUALSCREEN */
2917 /* SM_YVIRTUALSCREEN */
2918 /* SM_CXVIRTUALSCREEN */
2919 /* SM_CYVIRTUALSCREEN */
2920 /* SM_CMONITORS */
2921 /* SM_SAMEDISPLAYFORMAT */
2922 /* SM_IMMENABLED */
2923 /* SM_CXFOCUSBORDER */
2924 /* SM_CYFOCUSBORDER */
2925 /* SM_TABLETPC */
2926 /* SM_MEDIACENTER */
2927 /* SM_CMETRICS */
2928 /* end of tests */
2929 if( gsm_error_ctr ) { /* if any errors where found */
2930 trace( "BorderWidth %d CaptionWidth %d CaptionHeight %d IconSpacing %d IconVerticalSpacing %d\n",
2931 ncm.iBorderWidth, ncm.iCaptionWidth, ncm.iCaptionHeight, IconSpacing, IconVerticalSpacing);
2932 trace( "MenuHeight %d MenuWidth %d ScrollHeight %d ScrollWidth %d SmCaptionHeight %d SmCaptionWidth %d\n",
2933 ncm.iMenuHeight, ncm.iMenuWidth, ncm.iScrollHeight, ncm.iScrollWidth, ncm.iSmCaptionHeight, ncm.iSmCaptionWidth);
2934 trace( "Captionfontchar width %d MenuFont %d,%d CaptionWidth from registry: %d screen %d,%d\n",
2935 avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidthfromreg, screen.cx, screen.cy);
2938 DeleteDC(hdc);
2941 static void test_EnumDisplaySettings(void)
2943 DEVMODEA devmode;
2944 DWORD val;
2945 HDC hdc;
2946 DWORD num;
2948 memset(&devmode, 0, sizeof(devmode));
2949 /* Win95 doesn't handle ENUM_CURRENT_SETTINGS correctly */
2950 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2952 hdc = GetDC(0);
2953 val = GetDeviceCaps(hdc, BITSPIXEL);
2954 ok(devmode.dmBitsPerPel == val ||
2955 broken(devmode.dmDeviceName[0] == 0), /* Win95 */
2956 "GetDeviceCaps(BITSPIXEL) returned %d, EnumDisplaySettings returned %d\n",
2957 val, devmode.dmBitsPerPel);
2959 val = GetDeviceCaps(hdc, NUMCOLORS);
2960 if(devmode.dmBitsPerPel <= 8) {
2961 ok(val == 256, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
2962 } else {
2963 ok(val == -1, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
2966 ReleaseDC(0, hdc);
2968 num = 1;
2969 while (1) {
2970 SetLastError (0xdeadbeef);
2971 if (!EnumDisplaySettingsA(NULL, num, &devmode)) {
2972 DWORD le = GetLastError();
2973 ok(le == ERROR_NO_MORE_FILES ||
2974 le == ERROR_MOD_NOT_FOUND /* Win8 */ ||
2975 le == 0xdeadbeef, /* XP, 2003 */
2976 "Expected ERROR_NO_MORE_FILES, ERROR_MOD_NOT_FOUND or 0xdeadbeef, got %d for %d\n", le, num);
2977 break;
2979 num++;
2983 static void test_GetSysColorBrush(void)
2985 HBRUSH hbr;
2987 SetLastError(0xdeadbeef);
2988 hbr = GetSysColorBrush(-1);
2989 ok(hbr == NULL, "Expected NULL brush\n");
2990 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
2991 /* greater than max index */
2992 hbr = GetSysColorBrush(COLOR_MENUBAR);
2993 if (hbr)
2995 SetLastError(0xdeadbeef);
2996 hbr = GetSysColorBrush(COLOR_MENUBAR + 1);
2997 ok(hbr == NULL, "Expected NULL brush\n");
2998 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
3000 else
3001 win_skip("COLOR_MENUBAR unsupported\n");
3004 static void test_dpi_aware(void)
3006 BOOL ret;
3008 if (!pIsProcessDPIAware)
3010 win_skip("IsProcessDPIAware not available\n");
3011 return;
3014 if (pSetProcessDpiAwarenessContext)
3016 DPI_AWARENESS awareness;
3017 DPI_AWARENESS_CONTEXT context;
3018 ULONG_PTR i;
3019 UINT dpi;
3020 HDC hdc = GetDC( 0 );
3022 context = pGetThreadDpiAwarenessContext();
3023 todo_wine
3024 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3025 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3026 todo_wine
3027 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3028 todo_wine
3029 ok( !pIsProcessDPIAware(), "already aware\n" );
3030 dpi = pGetDpiForSystem();
3031 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
3032 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3033 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3034 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
3035 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3036 SetLastError( 0xdeadbeef );
3037 ret = pSetProcessDpiAwarenessContext( NULL );
3038 ok( !ret, "got %d\n", ret );
3039 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3040 SetLastError( 0xdeadbeef );
3041 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3042 ok( !ret, "got %d\n", ret );
3043 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3044 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3045 ok( ret, "got %d\n", ret );
3046 ok( pIsProcessDPIAware(), "not aware\n" );
3047 real_dpi = pGetDpiForSystem();
3048 SetLastError( 0xdeadbeef );
3049 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3050 ok( !ret, "got %d\n", ret );
3051 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3052 SetLastError( 0xdeadbeef );
3053 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3054 ok( !ret, "got %d\n", ret );
3055 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3057 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_INVALID );
3058 ok( !ret, "got %d\n", ret );
3059 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3060 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_UNAWARE );
3061 ok( !ret, "got %d\n", ret );
3062 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3063 ret = pGetProcessDpiAwarenessInternal( 0, &awareness );
3064 ok( ret, "got %d\n", ret );
3065 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3066 ret = pGetProcessDpiAwarenessInternal( GetCurrentProcess(), &awareness );
3067 ok( ret, "got %d\n", ret );
3068 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3069 ret = pGetProcessDpiAwarenessInternal( (HANDLE)0xdeadbeef, &awareness );
3070 ok( ret, "got %d\n", ret );
3071 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong value %d\n", awareness );
3073 ret = pIsProcessDPIAware();
3074 ok(ret, "got %d\n", ret);
3075 context = pGetThreadDpiAwarenessContext();
3076 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3077 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3078 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3079 SetLastError( 0xdeadbeef );
3080 context = pSetThreadDpiAwarenessContext( 0 );
3081 ok( !context, "got %p\n", context );
3082 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3083 SetLastError( 0xdeadbeef );
3084 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3085 ok( !context, "got %p\n", context );
3086 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3087 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3088 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3089 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3090 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3091 dpi = pGetDpiForSystem();
3092 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3093 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3094 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
3095 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3096 ok( !pIsProcessDPIAware(), "still aware\n" );
3097 context = pGetThreadDpiAwarenessContext();
3098 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3099 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3100 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3101 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3102 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3103 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3104 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3105 dpi = pGetDpiForSystem();
3106 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
3107 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3108 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3109 context = pGetThreadDpiAwarenessContext();
3110 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3111 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3112 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3113 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3114 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3115 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3116 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3117 dpi = pGetDpiForSystem();
3118 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
3119 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3120 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3121 ok( pIsProcessDPIAware(), "not aware\n" );
3122 context = pGetThreadDpiAwarenessContext();
3123 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3124 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000010 );
3125 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3126 context = pGetThreadDpiAwarenessContext();
3127 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3128 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000011 );
3129 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3130 context = pGetThreadDpiAwarenessContext();
3131 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3132 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
3133 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3134 context = pSetThreadDpiAwarenessContext( context );
3135 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3136 context = pGetThreadDpiAwarenessContext();
3137 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3138 for (i = 0; i < 0x100; i++)
3140 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i );
3141 switch (i)
3143 case 0x10:
3144 case 0x11:
3145 case 0x12:
3146 ok( awareness == (i & ~0x10), "%lx: wrong value %u\n", i, awareness );
3147 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i ), "%lx: not valid\n", i );
3148 break;
3149 default:
3150 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", i, awareness );
3151 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i ), "%lx: valid\n", i );
3152 break;
3154 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) );
3155 switch (i)
3157 case 0x10:
3158 case 0x11:
3159 case 0x12:
3160 ok( awareness == (i & ~0x10), "%lx: wrong value %u\n", i | 0x80000000, awareness );
3161 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) ),
3162 "%lx: not valid\n", i | 0x80000000 );
3163 break;
3164 default:
3165 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", i | 0x80000000, awareness );
3166 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) ),
3167 "%lx: valid\n", i | 0x80000000 );
3168 break;
3170 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3171 switch (~i)
3173 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE:
3174 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE:
3175 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE:
3176 ok( awareness == i, "%lx: wrong value %u\n", ~i, awareness );
3177 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i ), "%lx: not valid\n", ~i );
3178 break;
3179 default:
3180 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", ~i, awareness );
3181 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i ), "%lx: valid\n", ~i );
3182 break;
3185 ReleaseDC( 0, hdc );
3187 else win_skip( "SetProcessDpiAwarenessContext not supported\n" );
3189 ret = pSetProcessDPIAware();
3190 ok(ret, "got %d\n", ret);
3192 ret = pIsProcessDPIAware();
3193 ok(ret, "got %d\n", ret);
3195 if (pGetDpiForSystem) real_dpi = pGetDpiForSystem();
3196 dpi = real_dpi;
3197 test_GetSystemMetrics();
3200 static void test_window_dpi(void)
3202 DPI_AWARENESS_CONTEXT context, orig;
3203 DPI_AWARENESS awareness;
3204 HWND hwnd;
3206 if (!pGetWindowDpiAwarenessContext)
3208 win_skip( "GetWindowDpiAwarenessContext not supported\n" );
3209 return;
3211 orig = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3212 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3213 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3214 ok( hwnd != 0, "failed to create window\n" );
3215 context = pGetWindowDpiAwarenessContext( hwnd );
3216 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3217 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3218 DestroyWindow( hwnd );
3220 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3221 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3222 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3223 ok( hwnd != 0, "failed to create window\n" );
3224 context = pGetWindowDpiAwarenessContext( hwnd );
3225 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3226 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3227 DestroyWindow( hwnd );
3229 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3230 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3231 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3232 ok( hwnd != 0, "failed to create window\n" );
3233 context = pGetWindowDpiAwarenessContext( hwnd );
3234 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3235 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3236 DestroyWindow( hwnd );
3238 SetLastError( 0xdeadbeef );
3239 context = pGetWindowDpiAwarenessContext( (HWND)0xdeadbeef );
3240 ok( !context, "got %p\n", context );
3241 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
3243 SetLastError( 0xdeadbeef );
3244 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3245 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3246 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3248 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3249 SetLastError( 0xdeadbeef );
3250 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3251 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3252 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3254 pSetThreadDpiAwarenessContext( orig );
3257 START_TEST(sysparams)
3259 int argc;
3260 char** argv;
3261 WNDCLASSA wc;
3262 MSG msg;
3263 HANDLE hThread;
3264 DWORD dwThreadId;
3265 HANDLE hInstance, hdll;
3267 hdll = GetModuleHandleA("user32.dll");
3268 pChangeDisplaySettingsExA = (void*)GetProcAddress(hdll, "ChangeDisplaySettingsExA");
3269 pIsProcessDPIAware = (void*)GetProcAddress(hdll, "IsProcessDPIAware");
3270 pSetProcessDPIAware = (void*)GetProcAddress(hdll, "SetProcessDPIAware");
3271 pGetDpiForSystem = (void*)GetProcAddress(hdll, "GetDpiForSystem");
3272 pSetProcessDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessContext");
3273 pGetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "GetProcessDpiAwarenessInternal");
3274 pSetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessInternal");
3275 pGetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetThreadDpiAwarenessContext");
3276 pSetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetThreadDpiAwarenessContext");
3277 pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetWindowDpiAwarenessContext");
3278 pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetAwarenessFromDpiAwarenessContext");
3279 pIsValidDpiAwarenessContext = (void*)GetProcAddress(hdll, "IsValidDpiAwarenessContext");
3281 hInstance = GetModuleHandleA( NULL );
3282 hdc = GetDC(0);
3283 dpi = GetDeviceCaps( hdc, LOGPIXELSY);
3284 real_dpi = get_real_dpi();
3285 trace("dpi %d real_dpi %d\n", dpi, real_dpi);
3286 iswin9x = GetVersion() & 0x80000000;
3288 /* This test requires interactivity, if we don't have it, give up */
3289 if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) &&
3290 GetLastError()==ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) return;
3292 argc = winetest_get_mainargs(&argv);
3293 strict=(argc >= 3 && strcmp(argv[2],"strict")==0);
3294 trace("strict=%d\n",strict);
3296 trace("testing GetSystemMetrics with your current desktop settings\n");
3297 test_GetSystemMetrics( );
3298 trace("testing EnumDisplaySettings vs GetDeviceCaps\n");
3299 test_EnumDisplaySettings( );
3300 test_GetSysColorBrush( );
3302 change_counter = 0;
3303 change_last_param = 0;
3305 wc.lpszClassName = "SysParamsTestClass";
3306 wc.lpfnWndProc = SysParamsTestWndProc;
3307 wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
3308 wc.hInstance = hInstance;
3309 wc.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
3310 wc.hCursor = LoadCursorA( 0, (LPCSTR)IDC_ARROW );
3311 wc.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
3312 wc.lpszMenuName = 0;
3313 wc.cbClsExtra = 0;
3314 wc.cbWndExtra = 0;
3315 RegisterClassA( &wc );
3317 ghTestWnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3318 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, hInstance, NULL );
3320 hThread = CreateThread( NULL, 0, SysParamsThreadFunc, 0, 0, &dwThreadId );
3321 assert( hThread );
3322 CloseHandle( hThread );
3324 while( GetMessageA( &msg, 0, 0, 0 )) {
3325 TranslateMessage( &msg );
3326 DispatchMessageA( &msg );
3328 ReleaseDC( 0, hdc);
3330 test_dpi_aware();
3331 test_window_dpi();