user32: Implement Get/SetProcessDpiAwarenessInternal().
[wine.git] / dlls / user32 / tests / sysparams.c
blobe1329923d69e0c7ebaa557b96bac5c06e1db60e7
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 DPI_AWARENESS_CONTEXT (WINAPI *pGetThreadDpiAwarenessContext)(void);
48 static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
49 static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
50 static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
52 static BOOL strict;
53 static int dpi, real_dpi;
54 static BOOL iswin9x;
55 static HDC hdc;
57 #define eq(received, expected, label, type) \
58 ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
61 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
62 #define SPI_SETBEEP_VALNAME "Beep"
63 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
64 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
65 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
66 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
67 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop\\WindowMetrics"
68 #define SPI_SETBORDER_REGKEY2 "Control Panel\\Desktop"
69 #define SPI_SETBORDER_VALNAME "BorderWidth"
70 #define SPI_METRIC_REGKEY "Control Panel\\Desktop\\WindowMetrics"
71 #define SPI_SCROLLWIDTH_VALNAME "ScrollWidth"
72 #define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight"
73 #define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth"
74 #define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight"
75 #define SPI_CAPTIONFONT_VALNAME "CaptionFont"
76 #define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth"
77 #define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight"
78 #define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont"
79 #define SPI_MENUWIDTH_VALNAME "MenuWidth"
80 #define SPI_MENUHEIGHT_VALNAME "MenuHeight"
81 #define SPI_MENUFONT_VALNAME "MenuFont"
82 #define SPI_STATUSFONT_VALNAME "StatusFont"
83 #define SPI_MESSAGEFONT_VALNAME "MessageFont"
85 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
86 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
87 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
88 #define SPI_ICONHORIZONTALSPACING_REGKEY2 "Control Panel\\Desktop"
89 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
90 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
91 #define SPI_ICONVERTICALSPACING_REGKEY2 "Control Panel\\Desktop"
92 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
93 #define SPI_MINIMIZEDMETRICS_REGKEY "Control Panel\\Desktop\\WindowMetrics"
94 #define SPI_MINWIDTH_VALNAME "MinWidth"
95 #define SPI_MINHORZGAP_VALNAME "MinHorzGap"
96 #define SPI_MINVERTGAP_VALNAME "MinVertGap"
97 #define SPI_MINARRANGE_VALNAME "MinArrange"
98 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
99 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
100 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
101 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
102 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
103 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
104 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
105 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
106 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
107 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
108 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
109 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
110 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
111 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
112 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
113 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
114 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
115 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
116 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
117 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
118 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
119 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
120 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
121 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
122 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
123 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
124 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
125 #define SPI_SETSHOWSOUNDS_VALNAME "On"
126 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Accessibility\\Keyboard Preference"
127 #define SPI_SETKEYBOARDPREF_VALNAME "On"
128 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY "Control Panel\\Accessibility"
129 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY "Keyboard Preference"
130 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Accessibility\\Blind Access"
131 #define SPI_SETSCREENREADER_VALNAME "On"
132 #define SPI_SETSCREENREADER_REGKEY_LEGACY "Control Panel\\Accessibility"
133 #define SPI_SETSCREENREADER_VALNAME_LEGACY "Blind Access"
134 #define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\\Desktop"
135 #define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing"
136 #define SPI_SETFONTSMOOTHINGTYPE_VALNAME "FontSmoothingType"
137 #define SPI_SETFONTSMOOTHINGCONTRAST_VALNAME "FontSmoothingGamma"
138 #define SPI_SETFONTSMOOTHINGORIENTATION_VALNAME "FontSmoothingOrientation"
139 #define SPI_SETLOWPOWERACTIVE_REGKEY "Control Panel\\Desktop"
140 #define SPI_SETLOWPOWERACTIVE_VALNAME "LowPowerActive"
141 #define SPI_SETPOWEROFFACTIVE_REGKEY "Control Panel\\Desktop"
142 #define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive"
143 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
144 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
145 #define SPI_SETSNAPTODEFBUTTON_REGKEY "Control Panel\\Mouse"
146 #define SPI_SETSNAPTODEFBUTTON_VALNAME "SnapToDefaultButton"
147 #define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse"
148 #define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth"
149 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse"
150 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight"
151 #define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse"
152 #define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime"
153 #define SPI_SETMOUSESCROLLCHARS_REGKEY "Control Panel\\Desktop"
154 #define SPI_SETMOUSESCROLLCHARS_VALNAME "WheelScrollChars"
155 #define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop"
156 #define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines"
157 #define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop"
158 #define SPI_SETMENUSHOWDELAY_VALNAME "MenuShowDelay"
159 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
160 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
162 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
163 #define WINE_CURRENT_USER_REGKEY "Wine"
165 static HWND ghTestWnd;
167 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
168 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
169 LPARAM lParam );
170 static int change_counter;
171 static int change_setworkarea_param, change_iconverticalspacing_param;
172 static int change_last_param;
173 static int last_bpp;
174 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
175 static HANDLE displaychange_sem = 0;
177 static BOOL get_reg_dword(HKEY base, const char *key_name, const char *value_name, DWORD *value)
179 HKEY key;
180 DWORD type, data, size = sizeof(data);
181 BOOL ret = FALSE;
183 if (RegOpenKeyA(base, key_name, &key) == ERROR_SUCCESS)
185 if (RegQueryValueExA(key, value_name, NULL, &type, (void *)&data, &size) == ERROR_SUCCESS &&
186 type == REG_DWORD)
188 *value = data;
189 ret = TRUE;
191 RegCloseKey(key);
193 return ret;
196 static DWORD get_real_dpi(void)
198 DWORD dpi;
200 if (get_reg_dword(HKEY_CURRENT_USER, "Control Panel\\Desktop", "LogPixels", &dpi))
201 return dpi;
202 if (get_reg_dword(HKEY_CURRENT_CONFIG, "Software\\Fonts", "LogPixels", &dpi))
203 return dpi;
204 return USER_DEFAULT_SCREEN_DPI;
207 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
208 LPARAM lParam )
210 switch (msg) {
212 case WM_DISPLAYCHANGE:
213 ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
214 last_bpp = wParam;
215 displaychange_ok = FALSE;
216 ReleaseSemaphore(displaychange_sem, 1, 0);
217 break;
219 case WM_SETTINGCHANGE:
220 if (change_counter>0) {
221 /* ignore these messages caused by resizing of toolbars */
222 if( wParam == SPI_SETWORKAREA){
223 change_setworkarea_param = 1;
224 break;
225 } else if( wParam == SPI_ICONVERTICALSPACING) {
226 change_iconverticalspacing_param = 1;
227 break;
228 } else if( displaychange_test_active)
229 break;
230 if( !change_last_param){
231 change_last_param = wParam;
232 break;
234 ok(0,"too many changes counter=%d last change=%d\n",
235 change_counter,change_last_param);
236 change_counter++;
237 change_last_param = wParam;
238 break;
240 change_counter++;
241 change_last_param = change_setworkarea_param = change_iconverticalspacing_param =0;
242 if( wParam == SPI_SETWORKAREA)
243 change_setworkarea_param = 1;
244 else if( wParam == SPI_ICONVERTICALSPACING)
245 change_iconverticalspacing_param = 1;
246 else
247 change_last_param = wParam;
248 break;
250 case WM_DESTROY:
251 PostQuitMessage( 0 );
252 break;
254 /* drop through */
255 default:
256 return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
259 return 0;
263 Performs testing for system parameters messages
264 params:
265 - system parameter id
266 - supposed value of the registry key
268 static void test_change_message( int action, int optional )
270 if (change_counter==0 && optional==1)
271 return;
272 ok( 1 == change_counter,
273 "Missed a message: change_counter=%d\n", change_counter );
274 change_counter = 0;
275 ok( action == change_last_param ||
276 ( change_setworkarea_param && action == SPI_SETWORKAREA) ||
277 ( change_iconverticalspacing_param && action == SPI_ICONVERTICALSPACING),
278 "Wrong action got %d expected %d\n", change_last_param, action );
279 change_last_param = 0;
282 static BOOL test_error_msg ( int rc, const char *name )
284 DWORD last_error = GetLastError();
286 if (rc==0)
288 if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
290 skip("%s not supported on this platform\n", name);
292 else if (last_error==ERROR_ACCESS_DENIED)
294 skip("%s does not have privileges to run\n", name);
296 else
298 trace("%s failed for reason: %d. Indicating test failure and skipping remainder of test\n",name,last_error);
299 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
301 return FALSE;
303 else
305 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
306 return TRUE;
311 * Tests the HKEY_CURRENT_USER subkey value.
312 * The value should contain string value.
314 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2,
315 const void *exp_value, DWORD exp_type, BOOL optional )
317 CHAR value[MAX_PATH];
318 DWORD valueLen;
319 DWORD type;
320 HKEY hKey;
321 LONG rc;
322 int found=0;
324 *value='\0';
325 valueLen=sizeof(value);
326 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
327 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
328 RegCloseKey( hKey );
329 if (rc==ERROR_SUCCESS)
331 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
332 switch (exp_type)
334 case REG_DWORD:
335 ok( *(DWORD *)value == *(DWORD *)exp_value,
336 "Wrong value in registry: %s %s %08x/%08x\n",
337 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
338 break;
339 case REG_SZ:
340 ok( !strcmp( exp_value, value ),
341 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
342 subKey1, valName1, value, (const char *)exp_value );
343 break;
345 found++;
347 else if (strict)
349 ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
350 subKey1, valName1);
352 if (valName2)
354 *value='\0';
355 valueLen=sizeof(value);
356 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
357 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
358 RegCloseKey( hKey );
359 if (rc==ERROR_SUCCESS)
361 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
362 switch (exp_type)
364 case REG_DWORD:
365 ok( *(DWORD *)value == *(DWORD *)exp_value,
366 "Wrong value in registry: %s %s %08x/%08x\n",
367 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
368 break;
369 case REG_SZ:
370 ok( !strcmp( exp_value, value ),
371 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
372 subKey1, valName1, value, (const char *)exp_value );
373 break;
375 found++;
377 else if (strict)
379 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
380 subKey1, valName2 );
383 if (subKey2 && !strict)
385 *value='\0';
386 valueLen=sizeof(value);
387 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
388 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
389 RegCloseKey( hKey );
390 if (rc==ERROR_SUCCESS)
392 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
393 switch (exp_type)
395 case REG_DWORD:
396 ok( *(DWORD *)value == *(DWORD *)exp_value,
397 "Wrong value in registry: %s %s %08x/%08x\n",
398 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
399 break;
400 case REG_SZ:
401 ok( !strcmp( exp_value, value ),
402 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
403 subKey1, valName1, value, (const char *)exp_value );
404 break;
406 found++;
408 else if (strict)
410 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
411 subKey2, valName1 );
413 if (valName2)
415 *value='\0';
416 valueLen=sizeof(value);
417 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
418 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
419 RegCloseKey( hKey );
420 if (rc==ERROR_SUCCESS)
422 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
423 switch (exp_type)
425 case REG_DWORD:
426 ok( *(DWORD *)value == *(DWORD *)exp_value,
427 "Wrong value in registry: %s %s %08x/%08x\n",
428 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
429 break;
430 case REG_SZ:
431 ok( !strcmp( exp_value, value ),
432 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
433 subKey1, valName1, value, (const char *)exp_value );
434 break;
436 found++;
438 else if (strict)
440 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
441 subKey2, valName2 );
445 ok(found || optional,
446 "Missing registry values: %s or %s in keys: %s or %s\n",
447 valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
450 #define test_reg_key( subKey, valName, testValue ) \
451 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, FALSE )
452 #define test_reg_key_optional( subKey, valName, testValue ) \
453 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, TRUE )
454 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
455 _test_reg_key( subKey1, subKey2, valName, NULL, testValue, REG_SZ, FALSE )
456 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
457 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, FALSE )
458 #define test_reg_key_ex2_optional( subKey1, subKey2, valName1, valName2, testValue ) \
459 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, TRUE )
460 #define test_reg_key_dword( subKey, valName, testValue ) \
461 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_DWORD, FALSE )
463 /* get a metric from the registry. If the value is negative
464 * it is assumed to be in twips and converted to pixels */
465 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
467 HKEY hkey;
468 char buf[64];
469 DWORD ret;
470 DWORD size, type;
471 int value;
473 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
474 size = sizeof(buf);
475 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
476 RegCloseKey( hkey );
477 if( ret != ERROR_SUCCESS) return -1;
478 value = atoi( buf);
479 if( value < 0)
480 value = ( -value * dpi + 720) / 1440;
481 return value;
484 typedef struct
486 INT16 lfHeight;
487 INT16 lfWidth;
488 INT16 lfEscapement;
489 INT16 lfOrientation;
490 INT16 lfWeight;
491 BYTE lfItalic;
492 BYTE lfUnderline;
493 BYTE lfStrikeOut;
494 BYTE lfCharSet;
495 BYTE lfOutPrecision;
496 BYTE lfClipPrecision;
497 BYTE lfQuality;
498 BYTE lfPitchAndFamily;
499 CHAR lfFaceName[LF_FACESIZE];
500 } LOGFONT16, *LPLOGFONT16;
502 /* get logfont from the registry */
503 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
505 HKEY hkey;
506 LOGFONTW lfw;
507 DWORD ret, size, type;
509 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
510 size = sizeof( lfw);
511 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
512 RegCloseKey( hkey );
513 ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
514 if( ret != ERROR_SUCCESS)
515 return FALSE;
516 if( size <= sizeof( LOGFONT16)) {
517 LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
518 plf->lfHeight = plf16->lfHeight;
519 plf->lfWidth = plf16->lfWidth;
520 plf->lfEscapement = plf16->lfEscapement;
521 plf->lfOrientation = plf16->lfOrientation;
522 plf->lfWeight = plf16->lfWeight;
523 plf->lfItalic = plf16->lfItalic;
524 plf->lfUnderline = plf16->lfUnderline;
525 plf->lfStrikeOut = plf16->lfStrikeOut;
526 plf->lfCharSet = plf16->lfCharSet;
527 plf->lfOutPrecision = plf16->lfOutPrecision;
528 plf->lfClipPrecision = plf16->lfClipPrecision;
529 plf->lfQuality = plf16->lfQuality;
530 plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
531 memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
532 } else if( size <= sizeof( LOGFONTA)) {
533 plf = (LOGFONTA*) &lfw;
534 } else {
535 plf->lfHeight = lfw.lfHeight;
536 plf->lfWidth = lfw.lfWidth;
537 plf->lfEscapement = lfw.lfEscapement;
538 plf->lfOrientation = lfw.lfOrientation;
539 plf->lfWeight = lfw.lfWeight;
540 plf->lfItalic = lfw.lfItalic;
541 plf->lfUnderline = lfw.lfUnderline;
542 plf->lfStrikeOut = lfw.lfStrikeOut;
543 plf->lfCharSet = lfw.lfCharSet;
544 plf->lfOutPrecision = lfw.lfOutPrecision;
545 plf->lfClipPrecision = lfw.lfClipPrecision;
546 plf->lfQuality = lfw.lfQuality;
547 plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
548 WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
549 LF_FACESIZE, NULL, NULL);
552 return TRUE;
555 static void test_SPI_SETBEEP( void ) /* 2 */
557 BOOL rc;
558 BOOL old_b;
559 BOOL b;
560 BOOL curr_val;
562 trace("testing SPI_{GET,SET}BEEP\n");
563 SetLastError(0xdeadbeef);
564 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
565 if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
566 return;
568 curr_val = TRUE;
569 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
570 if (!test_error_msg(rc,"SPI_SETBEEP")) return;
571 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
572 test_change_message( SPI_SETBEEP, 0 );
573 test_reg_key( SPI_SETBEEP_REGKEY,
574 SPI_SETBEEP_VALNAME,
575 curr_val ? "Yes" : "No" );
576 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
577 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
578 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
579 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
580 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
582 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
583 eq( b, curr_val, "SystemParametersInfoW", "%d" );
586 /* is a message sent for the second change? */
587 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
588 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
589 test_change_message( SPI_SETBEEP, 0 );
591 curr_val = FALSE;
592 rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
593 if (rc == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
594 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
595 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
596 test_change_message( SPI_SETBEEP, 0 );
597 test_reg_key( SPI_SETBEEP_REGKEY,
598 SPI_SETBEEP_VALNAME,
599 curr_val ? "Yes" : "No" );
600 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
601 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
602 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
603 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
604 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
606 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
607 eq( b, curr_val, "SystemParametersInfoW", "%d" );
609 ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
611 rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
612 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
615 static const char *setmouse_valuenames[3] = {
616 SPI_SETMOUSE_VALNAME1,
617 SPI_SETMOUSE_VALNAME2,
618 SPI_SETMOUSE_VALNAME3
622 * Runs check for one setting of spi_setmouse.
624 static BOOL run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change, int nchange )
626 BOOL rc;
627 INT mi[3];
628 static int aw_turn = 0;
629 static BOOL w_implemented = TRUE;
631 char buf[20];
632 int i;
634 aw_turn++;
635 rc = FALSE;
636 if ((aw_turn % 2!=0) && (w_implemented))
638 /* call unicode on odd (non even) calls */
639 SetLastError(0xdeadbeef);
640 rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
641 if (rc == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
643 w_implemented = FALSE;
644 trace("SystemParametersInfoW not supported on this platform\n");
648 if ((aw_turn % 2==0) || (!w_implemented))
650 /* call ascii version on even calls or if unicode is not available */
651 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
653 if (!test_error_msg(rc,"SPI_SETMOUSE")) return FALSE;
655 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
656 test_change_message( SPI_SETMOUSE, 0 );
657 for (i = 0; i < 3; i++)
659 sprintf( buf, "%d", curr_val[i] );
660 test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
663 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
664 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
665 for (i = 0; i < 3; i++)
667 ok(mi[i] == curr_val[i],
668 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
671 if (w_implemented)
673 rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
674 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
675 for (i = 0; i < 3; i++)
677 ok(mi[i] == curr_val[i],
678 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
682 if (0)
684 /* FIXME: this always fails for me - AJ */
685 for (i = 0; i < nchange; i++)
687 POINT mv;
688 mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
689 mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
690 GetCursorPos( &mv );
691 ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
692 ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
695 return TRUE;
698 static void test_SPI_SETMOUSE( void ) /* 4 */
700 BOOL rc;
701 INT old_mi[3];
703 /* win nt default values - 6, 10, 1 */
704 INT curr_val[3] = {6, 10, 1};
706 /* requested and projected mouse movements */
707 POINT req_change[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
708 POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
709 POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
710 POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
711 POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
712 POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
713 POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
714 POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
715 POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
717 int nchange = sizeof( req_change ) / sizeof( POINT );
719 trace("testing SPI_{GET,SET}MOUSE\n");
720 SetLastError(0xdeadbeef);
721 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
722 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
723 return;
725 if (!run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange )) return;
727 /* acceleration change */
728 curr_val[2] = 2;
729 run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
731 /* acceleration change */
732 curr_val[2] = 3;
733 run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
735 /* acceleration change */
736 curr_val[2] = 0;
737 run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
739 /* threshold change */
740 curr_val[2] = 1;
741 curr_val[0] = 7;
742 run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
744 /* threshold change */
745 curr_val[2] = 2;
746 curr_val[0] = 6;
747 curr_val[1] = 6;
748 run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
750 /* threshold change */
751 curr_val[1] = 7;
752 run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
754 /* threshold change */
755 curr_val[1] = 5;
756 run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
758 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
759 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
762 static BOOL test_setborder(UINT curr_val, int usesetborder, int dpi)
764 BOOL rc;
765 UINT border, regval;
766 INT frame;
767 NONCLIENTMETRICSA ncm;
769 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
770 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
771 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
772 if( usesetborder) {
773 rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
774 if (!test_error_msg(rc,"SPI_SETBORDER")) return FALSE;
775 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
776 test_change_message( SPI_SETBORDER, 1 );
777 } else { /* set non client metrics */
778 ncm.iBorderWidth = curr_val;
779 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
780 SPIF_SENDCHANGE);
781 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return FALSE;
782 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
783 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
785 if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
786 regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
787 if( regval != curr_val)
788 regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
789 ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
791 /* minimum border width is 1 */
792 if (curr_val == 0) curr_val = 1;
793 /* should be the same as the non client metrics */
794 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
795 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
796 eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
797 /* and from SPI_GETBORDER */
798 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
799 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
800 eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
801 /* test some SystemMetrics */
802 frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
803 eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
804 eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
805 eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
806 eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
807 return TRUE;
810 static void test_SPI_SETBORDER( void ) /* 6 */
812 BOOL rc;
813 UINT old_border;
814 NONCLIENTMETRICSA ncmsave;
815 INT CaptionWidth,
816 PaddedBorderWidth;
818 ncmsave.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
819 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
820 if( !rc) {
821 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
822 return;
824 /* CaptionWidth from the registry may have different value of iCaptionWidth
825 * from the non client metrics (observed on WinXP).
826 * Fix this so we can safely restore settings with the nonclientmetrics */
827 CaptionWidth = metricfromreg(
828 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
829 ncmsave.iCaptionWidth = CaptionWidth;
831 /* These tests hang when XFree86 4.0 for Windows is running (tested on
832 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
833 * running.
835 if (FindWindowA( NULL, "Cygwin/XFree86" ))
836 return;
838 trace("testing SPI_{GET,SET}BORDER\n");
840 SetLastError(0xdeadbeef);
841 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 );
842 if (!test_error_msg(rc,"SPI_{GET,SET}BORDER"))
843 return;
844 /* FIXME: include new PaddedBorderWidth parameter */
845 PaddedBorderWidth = ncmsave.iBorderWidth - old_border;
846 if( PaddedBorderWidth){
847 win_skip( "Cannot reliably restore border width yet (PaddedBorderWidth = %d)\n",
848 PaddedBorderWidth);
849 return;
851 /* This will restore sane values if the test hang previous run. */
852 if ( old_border == 7 || old_border == 20 )
853 old_border = 1;
855 /* The SPI_SETBORDER seems to be buggy on Win9x/ME (looks like you need to
856 * do it twice to make the intended change). So skip parts of the tests on
857 * those platforms */
858 if( !iswin9x) {
859 /* win2k3 fails if you set the same border twice, or if size is 0 */
860 if (!test_setborder(2, 1, dpi)) return;
861 test_setborder(1, 1, dpi);
862 test_setborder(3, 1, dpi);
864 if (!test_setborder(1, 0, dpi)) return;
865 test_setborder(0, 0, dpi);
866 test_setborder(3, 0, dpi);
868 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave,
869 SPIF_UPDATEINIFILE| SPIF_SENDCHANGE);
870 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
871 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
874 static void test_SPI_SETKEYBOARDSPEED( void ) /* 10 */
876 BOOL rc;
877 UINT old_speed;
878 const UINT vals[]={0,20,31};
879 unsigned int i;
881 trace("testing SPI_{GET,SET}KEYBOARDSPEED\n");
882 SetLastError(0xdeadbeef);
883 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &old_speed, 0 );
884 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDSPEED"))
885 return;
887 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
889 UINT v;
890 char buf[10];
892 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, vals[i], 0,
893 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
894 if (!test_error_msg(rc,"SPI_SETKEYBOARDSPEED")) return;
895 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
896 test_change_message( SPI_SETKEYBOARDSPEED, 0 );
897 sprintf( buf, "%d", vals[i] );
898 test_reg_key( SPI_SETKEYBOARDSPEED_REGKEY, SPI_SETKEYBOARDSPEED_VALNAME, buf );
900 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &v, 0 );
901 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
902 eq( v, vals[i], "SPI_{GET,SET}KEYBOARDSPEED", "%d" );
905 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, old_speed, 0, SPIF_UPDATEINIFILE );
906 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
909 /* test_SPI_ICONHORIZONTALSPACING helper */
910 static BOOL dotest_spi_iconhorizontalspacing( INT curr_val)
912 BOOL rc;
913 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
914 ICONMETRICSA im;
916 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0,
917 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
918 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING")) return FALSE;
919 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
920 test_change_message( SPI_ICONHORIZONTALSPACING, 0 );
921 curr_val = max( curr_val, min_val );
922 /* The registry keys depend on the Windows version and the values too
923 * let's test (works on win95,ME,NT4,2k,XP)
925 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY2, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
926 if( regval != curr_val)
927 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
928 ok( curr_val == regval,
929 "wrong value in registry %d, expected %d\n", regval, curr_val);
930 /* compare with what SPI_ICONHORIZONTALSPACING returns */
931 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
932 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
933 eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d");
934 /* and with a system metrics */
935 eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" );
936 /* and with what SPI_GETICONMETRICS returns */
937 im.cbSize = sizeof(ICONMETRICSA);
938 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
939 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
940 eq( im.iHorzSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
941 return TRUE;
944 static void test_SPI_ICONHORIZONTALSPACING( void ) /* 13 */
946 BOOL rc;
947 INT old_spacing;
949 trace("testing SPI_ICONHORIZONTALSPACING\n");
950 SetLastError(0xdeadbeef);
951 /* default value: 75 */
952 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &old_spacing, 0 );
953 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING"))
954 return;
955 /* do not increase the value as it would upset the user's icon layout */
956 if (!dotest_spi_iconhorizontalspacing( old_spacing - 1)) return;
957 dotest_spi_iconhorizontalspacing( 10); /* minimum is 32 */
958 /* restore */
959 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, old_spacing, 0, SPIF_UPDATEINIFILE );
960 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
963 static void test_SPI_SETSCREENSAVETIMEOUT( void ) /* 14 */
965 BOOL rc;
966 UINT old_timeout;
967 const UINT vals[]={0,32767};
968 unsigned int i;
970 trace("testing SPI_{GET,SET}SCREENSAVETIMEOUT\n");
971 SetLastError(0xdeadbeef);
972 rc=SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &old_timeout, 0 );
973 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVETIMEOUT"))
974 return;
976 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
978 UINT v;
979 char buf[10];
981 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, vals[i], 0,
982 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
983 if (!test_error_msg(rc,"SPI_SETSCREENSAVETIMEOUT")) return;
984 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
985 test_change_message( SPI_SETSCREENSAVETIMEOUT, 0 );
986 sprintf( buf, "%d", vals[i] );
987 test_reg_key( SPI_SETSCREENSAVETIMEOUT_REGKEY,
988 SPI_SETSCREENSAVETIMEOUT_VALNAME, buf );
990 rc = SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &v, 0 );
991 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
992 eq( v, vals[i], "SPI_{GET,SET}SCREENSAVETIMEOUT", "%d" );
995 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, old_timeout, 0,
996 SPIF_UPDATEINIFILE );
997 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1000 static void test_SPI_SETSCREENSAVEACTIVE( void ) /* 17 */
1002 BOOL rc;
1003 BOOL old_b;
1004 const UINT vals[]={TRUE,FALSE};
1005 unsigned int i;
1007 trace("testing SPI_{GET,SET}SCREENSAVEACTIVE\n");
1008 SetLastError(0xdeadbeef);
1009 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &old_b, 0 );
1010 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVEACTIVE"))
1011 return;
1013 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1015 UINT v;
1017 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, vals[i], 0,
1018 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1019 if (!test_error_msg(rc,"SPI_SETSCREENSAVEACTIVE")) return;
1020 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1021 test_change_message( SPI_SETSCREENSAVEACTIVE, 0 );
1022 test_reg_key( SPI_SETSCREENSAVEACTIVE_REGKEY,
1023 SPI_SETSCREENSAVEACTIVE_VALNAME,
1024 vals[i] ? "1" : "0" );
1026 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &v, 0 );
1027 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1028 ok(v == vals[i] || broken(! v) /* Win 7 */,
1029 "SPI_{GET,SET}SCREENSAVEACTIVE: got %d instead of %d\n", v, vals[i]);
1032 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
1033 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1036 static void test_SPI_SETGRIDGRANULARITY( void ) /* 19 */
1038 /* ??? */;
1041 static void test_SPI_SETKEYBOARDDELAY( void ) /* 23 */
1043 BOOL rc;
1044 UINT old_delay;
1045 const UINT vals[]={0,3};
1046 unsigned int i;
1048 trace("testing SPI_{GET,SET}KEYBOARDDELAY\n");
1049 SetLastError(0xdeadbeef);
1050 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &old_delay, 0 );
1051 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDDELAY"))
1052 return;
1054 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1056 UINT delay;
1057 char buf[10];
1059 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, vals[i], 0,
1060 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1061 if (!test_error_msg(rc,"SPI_SETKEYBOARDDELAY")) return;
1062 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1063 test_change_message( SPI_SETKEYBOARDDELAY, 0 );
1064 sprintf( buf, "%d", vals[i] );
1065 test_reg_key( SPI_SETKEYBOARDDELAY_REGKEY,
1066 SPI_SETKEYBOARDDELAY_VALNAME, buf );
1068 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &delay, 0 );
1069 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1070 eq( delay, vals[i], "SPI_{GET,SET}KEYBOARDDELAY", "%d" );
1073 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, old_delay, 0, SPIF_UPDATEINIFILE );
1074 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1078 /* test_SPI_ICONVERTICALSPACING helper */
1079 static BOOL dotest_spi_iconverticalspacing( INT curr_val)
1081 BOOL rc;
1082 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
1083 ICONMETRICSA im;
1085 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0,
1086 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1087 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING")) return FALSE;
1088 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1089 test_change_message( SPI_ICONVERTICALSPACING, 0 );
1090 curr_val = max( curr_val, min_val );
1091 /* The registry keys depend on the Windows version and the values too
1092 * let's test (works on win95,ME,NT4,2k,XP)
1094 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY2, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1095 if( regval != curr_val)
1096 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1097 ok( curr_val == regval,
1098 "wrong value in registry %d, expected %d\n", regval, curr_val);
1099 /* compare with what SPI_ICONVERTICALSPACING returns */
1100 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1101 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1102 eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" );
1103 /* and with a system metrics */
1104 eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" );
1105 /* and with what SPI_GETICONMETRICS returns */
1106 im.cbSize = sizeof(ICONMETRICSA);
1107 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1108 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1109 eq( im.iVertSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
1110 return TRUE;
1113 static void test_SPI_ICONVERTICALSPACING( void ) /* 24 */
1115 BOOL rc;
1116 INT old_spacing;
1118 trace("testing SPI_ICONVERTICALSPACING\n");
1119 SetLastError(0xdeadbeef);
1120 /* default value: 75 */
1121 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &old_spacing, 0 );
1122 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING"))
1123 return;
1124 /* do not increase the value as it would upset the user's icon layout */
1125 if (!dotest_spi_iconverticalspacing( old_spacing - 1)) return;
1126 /* same tests with a value less than the minimum 32 */
1127 dotest_spi_iconverticalspacing( 10);
1128 /* restore */
1129 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, old_spacing, 0,
1130 SPIF_UPDATEINIFILE );
1131 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1134 static void test_SPI_SETICONTITLEWRAP( void ) /* 26 */
1136 BOOL rc;
1137 BOOL old_b;
1138 const UINT vals[]={TRUE,FALSE};
1139 unsigned int i;
1140 ICONMETRICSA im;
1142 /* These tests hang when XFree86 4.0 for Windows is running (tested on
1143 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
1144 * running.
1146 if (FindWindowA( NULL, "Cygwin/XFree86" ))
1147 return;
1149 trace("testing SPI_{GET,SET}ICONTITLEWRAP\n");
1150 SetLastError(0xdeadbeef);
1151 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &old_b, 0 );
1152 if (!test_error_msg(rc,"SPI_{GET,SET}ICONTITLEWRAP"))
1153 return;
1155 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1157 UINT v;
1158 UINT regval;
1160 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, vals[i], 0,
1161 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1162 if (!test_error_msg(rc,"SPI_SETICONTITLEWRAP")) return;
1163 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1164 test_change_message( SPI_SETICONTITLEWRAP, 1 );
1165 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2,
1166 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1167 if( regval != vals[i])
1168 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1,
1169 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1170 ok( regval == vals[i] || broken(regval == -1), /* win9x */
1171 "wrong value in registry %d, expected %d\n", regval, vals[i] );
1173 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &v, 0 );
1174 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1175 eq( v, vals[i], "SPI_{GET,SET}ICONTITLEWRAP", "%d" );
1176 /* and test with what SPI_GETICONMETRICS returns */
1177 im.cbSize = sizeof(ICONMETRICSA);
1178 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1179 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1180 eq( im.iTitleWrap, (BOOL)vals[i], "SPI_GETICONMETRICS", "%d" );
1183 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, old_b, 0, SPIF_UPDATEINIFILE );
1184 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1187 static void test_SPI_SETMENUDROPALIGNMENT( void ) /* 28 */
1189 BOOL rc;
1190 BOOL old_b;
1191 const UINT vals[]={TRUE,FALSE};
1192 unsigned int i;
1194 trace("testing SPI_{GET,SET}MENUDROPALIGNMENT\n");
1195 SetLastError(0xdeadbeef);
1196 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &old_b, 0 );
1197 if (!test_error_msg(rc,"SPI_{GET,SET}MENUDROPALIGNMENT"))
1198 return;
1200 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1202 UINT v;
1204 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, vals[i], 0,
1205 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1206 if (!test_error_msg(rc,"SPI_SETMENUDROPALIGNMENT")) return;
1207 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1208 test_change_message( SPI_SETMENUDROPALIGNMENT, 0 );
1209 test_reg_key_ex( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1210 SPI_SETMENUDROPALIGNMENT_REGKEY2,
1211 SPI_SETMENUDROPALIGNMENT_VALNAME,
1212 vals[i] ? "1" : "0" );
1214 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &v, 0 );
1215 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1216 eq( v, vals[i], "SPI_{GET,SET}MENUDROPALIGNMENT", "%d" );
1217 eq( GetSystemMetrics( SM_MENUDROPALIGNMENT ), (int)vals[i],
1218 "SM_MENUDROPALIGNMENT", "%d" );
1221 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, old_b, 0,
1222 SPIF_UPDATEINIFILE );
1223 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1226 static void test_SPI_SETDOUBLECLKWIDTH( void ) /* 29 */
1228 BOOL rc;
1229 INT old_width;
1230 const UINT vals[]={0,10000};
1231 unsigned int i;
1233 trace("testing SPI_{GET,SET}DOUBLECLKWIDTH\n");
1234 old_width = GetSystemMetrics( SM_CXDOUBLECLK );
1236 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1238 char buf[10];
1240 SetLastError(0xdeadbeef);
1241 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, vals[i], 0,
1242 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1243 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKWIDTH"))
1244 return;
1246 test_change_message( SPI_SETDOUBLECLKWIDTH, 0 );
1247 sprintf( buf, "%d", vals[i] );
1248 test_reg_key_ex( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1249 SPI_SETDOUBLECLKWIDTH_REGKEY2,
1250 SPI_SETDOUBLECLKWIDTH_VALNAME, buf );
1251 eq( GetSystemMetrics( SM_CXDOUBLECLK ), (int)vals[i],
1252 "SM_CXDOUBLECLK", "%d" );
1255 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, old_width, 0,
1256 SPIF_UPDATEINIFILE );
1257 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1260 static void test_SPI_SETDOUBLECLKHEIGHT( void ) /* 30 */
1262 BOOL rc;
1263 INT old_height;
1264 const UINT vals[]={0,10000};
1265 unsigned int i;
1267 trace("testing SPI_{GET,SET}DOUBLECLKHEIGHT\n");
1268 old_height = GetSystemMetrics( SM_CYDOUBLECLK );
1270 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1272 char buf[10];
1274 SetLastError(0xdeadbeef);
1275 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, vals[i], 0,
1276 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1277 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKHEIGHT"))
1278 return;
1280 test_change_message( SPI_SETDOUBLECLKHEIGHT, 0 );
1281 sprintf( buf, "%d", vals[i] );
1282 test_reg_key_ex( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1283 SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1284 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf );
1285 eq( GetSystemMetrics( SM_CYDOUBLECLK ), (int)vals[i],
1286 "SM_CYDOUBLECLK", "%d" );
1289 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, old_height, 0,
1290 SPIF_UPDATEINIFILE );
1291 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1294 static void test_SPI_SETDOUBLECLICKTIME( void ) /* 32 */
1296 BOOL rc;
1297 UINT curr_val;
1298 UINT saved_val;
1299 UINT old_time;
1300 char buf[10];
1302 trace("testing SPI_{GET,SET}DOUBLECLICKTIME\n");
1303 old_time = GetDoubleClickTime();
1305 curr_val = 0;
1306 SetLastError(0xdeadbeef);
1307 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1308 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1309 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLICKTIME"))
1310 return;
1312 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1313 sprintf( buf, "%d", curr_val );
1314 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1315 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1316 curr_val = 500; /* used value for 0 */
1317 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1319 curr_val = 1000;
1320 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1321 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1322 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1323 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1324 sprintf( buf, "%d", curr_val );
1325 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1326 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1327 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1329 saved_val = curr_val;
1331 curr_val = 0;
1332 SetDoubleClickTime( curr_val );
1333 sprintf( buf, "%d", saved_val );
1334 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1335 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1336 curr_val = 500; /* used value for 0 */
1337 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1339 curr_val = 1000;
1340 SetDoubleClickTime( curr_val );
1341 sprintf( buf, "%d", saved_val );
1342 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1343 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1344 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1346 rc=SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, old_time, 0, SPIF_UPDATEINIFILE);
1347 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1350 static void test_SPI_SETMOUSEBUTTONSWAP( void ) /* 33 */
1352 BOOL rc;
1353 BOOL old_b;
1354 const UINT vals[]={TRUE,FALSE};
1355 unsigned int i;
1357 trace("testing SPI_{GET,SET}MOUSEBUTTONSWAP\n");
1358 old_b = GetSystemMetrics( SM_SWAPBUTTON );
1360 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1362 SetLastError(0xdeadbeef);
1363 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[i], 0,
1364 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1365 if (!test_error_msg(rc,"SPI_SETMOUSEBUTTONSWAP")) return;
1367 test_change_message( SPI_SETMOUSEBUTTONSWAP, 0 );
1368 test_reg_key( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1369 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1370 vals[i] ? "1" : "0" );
1371 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i],
1372 "SM_SWAPBUTTON", "%d" );
1373 rc=SwapMouseButton((BOOL)vals[i^1]);
1374 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i^1],
1375 "SwapMouseButton", "%d" );
1376 ok( rc==(BOOL)vals[i], "SwapMouseButton does not return previous state (really %d)\n", rc );
1379 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, old_b, 0,
1380 SPIF_UPDATEINIFILE );
1381 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1384 static void test_SPI_SETFASTTASKSWITCH( void ) /* 36 */
1386 BOOL rc;
1387 BOOL v;
1389 trace("testing SPI_GETFASTTASKSWITCH\n");
1390 SetLastError(0xdeadbeef);
1391 rc=SystemParametersInfoA( SPI_GETFASTTASKSWITCH, 0, &v, 0 );
1392 if (!test_error_msg(rc,"SPI_{GET,SET}FASTTASKSWITCH"))
1393 return;
1395 /* there is not a single Windows platform on which SPI_GETFASTTASKSWITCH
1396 * works. That sure simplifies testing!
1400 static void test_SPI_SETDRAGFULLWINDOWS( void ) /* 37 */
1402 BOOL rc;
1403 BOOL old_b;
1404 const UINT vals[]={TRUE,FALSE};
1405 unsigned int i;
1407 trace("testing SPI_{GET,SET}DRAGFULLWINDOWS\n");
1408 SetLastError(0xdeadbeef);
1409 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &old_b, 0 );
1411 /* SPI_{GET,SET}DRAGFULLWINDOWS is not implemented on Win95 */
1412 if (!test_error_msg(rc,"SPI_{GET,SET}DRAGFULLWINDOWS"))
1413 return;
1415 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1417 UINT v;
1419 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, vals[i], 0,
1420 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1421 if (!test_error_msg(rc,"SPI_SETDRAGFULLWINDOWS")) return;
1422 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1423 test_change_message( SPI_SETDRAGFULLWINDOWS, 0 );
1424 test_reg_key( SPI_SETDRAGFULLWINDOWS_REGKEY,
1425 SPI_SETDRAGFULLWINDOWS_VALNAME,
1426 vals[i] ? "1" : "0" );
1428 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &v, 0 );
1429 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1430 eq( v, vals[i], "SPI_{GET,SET}DRAGFULLWINDOWS", "%d" );
1433 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, old_b, 0, SPIF_UPDATEINIFILE );
1434 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1437 #define test_reg_metric( KEY, VAL, val) \
1438 { INT regval;\
1439 regval = metricfromreg( KEY, VAL, dpi);\
1440 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1443 #define test_reg_metric2( KEY1, KEY2, VAL, val) \
1444 { INT regval;\
1445 regval = metricfromreg( KEY1, VAL, dpi);\
1446 if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\
1447 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1450 #define test_reg_font( KEY, VAL, LF) \
1451 { LOGFONTA lfreg;\
1452 lffromreg( KEY, VAL, &lfreg);\
1453 ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == MulDiv( lfreg.lfHeight, dpi, real_dpi ) : \
1454 MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\
1455 (LF).lfWidth == lfreg.lfWidth &&\
1456 (LF).lfWeight == lfreg.lfWeight &&\
1457 !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\
1458 , "wrong value \"%s\" in registry %d, %d\n", VAL, (LF).lfHeight, lfreg.lfHeight);\
1461 #define TEST_NONCLIENTMETRICS_REG( ncm) \
1462 /*FIXME: test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);*/\
1463 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\
1464 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\
1465 /*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\
1466 test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\
1467 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\
1468 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\
1469 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\
1470 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\
1471 test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\
1472 test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\
1473 test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\
1474 test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\
1475 test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont);
1477 /* get text metric height value for the specified logfont */
1478 static int get_tmheight( LOGFONTA *plf, int flag)
1480 TEXTMETRICA tm;
1481 HFONT hfont = CreateFontIndirectA( plf);
1482 hfont = SelectObject( hdc, hfont);
1483 GetTextMetricsA( hdc, &tm);
1484 hfont = SelectObject( hdc, hfont);
1485 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1488 static void test_GetSystemMetrics( void);
1489 static UINT smcxsmsize = 999999999;
1491 static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */
1493 BOOL rc;
1494 INT expect;
1495 NONCLIENTMETRICSA Ncmorig;
1496 NONCLIENTMETRICSA Ncmnew;
1497 NONCLIENTMETRICSA Ncmcur;
1498 NONCLIENTMETRICSA Ncmstart;
1500 Ncmorig.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1501 Ncmnew.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1502 Ncmcur.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1503 Ncmstart.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1505 trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n");
1506 change_counter = 0;
1507 SetLastError(0xdeadbeef);
1508 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmorig, FALSE );
1509 if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS"))
1510 return;
1511 Ncmstart = Ncmorig;
1512 smcxsmsize = Ncmstart.iSmCaptionWidth;
1513 /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if
1514 the caption font height is higher than the CaptionHeight field,
1515 the latter is adjusted accordingly. To be able to restore these setting
1516 accurately be restore the raw values. */
1517 Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, real_dpi);
1518 Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi);
1519 Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi);
1520 Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi);
1521 /* test registry entries */
1522 TEST_NONCLIENTMETRICS_REG( Ncmorig)
1523 Ncmorig.lfCaptionFont.lfHeight = MulDiv( Ncmorig.lfCaptionFont.lfHeight, real_dpi, dpi );
1525 /* make small changes */
1526 Ncmnew = Ncmstart;
1527 Ncmnew.iBorderWidth += 1;
1528 Ncmnew.iScrollWidth += 1;
1529 Ncmnew.iScrollHeight -= 1;
1530 Ncmnew.iCaptionWidth -= 2;
1531 Ncmnew.iCaptionHeight += 2;
1532 Ncmnew.lfCaptionFont.lfHeight +=1;
1533 Ncmnew.lfCaptionFont.lfWidth +=2;
1534 Ncmnew.lfCaptionFont.lfWeight +=1;
1535 Ncmnew.iSmCaptionWidth += 1;
1536 Ncmnew.iSmCaptionHeight += 2;
1537 Ncmnew.lfSmCaptionFont.lfHeight +=3;
1538 Ncmnew.lfSmCaptionFont.lfWidth -=1;
1539 Ncmnew.lfSmCaptionFont.lfWeight +=3;
1540 Ncmnew.iMenuWidth += 1;
1541 Ncmnew.iMenuHeight += 2;
1542 Ncmnew.lfMenuFont.lfHeight +=1;
1543 Ncmnew.lfMenuFont.lfWidth +=1;
1544 Ncmnew.lfMenuFont.lfWeight +=2;
1545 Ncmnew.lfStatusFont.lfHeight -=1;
1546 Ncmnew.lfStatusFont.lfWidth -=1;
1547 Ncmnew.lfStatusFont.lfWeight +=3;
1548 Ncmnew.lfMessageFont.lfHeight -=2;
1549 Ncmnew.lfMessageFont.lfWidth -=1;
1550 Ncmnew.lfMessageFont.lfWeight +=4;
1552 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1553 SPIF_SENDCHANGE);
1554 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return;
1555 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1556 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1557 /* get them back */
1558 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1559 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1560 /* test registry entries */
1561 TEST_NONCLIENTMETRICS_REG( Ncmcur)
1562 /* test the system metrics with these settings */
1563 test_GetSystemMetrics();
1564 /* now for something invalid: increase the {menu|caption|smcaption} fonts
1565 by a large amount will increase the {menu|caption|smcaption} height*/
1566 Ncmnew = Ncmstart;
1567 Ncmnew.lfMenuFont.lfHeight -= 8;
1568 Ncmnew.lfCaptionFont.lfHeight =-4;
1569 Ncmnew.lfSmCaptionFont.lfHeight -=10;
1570 /* also show that a few values are lo limited */
1571 Ncmnew.iCaptionWidth = 0;
1572 Ncmnew.iCaptionHeight = 0;
1573 Ncmnew.iScrollHeight = 0;
1574 Ncmnew.iScrollWidth = 0;
1576 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1577 SPIF_SENDCHANGE);
1578 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1579 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1580 /* raw values are in registry */
1581 TEST_NONCLIENTMETRICS_REG( Ncmnew)
1582 /* get them back */
1583 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1584 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1585 /* cooked values are returned */
1586 expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1));
1587 ok( Ncmcur.iMenuHeight == expect,
1588 "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect);
1589 expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0));
1590 ok( Ncmcur.iCaptionHeight == expect,
1591 "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect);
1592 expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0));
1593 ok( Ncmcur.iSmCaptionHeight == expect,
1594 "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect);
1596 /* iCaptionWidth depends on a version, could be 8, 12 (Vista, Win7), 13 */
1597 ok( (Ncmcur.iCaptionWidth >= 8 && Ncmcur.iCaptionWidth <= 13) ||
1598 Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */
1599 "CaptionWidth: %d expected from [8, 13] or %d\n", Ncmcur.iCaptionWidth, Ncmstart.iCaptionWidth);
1600 ok( Ncmcur.iScrollWidth == 8,
1601 "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth);
1602 ok( Ncmcur.iScrollHeight == 8,
1603 "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight);
1604 /* test the system metrics with these settings */
1605 test_GetSystemMetrics();
1606 /* restore */
1607 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA),
1608 &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1609 test_change_message( SPI_SETNONCLIENTMETRICS, 0 );
1610 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1611 /* test the system metrics with these settings */
1612 test_GetSystemMetrics();
1615 static void test_SPI_SETMINIMIZEDMETRICS( void ) /* 44 */
1617 BOOL rc;
1618 INT regval;
1619 MINIMIZEDMETRICS lpMm_orig;
1620 MINIMIZEDMETRICS lpMm_new;
1621 MINIMIZEDMETRICS lpMm_cur;
1623 lpMm_orig.cbSize = sizeof(MINIMIZEDMETRICS);
1624 lpMm_new.cbSize = sizeof(MINIMIZEDMETRICS);
1625 lpMm_cur.cbSize = sizeof(MINIMIZEDMETRICS);
1627 trace("testing SPI_{GET,SET}MINIMIZEDMETRICS\n");
1628 SetLastError(0xdeadbeef);
1629 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_orig, FALSE );
1630 if (!test_error_msg(rc,"SPI_{GET,SET}MINIMIZEDMETRICS"))
1631 return;
1632 /* Test registry. Note that it is perfectly valid for some fields to
1633 * not be set.
1635 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1636 ok( regval == -1 || regval == lpMm_orig.iWidth, "wrong value in registry %d, expected %d\n",
1637 regval, lpMm_orig.iWidth);
1638 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1639 ok( regval == -1 || regval == lpMm_orig.iHorzGap, "wrong value in registry %d, expected %d\n",
1640 regval, lpMm_orig.iHorzGap);
1641 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1642 ok( regval == -1 || regval == lpMm_orig.iVertGap, "wrong value in registry %d, expected %d\n",
1643 regval, lpMm_orig.iVertGap);
1644 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1645 ok( regval == -1 || regval == lpMm_orig.iArrange, "wrong value in registry %d, expected %d\n",
1646 regval, lpMm_orig.iArrange);
1647 /* set some new values */
1648 lpMm_cur.iWidth = 180;
1649 lpMm_cur.iHorzGap = 1;
1650 lpMm_cur.iVertGap = 1;
1651 lpMm_cur.iArrange = 5;
1652 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1653 &lpMm_cur, SPIF_UPDATEINIFILE );
1654 if (!test_error_msg(rc,"SPI_SETMINIMIZEDMETRICS")) return;
1655 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1656 /* read them back */
1657 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1658 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1659 /* and compare */
1660 eq( lpMm_new.iWidth, lpMm_cur.iWidth, "iWidth", "%d" );
1661 eq( lpMm_new.iHorzGap, lpMm_cur.iHorzGap, "iHorzGap", "%d" );
1662 eq( lpMm_new.iVertGap, lpMm_cur.iVertGap, "iVertGap", "%d" );
1663 eq( lpMm_new.iArrange, lpMm_cur.iArrange, "iArrange", "%d" );
1664 /* test registry */
1665 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1666 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1667 regval, lpMm_new.iWidth);
1668 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1669 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1670 regval, lpMm_new.iHorzGap);
1671 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1672 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1673 regval, lpMm_new.iVertGap);
1674 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1675 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1676 regval, lpMm_new.iArrange);
1677 /* test some system metrics */
1678 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1679 lpMm_new.iWidth, "iWidth", "%d" );
1680 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1681 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1682 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1683 lpMm_new.iVertGap, "iVertGap", "%d" );
1684 eq( GetSystemMetrics( SM_ARRANGE ),
1685 lpMm_new.iArrange, "iArrange", "%d" );
1686 /* now some really invalid settings */
1687 lpMm_cur.iWidth = -1;
1688 lpMm_cur.iHorzGap = -1;
1689 lpMm_cur.iVertGap = -1;
1690 lpMm_cur.iArrange = - 1;
1691 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1692 &lpMm_cur, SPIF_UPDATEINIFILE );
1693 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1694 /* read back */
1695 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1696 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1697 /* the width and H/V gaps have minimum 0, arrange is and'd with 0xf */
1698 eq( lpMm_new.iWidth, 0, "iWidth", "%d" );
1699 eq( lpMm_new.iHorzGap, 0, "iHorzGap", "%d" );
1700 eq( lpMm_new.iVertGap, 0, "iVertGap", "%d" );
1701 eq( lpMm_new.iArrange, 0xf & lpMm_cur.iArrange, "iArrange", "%d" );
1702 /* test registry */
1703 if (0)
1705 /* FIXME: cannot understand the results of this (11, 11, 11, 0) */
1706 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1707 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1708 regval, lpMm_new.iWidth);
1709 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1710 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1711 regval, lpMm_new.iHorzGap);
1712 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1713 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1714 regval, lpMm_new.iVertGap);
1715 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1716 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1717 regval, lpMm_new.iArrange);
1719 /* test some system metrics */
1720 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1721 lpMm_new.iWidth, "iWidth", "%d" );
1722 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1723 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1724 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1725 lpMm_new.iVertGap, "iVertGap", "%d" );
1726 eq( GetSystemMetrics( SM_ARRANGE ),
1727 lpMm_new.iArrange, "iArrange", "%d" );
1728 /* restore */
1729 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1730 &lpMm_orig, SPIF_UPDATEINIFILE );
1731 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1732 /* check that */
1733 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1734 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1735 eq( lpMm_new.iWidth, lpMm_orig.iWidth, "iWidth", "%d" );
1736 eq( lpMm_new.iHorzGap, lpMm_orig.iHorzGap, "iHorzGap", "%d" );
1737 eq( lpMm_new.iVertGap, lpMm_orig.iVertGap, "iVertGap", "%d" );
1738 eq( lpMm_new.iArrange, lpMm_orig.iArrange, "iArrange", "%d" );
1741 static void test_SPI_SETICONMETRICS( void ) /* 46 */
1743 BOOL rc, wrap;
1744 INT spacing;
1745 ICONMETRICSA im_orig;
1746 ICONMETRICSA im_new;
1747 ICONMETRICSA im_cur;
1748 INT regval;
1750 im_orig.cbSize = sizeof(ICONMETRICSA);
1751 im_new.cbSize = sizeof(ICONMETRICSA);
1752 im_cur.cbSize = sizeof(ICONMETRICSA);
1754 trace("testing SPI_{GET,SET}ICONMETRICS\n");
1755 SetLastError(0xdeadbeef);
1756 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE );
1757 if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS"))
1758 return;
1759 /* check some registry values */
1760 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1761 ok( regval==im_orig.iHorzSpacing || broken(regval == -1), /* nt4 */
1762 "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing);
1763 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1764 ok( regval==im_orig.iVertSpacing || broken(regval == -1), /* nt4 */
1765 "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing);
1766 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1767 if( regval != im_orig.iTitleWrap)
1768 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1769 ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap);
1771 /* change everything without creating something invalid ( Win9x would ignore
1772 * an invalid font for instance) */
1773 im_cur = im_orig;
1774 im_cur.iHorzSpacing += 10;
1775 im_cur.iVertSpacing += 6;
1776 im_cur.iTitleWrap = !im_cur.iTitleWrap;
1777 im_cur.lfFont.lfHeight += 1;
1778 im_cur.lfFont.lfWidth += 2;
1779 im_cur.lfFont.lfEscapement = 1;
1780 im_cur.lfFont.lfWeight = im_cur.lfFont.lfWeight > 100 ? 1 : 314;
1781 im_cur.lfFont.lfItalic = !im_cur.lfFont.lfItalic;
1782 im_cur.lfFont.lfStrikeOut = !im_cur.lfFont.lfStrikeOut;
1783 im_cur.lfFont.lfUnderline = !im_cur.lfFont.lfUnderline;
1784 im_cur.lfFont.lfCharSet = im_cur.lfFont.lfCharSet ? 0 : 1;
1785 im_cur.lfFont.lfOutPrecision = im_cur.lfFont.lfOutPrecision == OUT_DEFAULT_PRECIS ?
1786 OUT_TT_PRECIS : OUT_DEFAULT_PRECIS;
1787 im_cur.lfFont.lfClipPrecision ^= CLIP_LH_ANGLES;
1788 im_cur.lfFont.lfPitchAndFamily = im_cur.lfFont.lfPitchAndFamily ? 0 : 1;
1789 im_cur.lfFont.lfQuality = im_cur.lfFont.lfQuality == DEFAULT_QUALITY ?
1790 DRAFT_QUALITY : DEFAULT_QUALITY;
1791 if( strcmp( im_cur.lfFont.lfFaceName, "MS Serif"))
1792 strcpy( im_cur.lfFont.lfFaceName, "MS Serif");
1793 else
1794 strcpy( im_cur.lfFont.lfFaceName, "MS Sans Serif");
1796 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, SPIF_UPDATEINIFILE );
1797 if (!test_error_msg(rc,"SPI_SETICONMETRICS")) return;
1798 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1800 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1801 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1802 /* test GET <-> SETICONMETRICS */
1803 eq( im_new.iHorzSpacing, im_cur.iHorzSpacing, "iHorzSpacing", "%d" );
1804 eq( im_new.iVertSpacing, im_cur.iVertSpacing, "iVertSpacing", "%d" );
1805 eq( im_new.iTitleWrap, im_cur.iTitleWrap, "iTitleWrap", "%d" );
1806 eq( im_new.lfFont.lfHeight, im_cur.lfFont.lfHeight, "lfHeight", "%d" );
1807 eq( im_new.lfFont.lfWidth, im_cur.lfFont.lfWidth, "lfWidth", "%d" );
1808 eq( im_new.lfFont.lfEscapement, im_cur.lfFont.lfEscapement, "lfEscapement", "%d" );
1809 eq( im_new.lfFont.lfWeight, im_cur.lfFont.lfWeight, "lfWeight", "%d" );
1810 eq( im_new.lfFont.lfItalic, im_cur.lfFont.lfItalic, "lfItalic", "%d" );
1811 eq( im_new.lfFont.lfStrikeOut, im_cur.lfFont.lfStrikeOut, "lfStrikeOut", "%d" );
1812 eq( im_new.lfFont.lfUnderline, im_cur.lfFont.lfUnderline, "lfUnderline", "%d" );
1813 eq( im_new.lfFont.lfCharSet, im_cur.lfFont.lfCharSet, "lfCharSet", "%d" );
1814 eq( im_new.lfFont.lfOutPrecision, im_cur.lfFont.lfOutPrecision, "lfOutPrecision", "%d" );
1815 eq( im_new.lfFont.lfClipPrecision, im_cur.lfFont.lfClipPrecision, "lfClipPrecision", "%d" );
1816 eq( im_new.lfFont.lfPitchAndFamily, im_cur.lfFont.lfPitchAndFamily, "lfPitchAndFamily", "%d" );
1817 eq( im_new.lfFont.lfQuality, im_cur.lfFont.lfQuality, "lfQuality", "%d" );
1818 ok( !strcmp( im_new.lfFont.lfFaceName, im_cur.lfFont.lfFaceName),
1819 "wrong facename \"%s\", should be \"%s\"\n", im_new.lfFont.lfFaceName,
1820 im_cur.lfFont.lfFaceName);
1821 /* test some system metrics */
1822 eq( GetSystemMetrics( SM_CXICONSPACING ),
1823 im_new.iHorzSpacing, "iHorzSpacing", "%d" );
1824 eq( GetSystemMetrics( SM_CYICONSPACING ),
1825 im_new.iVertSpacing, "iVertSpacing", "%d" );
1826 /* check some registry values */
1827 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1828 ok( regval==im_cur.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iHorzSpacing);
1829 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1830 ok( regval==im_cur.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iVertSpacing);
1831 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1832 if( regval != im_cur.iTitleWrap)
1833 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1834 ok( regval==im_cur.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_cur.iTitleWrap);
1835 /* test some values from other SPI_GETxxx calls */
1836 rc = SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
1837 ok( rc && spacing == im_cur.iHorzSpacing,
1838 "SystemParametersInfoA( SPI_ICONHORIZONTALSPACING...) failed or returns wrong value %d instead of %d\n",
1839 spacing, im_cur.iHorzSpacing);
1840 rc = SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1841 ok( rc && spacing == im_cur.iVertSpacing,
1842 "SystemParametersInfoA( SPI_ICONVERTICALSPACING...) failed or returns wrong value %d instead of %d\n",
1843 spacing, im_cur.iVertSpacing);
1844 rc = SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &wrap, 0 );
1845 ok( rc && wrap == im_cur.iTitleWrap,
1846 "SystemParametersInfoA( SPI_GETICONTITLEWRAP...) failed or returns wrong value %d instead of %d\n",
1847 wrap, im_cur.iTitleWrap);
1848 /* restore old values */
1849 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig,SPIF_UPDATEINIFILE );
1850 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1852 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1853 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1855 eq( im_new.iHorzSpacing, im_orig.iHorzSpacing, "iHorzSpacing", "%d" );
1856 eq( im_new.iVertSpacing, im_orig.iVertSpacing, "iVertSpacing", "%d" );
1857 eq( im_new.iTitleWrap, im_orig.iTitleWrap, "iTitleWrap", "%d" );
1860 static void test_SPI_SETWORKAREA( void ) /* 47 */
1862 BOOL rc;
1863 RECT old_area;
1864 RECT area;
1865 RECT curr_val;
1867 trace("testing SPI_{GET,SET}WORKAREA\n");
1868 SetLastError(0xdeadbeef);
1869 rc=SystemParametersInfoA(SPI_GETWORKAREA, 0, &old_area, 0);
1870 if (!test_error_msg(rc,"SPI_{GET,SET}WORKAREA"))
1871 return;
1873 /* Modify the work area only minimally as this causes the icons that
1874 * fall outside it to be moved around thus requiring the user to
1875 * reposition them manually one by one.
1876 * Changing the work area by just one pixel should make this occurrence
1877 * reasonably unlikely.
1879 SetRect(&curr_val, old_area.left, old_area.top, old_area.right - 1, old_area.bottom - 1);
1880 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &curr_val,
1881 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1882 if (!test_error_msg(rc,"SPI_SETWORKAREA")) return;
1883 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1884 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1885 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1886 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1887 test_change_message( SPI_SETWORKAREA, 0);
1888 eq( area.left, curr_val.left, "left", "%d" );
1889 eq( area.top, curr_val.top, "top", "%d" );
1890 /* size may be rounded */
1891 ok( area.right >= curr_val.right - 16 && area.right < curr_val.right + 16,
1892 "right: got %d instead of %d\n", area.right, curr_val.right );
1893 ok( area.bottom >= curr_val.bottom - 16 && area.bottom < curr_val.bottom + 16,
1894 "bottom: got %d instead of %d\n", area.bottom, curr_val.bottom );
1895 curr_val = area;
1896 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &old_area,
1897 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1898 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1899 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1900 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1901 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1902 test_change_message( SPI_SETWORKAREA, 0 );
1903 eq( area.left, old_area.left, "left", "%d" );
1904 eq( area.top, old_area.top, "top", "%d" );
1905 /* size may be rounded */
1906 ok( area.right >= old_area.right - 16 && area.right < old_area.right + 16,
1907 "right: got %d instead of %d\n", area.right, old_area.right );
1908 ok( area.bottom >= old_area.bottom - 16 && area.bottom < old_area.bottom + 16,
1909 "bottom: got %d instead of %d\n", area.bottom, old_area.bottom );
1912 static void test_SPI_SETSHOWSOUNDS( void ) /* 57 */
1914 BOOL rc;
1915 BOOL old_b;
1916 const UINT vals[]={TRUE,FALSE};
1917 unsigned int i;
1919 trace("testing SPI_{GET,SET}SHOWSOUNDS\n");
1920 SetLastError(0xdeadbeef);
1921 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &old_b, 0 );
1922 /* SPI_{GET,SET}SHOWSOUNDS is completely broken on Win9x */
1923 if (!test_error_msg(rc,"SPI_{GET,SET}SHOWSOUNDS"))
1924 return;
1926 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1928 UINT v;
1930 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0,
1931 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1932 if (!test_error_msg(rc,"SPI_SETSHOWSOUNDS")) return;
1933 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1934 test_change_message( SPI_SETSHOWSOUNDS, 1 );
1935 test_reg_key( SPI_SETSHOWSOUNDS_REGKEY,
1936 SPI_SETSHOWSOUNDS_VALNAME,
1937 vals[i] ? "1" : "0" );
1939 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &v, 0 );
1940 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1941 eq( v, vals[i], "SPI_GETSHOWSOUNDS", "%d" );
1942 eq( GetSystemMetrics( SM_SHOWSOUNDS ), (int)vals[i],
1943 "SM_SHOWSOUNDS", "%d" );
1946 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, old_b, 0, SPIF_UPDATEINIFILE );
1947 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1950 static void test_SPI_SETKEYBOARDPREF( void ) /* 69 */
1952 BOOL rc;
1953 BOOL old_b;
1954 const UINT vals[]={TRUE,FALSE};
1955 unsigned int i;
1957 trace("testing SPI_{GET,SET}KEYBOARDPREF\n");
1958 SetLastError(0xdeadbeef);
1959 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &old_b, 0 );
1960 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDPREF"))
1961 return;
1963 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1965 BOOL v;
1967 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0,
1968 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1969 if (!test_error_msg(rc,"SPI_SETKEYBOARDPREF")) return;
1970 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1971 test_change_message( SPI_SETKEYBOARDPREF, 1 );
1972 test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY,
1973 SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY,
1974 vals[i] ? "1" : "0" );
1976 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &v, 0 );
1977 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1978 eq( v, (BOOL)vals[i], "SPI_GETKEYBOARDPREF", "%d" );
1981 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, old_b, 0, SPIF_UPDATEINIFILE );
1982 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1985 static void test_SPI_SETSCREENREADER( void ) /* 71 */
1987 BOOL rc;
1988 BOOL old_b;
1989 const UINT vals[]={TRUE,FALSE};
1990 unsigned int i;
1992 trace("testing SPI_{GET,SET}SCREENREADER\n");
1993 SetLastError(0xdeadbeef);
1994 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &old_b, 0 );
1995 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENREADER"))
1996 return;
1998 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2000 BOOL v;
2002 rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0,
2003 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2004 if (!test_error_msg(rc,"SPI_SETSCREENREADER")) return;
2005 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2006 test_change_message( SPI_SETSCREENREADER, 1 );
2007 test_reg_key_ex2_optional( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY,
2008 SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY,
2009 vals[i] ? "1" : "0" );
2011 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &v, 0 );
2012 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2013 eq( v, (BOOL)vals[i], "SPI_GETSCREENREADER", "%d" );
2016 rc=SystemParametersInfoA( SPI_SETSCREENREADER, old_b, 0, SPIF_UPDATEINIFILE );
2017 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2020 static void test_SPI_SETFONTSMOOTHING( void ) /* 75 */
2022 BOOL rc;
2023 BOOL old_b;
2024 DWORD old_type, old_contrast, old_orient;
2025 const UINT vals[]={0xffffffff,0,1,2};
2026 unsigned int i;
2028 trace("testing SPI_{GET,SET}FONTSMOOTHING\n");
2029 if( iswin9x) return; /* 95/98/ME don't seem to implement this fully */
2030 SetLastError(0xdeadbeef);
2031 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &old_b, 0 );
2032 if (!test_error_msg(rc,"SPI_{GET,SET}FONTSMOOTHING"))
2033 return;
2034 SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &old_type, 0 );
2035 SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &old_contrast, 0 );
2036 SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &old_orient, 0 );
2038 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2040 UINT v;
2042 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, vals[i], 0,
2043 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2044 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHING")) return;
2045 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2046 test_change_message( SPI_SETFONTSMOOTHING, 0 );
2047 test_reg_key( SPI_SETFONTSMOOTHING_REGKEY,
2048 SPI_SETFONTSMOOTHING_VALNAME,
2049 vals[i] ? "2" : "0" );
2051 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, 0, UlongToPtr(vals[i]),
2052 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2053 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGTYPE")) return;
2054 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2055 test_change_message( SPI_SETFONTSMOOTHINGTYPE, 0 );
2056 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2057 SPI_SETFONTSMOOTHINGTYPE_VALNAME, &vals[i] );
2059 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, 0, UlongToPtr(vals[i]),
2060 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2061 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGCONTRAST")) return;
2062 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2063 test_change_message( SPI_SETFONTSMOOTHINGCONTRAST, 0 );
2064 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2065 SPI_SETFONTSMOOTHINGCONTRAST_VALNAME, &vals[i] );
2067 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, 0, UlongToPtr(vals[i]),
2068 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2069 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGORIENTATION")) return;
2070 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2071 test_change_message( SPI_SETFONTSMOOTHINGORIENTATION, 0 );
2072 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2073 SPI_SETFONTSMOOTHINGORIENTATION_VALNAME, &vals[i] );
2075 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &v, 0 );
2076 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2077 eq( v, vals[i] ? 1 : 0, "SPI_GETFONTSMOOTHING", "%d" );
2079 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &v, 0 );
2080 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2081 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2083 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &v, 0 );
2084 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2085 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2087 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &v, 0 );
2088 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2089 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2092 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, old_b, 0, SPIF_UPDATEINIFILE );
2093 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2094 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, old_type, 0, SPIF_UPDATEINIFILE );
2095 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2096 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, old_contrast, 0, SPIF_UPDATEINIFILE );
2097 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2098 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, old_orient, 0, SPIF_UPDATEINIFILE );
2099 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2102 static void test_SPI_SETLOWPOWERACTIVE( void ) /* 85 */
2104 BOOL rc;
2105 BOOL old_b;
2106 const UINT vals[]={TRUE,FALSE};
2107 unsigned int i;
2109 trace("testing SPI_{GET,SET}LOWPOWERACTIVE\n");
2110 SetLastError(0xdeadbeef);
2111 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &old_b, 0 );
2112 if (!test_error_msg(rc,"SPI_{GET,SET}LOWPOWERACTIVE"))
2113 return;
2115 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2117 UINT v;
2119 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0,
2120 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2121 if (!test_error_msg(rc,"SPI_SETLOWPOWERACTIVE")) return;
2122 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2123 test_change_message( SPI_SETLOWPOWERACTIVE, 1 );
2124 test_reg_key_optional( SPI_SETLOWPOWERACTIVE_REGKEY,
2125 SPI_SETLOWPOWERACTIVE_VALNAME,
2126 vals[i] ? "1" : "0" );
2128 /* SPI_SETLOWPOWERACTIVE is not persistent in win2k3 and above */
2129 v = 0xdeadbeef;
2130 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 );
2131 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2132 ok(v == vals[i] ||
2133 broken(v == (0xdead0000 | vals[i])) || /* win98 only sets the low word */
2134 v == 0, /* win2k3 */
2135 "SPI_GETLOWPOWERACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2138 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2139 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2142 static void test_SPI_SETPOWEROFFACTIVE( void ) /* 86 */
2144 BOOL rc;
2145 BOOL old_b;
2146 const UINT vals[]={TRUE,FALSE};
2147 unsigned int i;
2149 trace("testing SPI_{GET,SET}POWEROFFACTIVE\n");
2150 SetLastError(0xdeadbeef);
2151 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &old_b, 0 );
2152 if (!test_error_msg(rc,"SPI_{GET,SET}POWEROFFACTIVE"))
2153 return;
2155 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2157 UINT v;
2159 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0,
2160 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2161 if (!test_error_msg(rc,"SPI_SETPOWEROFFACTIVE")) return;
2162 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2163 test_change_message( SPI_SETPOWEROFFACTIVE, 1 );
2164 test_reg_key_optional( SPI_SETPOWEROFFACTIVE_REGKEY,
2165 SPI_SETPOWEROFFACTIVE_VALNAME,
2166 vals[i] ? "1" : "0" );
2168 /* SPI_SETPOWEROFFACTIVE is not persistent in win2k3 and above */
2169 v = 0xdeadbeef;
2170 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 );
2171 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2172 ok(v == vals[i] ||
2173 broken(v == (0xdead0000 | vals[i])) || /* win98 only sets the low word */
2174 v == 0, /* win2k3 */
2175 "SPI_GETPOWEROFFACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2178 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2179 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2182 static void test_SPI_SETSNAPTODEFBUTTON( void ) /* 95 */
2184 BOOL rc;
2185 BOOL old_b;
2186 const UINT vals[]={TRUE,FALSE};
2187 unsigned int i;
2189 trace("testing SPI_{GET,SET}SNAPTODEFBUTTON\n");
2190 SetLastError(0xdeadbeef);
2191 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &old_b, 0 );
2192 if (!test_error_msg(rc,"SPI_GETSNAPTODEFBUTTON"))
2193 return;
2195 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2197 UINT v;
2199 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, vals[i], 0,
2200 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2201 if (!test_error_msg(rc,"SPI_SETSNAPTODEFBUTTON")) return;
2202 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2203 test_change_message( SPI_SETSNAPTODEFBUTTON, 0 );
2204 test_reg_key_optional( SPI_SETSNAPTODEFBUTTON_REGKEY,
2205 SPI_SETSNAPTODEFBUTTON_VALNAME,
2206 vals[i] ? "1" : "0" );
2208 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &v, 0 );
2209 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2210 eq( v, vals[i], "SPI_GETSNAPTODEFBUTTON", "%d" );
2213 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, old_b, 0, SPIF_UPDATEINIFILE );
2214 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2217 static void test_SPI_SETMOUSEHOVERWIDTH( void ) /* 99 */
2219 BOOL rc;
2220 UINT old_width;
2221 const UINT vals[]={0,32767};
2222 unsigned int i;
2224 trace("testing SPI_{GET,SET}MOUSEHOVERWIDTH\n");
2225 SetLastError(0xdeadbeef);
2226 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &old_width, 0 );
2227 /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2228 * what MSDN states (Verified on Win98SE)
2230 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERWIDTH"))
2231 return;
2233 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2235 UINT v;
2236 char buf[10];
2238 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, vals[i], 0,
2239 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2240 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERWIDTH")) return;
2241 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2242 test_change_message( SPI_SETMOUSEHOVERWIDTH, 0 );
2243 sprintf( buf, "%d", vals[i] );
2244 test_reg_key( SPI_SETMOUSEHOVERWIDTH_REGKEY,
2245 SPI_SETMOUSEHOVERWIDTH_VALNAME, buf );
2247 SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &v, 0 );
2248 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2249 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERWIDTH", "%d" );
2252 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, old_width, 0,
2253 SPIF_UPDATEINIFILE );
2254 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2257 static void test_SPI_SETMOUSEHOVERHEIGHT( void ) /* 101 */
2259 BOOL rc;
2260 UINT old_height;
2261 const UINT vals[]={0,32767};
2262 unsigned int i;
2264 trace("testing SPI_{GET,SET}MOUSEHOVERHEIGHT\n");
2265 SetLastError(0xdeadbeef);
2266 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &old_height, 0 );
2267 /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2268 * what MSDN states (Verified on Win98SE)
2270 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERHEIGHT"))
2271 return;
2273 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2275 UINT v;
2276 char buf[10];
2278 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, vals[i], 0,
2279 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2280 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERHEIGHT")) return;
2281 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2282 test_change_message( SPI_SETMOUSEHOVERHEIGHT, 0 );
2283 sprintf( buf, "%d", vals[i] );
2284 test_reg_key( SPI_SETMOUSEHOVERHEIGHT_REGKEY,
2285 SPI_SETMOUSEHOVERHEIGHT_VALNAME, buf );
2287 SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &v, 0 );
2288 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2289 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERHEIGHT", "%d" );
2292 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, old_height, 0,
2293 SPIF_UPDATEINIFILE );
2294 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2297 static void test_SPI_SETMOUSEHOVERTIME( void ) /* 103 */
2299 BOOL rc;
2300 UINT old_time;
2302 /* Windows XP accepts 10 as the minimum hover time. Any value below will be
2303 * defaulted to a value of 10 automatically.
2305 const UINT vals[]={10,32767};
2306 unsigned int i;
2308 trace("testing SPI_{GET,SET}MOUSEHOVERTIME\n");
2309 SetLastError(0xdeadbeef);
2310 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &old_time, 0 );
2311 /* SPI_{GET,SET}MOUSEHOVERWIDTH does not seem to be supported on Win9x despite
2312 * what MSDN states (Verified on Win98SE)
2314 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERTIME"))
2315 return;
2317 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2319 UINT v;
2320 char buf[10];
2322 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, vals[i], 0,
2323 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2324 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERTIME")) return;
2325 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2326 test_change_message( SPI_SETMOUSEHOVERTIME, 0 );
2327 sprintf( buf, "%d", vals[i] );
2328 test_reg_key( SPI_SETMOUSEHOVERTIME_REGKEY,
2329 SPI_SETMOUSEHOVERTIME_VALNAME, buf );
2331 SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &v, 0 );
2332 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2333 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERTIME", "%d" );
2336 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, old_time, 0,
2337 SPIF_UPDATEINIFILE );
2338 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2341 static void test_SPI_SETWHEELSCROLLLINES( void ) /* 105 */
2343 BOOL rc;
2344 UINT old_lines;
2345 const UINT vals[]={0,32767};
2346 unsigned int i;
2348 trace("testing SPI_{GET,SET}WHEELSCROLLLINES\n");
2349 SetLastError(0xdeadbeef);
2350 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &old_lines, 0 );
2352 /* SPI_{GET,SET}WHEELSCROLLLINES not supported on Windows 95 */
2353 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLLINES"))
2354 return;
2356 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2358 UINT v;
2359 char buf[10];
2361 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, vals[i], 0,
2362 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2363 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLLINES")) return;
2364 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2365 test_change_message( SPI_SETWHEELSCROLLLINES, 0 );
2366 sprintf( buf, "%d", vals[i] );
2367 test_reg_key( SPI_SETMOUSESCROLLLINES_REGKEY,
2368 SPI_SETMOUSESCROLLLINES_VALNAME, buf );
2370 SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &v, 0 );
2371 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2372 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLLINES", "%d" );
2375 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, old_lines, 0,
2376 SPIF_UPDATEINIFILE );
2377 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2380 static void test_SPI_SETMENUSHOWDELAY( void ) /* 107 */
2382 BOOL rc;
2383 UINT old_delay;
2384 const UINT vals[]={0,32767};
2385 unsigned int i;
2387 trace("testing SPI_{GET,SET}MENUSHOWDELAY\n");
2388 SetLastError(0xdeadbeef);
2389 rc=SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &old_delay, 0 );
2391 /* SPI_{GET,SET}MENUSHOWDELAY not supported on Windows 95 */
2392 if (!test_error_msg(rc,"SPI_{GET,SET}MENUSHOWDELAY"))
2393 return;
2395 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2397 UINT v;
2398 char buf[10];
2400 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, vals[i], 0,
2401 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2402 if (!test_error_msg(rc,"SPI_SETMENUSHOWDELAY")) return;
2403 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2404 test_change_message( SPI_SETMENUSHOWDELAY, 0 );
2405 sprintf( buf, "%d", vals[i] );
2406 test_reg_key( SPI_SETMENUSHOWDELAY_REGKEY,
2407 SPI_SETMENUSHOWDELAY_VALNAME, buf );
2409 SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &v, 0 );
2410 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2411 eq( v, vals[i], "SPI_{GET,SET}MENUSHOWDELAY", "%d" );
2414 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, old_delay, 0,
2415 SPIF_UPDATEINIFILE );
2416 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2419 static void test_SPI_SETWHEELSCROLLCHARS( void ) /* 108 */
2421 BOOL rc;
2422 UINT old_chars;
2423 const UINT vals[]={32767,0};
2424 unsigned int i;
2426 trace("testing SPI_{GET,SET}WHEELSCROLLCHARS\n");
2427 SetLastError(0xdeadbeef);
2428 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &old_chars, 0 );
2430 /* SPI_{GET,SET}WHEELSCROLLCHARS not supported on Windows 95 */
2431 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLCHARS"))
2432 return;
2434 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2436 UINT v;
2437 char buf[10];
2439 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, vals[i], 0,
2440 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2441 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLCHARS")) return;
2442 test_change_message( SPI_SETWHEELSCROLLCHARS, 0 );
2443 sprintf( buf, "%d", vals[i] );
2444 test_reg_key( SPI_SETMOUSESCROLLCHARS_REGKEY,
2445 SPI_SETMOUSESCROLLCHARS_VALNAME, buf );
2447 SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &v, 0 );
2448 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2449 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLCHARS", "%d" );
2452 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, old_chars, 0,
2453 SPIF_UPDATEINIFILE );
2454 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2457 static void test_SPI_SETWALLPAPER( void ) /* 115 */
2459 BOOL rc;
2460 char oldval[260];
2461 char newval[260];
2463 trace("testing SPI_{GET,SET}DESKWALLPAPER\n");
2464 SetLastError(0xdeadbeef);
2465 rc=SystemParametersInfoA(SPI_GETDESKWALLPAPER, 260, oldval, 0);
2466 /* SPI_{GET,SET}DESKWALLPAPER is completely broken on Win9x and
2467 * unimplemented on NT4
2469 if (!test_error_msg(rc,"SPI_{GET,SET}DESKWALLPAPER"))
2470 return;
2472 strcpy(newval, "");
2473 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, newval, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
2474 if (!test_error_msg(rc,"SPI_SETDESKWALLPAPER")) return;
2475 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
2476 test_change_message(SPI_SETDESKWALLPAPER, 0);
2478 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, oldval, SPIF_UPDATEINIFILE);
2479 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2481 test_reg_key(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, oldval);
2484 static void test_WM_DISPLAYCHANGE(void)
2486 DEVMODEA mode, startmode;
2487 int start_bpp, last_set_bpp = 0;
2488 int test_bpps[] = {8, 16, 24, 32}, i;
2489 LONG change_ret;
2490 DWORD wait_ret;
2492 if (!pChangeDisplaySettingsExA)
2494 win_skip("ChangeDisplaySettingsExA is not available\n");
2495 return;
2498 displaychange_test_active = TRUE;
2500 memset(&startmode, 0, sizeof(startmode));
2501 startmode.dmSize = sizeof(startmode);
2502 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &startmode);
2503 start_bpp = startmode.dmBitsPerPel;
2505 displaychange_sem = CreateSemaphoreW(NULL, 0, 1, NULL);
2507 for(i = 0; i < sizeof(test_bpps)/sizeof(test_bpps[0]); i++) {
2508 last_bpp = -1;
2510 memset(&mode, 0, sizeof(mode));
2511 mode.dmSize = sizeof(mode);
2512 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2513 mode.dmBitsPerPel = test_bpps[i];
2514 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2515 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2517 change_counter = 0; /* This sends a SETTINGSCHANGE message as well in which we aren't interested */
2518 displaychange_ok = TRUE;
2519 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2520 /* Wait quite long for the message, screen setting changes can take some time */
2521 if(change_ret == DISP_CHANGE_SUCCESSFUL) {
2522 wait_ret = WaitForSingleObject(displaychange_sem, 10000);
2523 /* we may not get a notification if nothing changed */
2524 if (wait_ret == WAIT_TIMEOUT && !last_set_bpp && start_bpp == test_bpps[i])
2525 continue;
2526 ok(wait_ret == WAIT_OBJECT_0, "Waiting for the WM_DISPLAYCHANGE message timed out\n");
2528 displaychange_ok = FALSE;
2530 if(change_ret != DISP_CHANGE_SUCCESSFUL) {
2531 skip("Setting depth %d failed(ret = %d)\n", test_bpps[i], change_ret);
2532 ok(last_bpp == -1, "WM_DISPLAYCHANGE was sent with wParam %d despite mode change failure\n", last_bpp);
2533 continue;
2536 todo_wine_if(start_bpp != test_bpps[i]) {
2537 ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
2539 last_set_bpp = test_bpps[i];
2542 if(start_bpp != last_set_bpp && last_set_bpp != 0) {
2543 memset(&mode, 0, sizeof(mode));
2544 mode.dmSize = sizeof(mode);
2545 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2546 mode.dmBitsPerPel = start_bpp;
2547 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2548 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2550 displaychange_ok = TRUE;
2551 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2552 WaitForSingleObject(displaychange_sem, 10000);
2553 displaychange_ok = FALSE;
2554 CloseHandle(displaychange_sem);
2555 displaychange_sem = 0;
2558 displaychange_test_active = FALSE;
2562 * Registry entries for the system parameters.
2563 * Names are created by 'SET' flags names.
2564 * We assume that corresponding 'GET' entries use the same registry keys.
2566 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
2568 test_SPI_SETBEEP(); /* 1 */
2569 test_SPI_SETMOUSE(); /* 4 */
2570 test_SPI_SETBORDER(); /* 6 */
2571 test_SPI_SETKEYBOARDSPEED(); /* 10 */
2572 test_SPI_ICONHORIZONTALSPACING(); /* 13 */
2573 test_SPI_SETSCREENSAVETIMEOUT(); /* 14 */
2574 test_SPI_SETSCREENSAVEACTIVE(); /* 17 */
2575 test_SPI_SETGRIDGRANULARITY(); /* 19 */
2576 test_SPI_SETKEYBOARDDELAY(); /* 23 */
2577 test_SPI_ICONVERTICALSPACING(); /* 24 */
2578 test_SPI_SETICONTITLEWRAP(); /* 26 */
2579 test_SPI_SETMENUDROPALIGNMENT(); /* 28 */
2580 test_SPI_SETDOUBLECLKWIDTH(); /* 29 */
2581 test_SPI_SETDOUBLECLKHEIGHT(); /* 30 */
2582 test_SPI_SETDOUBLECLICKTIME(); /* 32 */
2583 test_SPI_SETMOUSEBUTTONSWAP(); /* 33 */
2584 test_SPI_SETFASTTASKSWITCH(); /* 36 */
2585 test_SPI_SETDRAGFULLWINDOWS(); /* 37 */
2586 /* test_WM_DISPLAYCHANGE seems to be somewhat buggy on
2587 * some versions of Windows (Vista, Win2k8, Win7B) in that
2588 * not all metrics are properly restored. Problems are
2589 * SM_CXMAXTRACK, SM_CYMAXTRACK
2590 * Fortunately setting the Non-Client metrics like in
2591 * test_SPI_SETNONCLIENTMETRICS will correct this. That is why
2592 * we do the DISPLAY change now... */
2593 test_WM_DISPLAYCHANGE();
2594 test_SPI_SETNONCLIENTMETRICS(); /* 42 */
2595 test_SPI_SETMINIMIZEDMETRICS(); /* 44 */
2596 test_SPI_SETICONMETRICS(); /* 46 */
2597 test_SPI_SETWORKAREA(); /* 47 */
2598 test_SPI_SETSHOWSOUNDS(); /* 57 */
2599 test_SPI_SETKEYBOARDPREF(); /* 69 */
2600 test_SPI_SETSCREENREADER(); /* 71 */
2601 test_SPI_SETFONTSMOOTHING(); /* 75 */
2602 test_SPI_SETLOWPOWERACTIVE(); /* 85 */
2603 test_SPI_SETPOWEROFFACTIVE(); /* 86 */
2604 test_SPI_SETSNAPTODEFBUTTON(); /* 95 */
2605 test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */
2606 test_SPI_SETMOUSEHOVERHEIGHT(); /* 101 */
2607 test_SPI_SETMOUSEHOVERTIME(); /* 103 */
2608 test_SPI_SETWHEELSCROLLLINES(); /* 105 */
2609 test_SPI_SETMENUSHOWDELAY(); /* 107 */
2610 test_SPI_SETWHEELSCROLLCHARS(); /* 108 */
2611 test_SPI_SETWALLPAPER(); /* 115 */
2614 SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
2615 return 0;
2618 /* test calculation of GetSystemMetrics values (mostly) from non client metrics,
2619 * icon metrics and minimized metrics.
2622 /* copied from wine's GdiGetCharDimensions, which is not available on most
2623 * windows versions */
2624 static LONG _GdiGetCharDimensions(HDC hdc, LPTEXTMETRICA lptm, LONG *height)
2626 SIZE sz;
2627 static const CHAR alphabet[] = {
2628 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
2629 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
2630 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
2632 if(lptm && !GetTextMetricsA(hdc, lptm)) return 0;
2634 if(!GetTextExtentPointA(hdc, alphabet, 52, &sz)) return 0;
2636 if (height) *height = sz.cy;
2637 return (sz.cx / 26 + 1) / 2;
2640 /* get text metrics and/or "average" char width of the specified logfont
2641 * for the specified dc */
2642 static void get_text_metr_size( HDC hdc, LOGFONTA *plf, TEXTMETRICA * ptm, UINT *psz)
2644 HFONT hfont, hfontsav;
2645 TEXTMETRICA tm;
2646 if( !ptm) ptm = &tm;
2647 hfont = CreateFontIndirectA( plf);
2648 if( !hfont || ( hfontsav = SelectObject( hdc, hfont)) == NULL ) {
2649 ptm->tmHeight = -1;
2650 if( psz) *psz = 10;
2651 if( hfont) DeleteObject( hfont);
2652 return;
2654 GetTextMetricsA( hdc, ptm);
2655 if( psz)
2656 if( !(*psz = _GdiGetCharDimensions( hdc, ptm, NULL)))
2657 *psz = 10;
2658 SelectObject( hdc, hfontsav);
2659 DeleteObject( hfont);
2662 static int gsm_error_ctr;
2664 #define ok_gsm( i, e)\
2666 int exp = (e);\
2667 int act = GetSystemMetrics( (i));\
2668 if( exp != act) gsm_error_ctr++;\
2669 ok( !( exp != act),"GetSystemMetrics(%s): expected %d actual %d\n", #i, exp,act);\
2671 #define ok_gsm_2( i, e1, e2)\
2673 int exp1 = (e1);\
2674 int exp2 = (e2);\
2675 int act = GetSystemMetrics( (i));\
2676 if( exp1 != act && exp2 != act) gsm_error_ctr++;\
2677 ok( !( exp1 != act && exp2 != act), "GetSystemMetrics(%s): expected %d or %d actual %d\n", #i, exp1, exp2, act);\
2679 #define ok_gsm_3( i, e1, e2, e3)\
2681 int exp1 = (e1);\
2682 int exp2 = (e2);\
2683 int exp3 = (e3);\
2684 int act = GetSystemMetrics( (i));\
2685 if( exp1 != act && exp2 != act && exp3 != act) gsm_error_ctr++;\
2686 ok( !( exp1 != act && exp2 != act && exp3 != act),"GetSystemMetrics(%s): expected %d or %d or %d actual %d\n", #i, exp1, exp2, exp3, act);\
2689 static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
2691 return lstrcmpiA(elf->lfFaceName, (const char *)lparam);
2694 static BOOL is_font_enumerated(const char *name)
2696 HDC hdc = CreateCompatibleDC(0);
2697 BOOL ret = FALSE;
2699 if (!EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)name))
2700 ret = TRUE;
2702 DeleteDC(hdc);
2703 return ret;
2706 static int get_cursor_size( int size )
2708 /* only certain sizes are allowed for cursors */
2709 if (size >= 64) return 64;
2710 if (size >= 48) return 48;
2711 return 32;
2714 static void test_GetSystemMetrics( void)
2716 TEXTMETRICA tmMenuFont;
2717 UINT IconSpacing, IconVerticalSpacing;
2718 BOOL rc;
2720 HDC hdc = CreateICA( "Display", 0, 0, 0);
2721 UINT avcwCaption;
2722 INT CaptionWidthfromreg, smicon, broken_val;
2723 MINIMIZEDMETRICS minim;
2724 NONCLIENTMETRICSA ncm;
2725 SIZE screen;
2727 assert(sizeof(ncm) == 344);
2729 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2730 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2731 ok(rc, "SystemParametersInfoA failed\n");
2733 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) - 1;
2734 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2735 ok(!rc, "SystemParametersInfoA should fail\n");
2737 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) + 1;
2738 SetLastError(0xdeadbeef);
2739 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2740 ok(!rc, "SystemParametersInfoA should fail\n");
2742 ncm.cbSize = sizeof(ncm); /* Vista added padding */
2743 SetLastError(0xdeadbeef);
2744 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2745 ok(rc || broken(!rc) /* before Vista */, "SystemParametersInfoA failed\n");
2747 minim.cbSize = sizeof( minim);
2748 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2749 SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0);
2750 rc = SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2751 if( !rc) {
2752 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
2753 return;
2756 ok(is_font_enumerated(ncm.lfCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfCaptionFont.lfFaceName);
2757 ok(is_font_enumerated(ncm.lfSmCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfSmCaptionFont.lfFaceName);
2758 ok(is_font_enumerated(ncm.lfMenuFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMenuFont.lfFaceName);
2759 ok(is_font_enumerated(ncm.lfStatusFont.lfFaceName), "font %s should be enumerated\n", ncm.lfStatusFont.lfFaceName);
2760 ok(is_font_enumerated(ncm.lfMessageFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMessageFont.lfFaceName);
2762 /* CaptionWidth from the registry may have different value of iCaptionWidth
2763 * from the non client metrics (observed on WinXP) */
2764 CaptionWidthfromreg = metricfromreg(
2765 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
2766 get_text_metr_size( hdc, &ncm.lfMenuFont, &tmMenuFont, NULL);
2767 get_text_metr_size( hdc, &ncm.lfCaptionFont, NULL, &avcwCaption);
2768 /* FIXME: use icon metric */
2769 if( !SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &IconVerticalSpacing, 0))
2770 IconVerticalSpacing = 0;
2771 if( !SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &IconSpacing, 0 ))
2772 IconSpacing = 0;
2773 /* reset error counters */
2774 gsm_error_ctr = 0;
2776 /* the tests: */
2778 /* SM_CXSCREEN, cannot test these two */
2779 /* SM_CYSCREEN */
2780 ok_gsm( SM_CXVSCROLL, ncm.iScrollWidth);
2781 ok_gsm( SM_CYHSCROLL, ncm.iScrollWidth);
2782 ok_gsm( SM_CYCAPTION, ncm.iCaptionHeight+1);
2783 ok_gsm( SM_CXBORDER, 1);
2784 ok_gsm( SM_CYBORDER, 1);
2785 ok_gsm( SM_CXDLGFRAME, 3);
2786 ok_gsm( SM_CYDLGFRAME, 3);
2787 ok_gsm( SM_CYVTHUMB, ncm.iScrollHeight);
2788 ok_gsm( SM_CXHTHUMB, ncm.iScrollHeight);
2789 /* These don't depend on the Shell Icon Size registry value */
2790 ok_gsm( SM_CXICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2791 ok_gsm( SM_CYICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2792 ok_gsm( SM_CXCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2793 ok_gsm( SM_CYCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2794 ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1);
2795 ok_gsm( SM_CXFULLSCREEN,
2796 GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME));
2797 ok_gsm( SM_CYFULLSCREEN,
2798 GetSystemMetrics( SM_CYMAXIMIZED) - GetSystemMetrics( SM_CYMIN));
2799 /* SM_CYKANJIWINDOW */
2800 /* SM_MOUSEPRESENT */
2801 ok_gsm( SM_CYVSCROLL, ncm.iScrollHeight);
2802 ok_gsm( SM_CXHSCROLL, ncm.iScrollHeight);
2803 /* SM_DEBUG */
2804 /* SM_SWAPBUTTON */
2805 /* SM_RESERVED1 */
2806 /* SM_RESERVED2 */
2807 /* SM_RESERVED3 */
2808 /* SM_RESERVED4 */
2809 ok_gsm( SM_CXMIN, 3 * max( CaptionWidthfromreg >= 0 ? CaptionWidthfromreg : ncm.iCaptionWidth, 8) +
2810 GetSystemMetrics( SM_CYSIZE) + 4 + 4 * avcwCaption + 2 * GetSystemMetrics( SM_CXFRAME));
2811 ok_gsm( SM_CYMIN, GetSystemMetrics( SM_CYCAPTION) +
2812 2 * GetSystemMetrics( SM_CYFRAME));
2813 ok_gsm_2( SM_CXSIZE,
2814 ncm.iCaptionWidth, /* classic/standard windows style */
2815 GetSystemMetrics( SM_CYCAPTION) - 1 /* WinXP style */
2817 ok_gsm( SM_CYSIZE, ncm.iCaptionHeight);
2818 ok_gsm( SM_CXFRAME, ncm.iBorderWidth + 3);
2819 ok_gsm( SM_CYFRAME, ncm.iBorderWidth + 3);
2820 ok_gsm( SM_CXMINTRACK, GetSystemMetrics( SM_CXMIN));
2821 ok_gsm( SM_CYMINTRACK, GetSystemMetrics( SM_CYMIN));
2822 /* SM_CXDOUBLECLK */
2823 /* SM_CYDOUBLECLK */
2824 if( IconSpacing) ok_gsm( SM_CXICONSPACING, IconSpacing);
2825 if( IconVerticalSpacing) ok_gsm( SM_CYICONSPACING, IconVerticalSpacing);
2826 /* SM_MENUDROPALIGNMENT */
2827 /* SM_PENWINDOWS */
2828 /* SM_DBCSENABLED */
2829 /* SM_CMOUSEBUTTONS */
2830 /* SM_SECURE */
2831 ok_gsm( SM_CXEDGE, 2);
2832 ok_gsm( SM_CYEDGE, 2);
2833 /* sign-extension for iHorzGap/iVertGap is broken on Win9x */
2834 ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + (short)minim.iHorzGap );
2835 ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + (short)minim.iVertGap );
2837 smicon = MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI );
2838 if (!pIsProcessDPIAware || pIsProcessDPIAware())
2839 smicon = max( min( smicon, CaptionWidthfromreg - 2), 4 ) & ~1;
2840 todo_wine_if( real_dpi == dpi && smicon != (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI) & ~1) )
2842 broken_val = (min( ncm.iCaptionHeight, CaptionWidthfromreg ) - 2) & ~1;
2843 broken_val = min( broken_val, 20 );
2845 if (smicon == 4)
2847 ok_gsm_2( SM_CXSMICON, smicon, 6 );
2848 ok_gsm_2( SM_CYSMICON, smicon, 6 );
2850 else if (smicon < broken_val)
2852 ok_gsm_2( SM_CXSMICON, smicon, broken_val );
2853 ok_gsm_2( SM_CYSMICON, smicon, broken_val );
2855 else
2857 ok_gsm( SM_CXSMICON, smicon );
2858 ok_gsm( SM_CYSMICON, smicon );
2862 ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1);
2863 ok_gsm_3( SM_CXSMSIZE,
2864 ncm.iSmCaptionWidth, /* classic/standard windows style */
2865 GetSystemMetrics( SM_CYSMCAPTION) - 1, /* WinXP style */
2866 smcxsmsize /* winXP seems to cache this value: setnonclientmetric
2867 does not change it */
2869 ok_gsm( SM_CYSMSIZE, GetSystemMetrics( SM_CYSMCAPTION) - 1);
2870 ok_gsm( SM_CXMENUSIZE, ncm.iMenuWidth);
2871 ok_gsm( SM_CYMENUSIZE, ncm.iMenuHeight);
2872 /* SM_ARRANGE */
2873 ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6);
2874 ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5);
2875 screen.cx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
2876 screen.cy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
2877 if (!screen.cx || !screen.cy) /* not supported on NT4 */
2879 screen.cx = GetSystemMetrics( SM_CXSCREEN );
2880 screen.cy = GetSystemMetrics( SM_CYSCREEN );
2882 ok_gsm_3( SM_CXMAXTRACK, screen.cx + 4 + 2 * GetSystemMetrics(SM_CXFRAME),
2883 screen.cx - 4 + 2 * GetSystemMetrics(SM_CXFRAME), /* Vista */
2884 screen.cx + 2 * GetSystemMetrics(SM_CXFRAME)); /* Win8 */
2885 ok_gsm_3( SM_CYMAXTRACK, screen.cy + 4 + 2 * GetSystemMetrics(SM_CYFRAME),
2886 screen.cy - 4 + 2 * GetSystemMetrics(SM_CYFRAME), /* Vista */
2887 screen.cy + 2 * GetSystemMetrics(SM_CYFRAME)); /* Win8 */
2888 /* the next two cannot really be tested as they depend on (application)
2889 * toolbars */
2890 /* SM_CXMAXIMIZED */
2891 /* SM_CYMAXIMIZED */
2892 /* SM_NETWORK */
2893 /* */
2894 /* */
2895 /* */
2896 /* SM_CLEANBOOT */
2897 /* SM_CXDRAG */
2898 /* SM_CYDRAG */
2899 /* SM_SHOWSOUNDS */
2900 ok_gsm( SM_CXMENUCHECK,
2901 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2902 ok_gsm( SM_CYMENUCHECK,
2903 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2904 /* SM_SLOWMACHINE */
2905 /* SM_MIDEASTENABLED */
2906 /* SM_MOUSEWHEELPRESENT */
2907 /* SM_XVIRTUALSCREEN */
2908 /* SM_YVIRTUALSCREEN */
2909 /* SM_CXVIRTUALSCREEN */
2910 /* SM_CYVIRTUALSCREEN */
2911 /* SM_CMONITORS */
2912 /* SM_SAMEDISPLAYFORMAT */
2913 /* SM_IMMENABLED */
2914 /* SM_CXFOCUSBORDER */
2915 /* SM_CYFOCUSBORDER */
2916 /* SM_TABLETPC */
2917 /* SM_MEDIACENTER */
2918 /* SM_CMETRICS */
2919 /* end of tests */
2920 if( gsm_error_ctr ) { /* if any errors where found */
2921 trace( "BorderWidth %d CaptionWidth %d CaptionHeight %d IconSpacing %d IconVerticalSpacing %d\n",
2922 ncm.iBorderWidth, ncm.iCaptionWidth, ncm.iCaptionHeight, IconSpacing, IconVerticalSpacing);
2923 trace( "MenuHeight %d MenuWidth %d ScrollHeight %d ScrollWidth %d SmCaptionHeight %d SmCaptionWidth %d\n",
2924 ncm.iMenuHeight, ncm.iMenuWidth, ncm.iScrollHeight, ncm.iScrollWidth, ncm.iSmCaptionHeight, ncm.iSmCaptionWidth);
2925 trace( "Captionfontchar width %d MenuFont %d,%d CaptionWidth from registry: %d screen %d,%d\n",
2926 avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidthfromreg, screen.cx, screen.cy);
2929 DeleteDC(hdc);
2932 static void test_EnumDisplaySettings(void)
2934 DEVMODEA devmode;
2935 DWORD val;
2936 HDC hdc;
2937 DWORD num;
2939 memset(&devmode, 0, sizeof(devmode));
2940 /* Win95 doesn't handle ENUM_CURRENT_SETTINGS correctly */
2941 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
2943 hdc = GetDC(0);
2944 val = GetDeviceCaps(hdc, BITSPIXEL);
2945 ok(devmode.dmBitsPerPel == val ||
2946 broken(devmode.dmDeviceName[0] == 0), /* Win95 */
2947 "GetDeviceCaps(BITSPIXEL) returned %d, EnumDisplaySettings returned %d\n",
2948 val, devmode.dmBitsPerPel);
2950 val = GetDeviceCaps(hdc, NUMCOLORS);
2951 if(devmode.dmBitsPerPel <= 8) {
2952 ok(val == 256, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
2953 } else {
2954 ok(val == -1, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
2957 ReleaseDC(0, hdc);
2959 num = 1;
2960 while (1) {
2961 SetLastError (0xdeadbeef);
2962 if (!EnumDisplaySettingsA(NULL, num, &devmode)) {
2963 DWORD le = GetLastError();
2964 ok(le == ERROR_NO_MORE_FILES ||
2965 le == ERROR_MOD_NOT_FOUND /* Win8 */ ||
2966 le == 0xdeadbeef, /* XP, 2003 */
2967 "Expected ERROR_NO_MORE_FILES, ERROR_MOD_NOT_FOUND or 0xdeadbeef, got %d for %d\n", le, num);
2968 break;
2970 num++;
2974 static void test_GetSysColorBrush(void)
2976 HBRUSH hbr;
2978 SetLastError(0xdeadbeef);
2979 hbr = GetSysColorBrush(-1);
2980 ok(hbr == NULL, "Expected NULL brush\n");
2981 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
2982 /* greater than max index */
2983 hbr = GetSysColorBrush(COLOR_MENUBAR);
2984 if (hbr)
2986 SetLastError(0xdeadbeef);
2987 hbr = GetSysColorBrush(COLOR_MENUBAR + 1);
2988 ok(hbr == NULL, "Expected NULL brush\n");
2989 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
2991 else
2992 win_skip("COLOR_MENUBAR unsupported\n");
2995 static void test_dpi_aware(void)
2997 BOOL ret;
2999 if (!pIsProcessDPIAware)
3001 win_skip("IsProcessDPIAware not available\n");
3002 return;
3005 if (pSetProcessDpiAwarenessContext)
3007 DPI_AWARENESS awareness;
3008 DPI_AWARENESS_CONTEXT context;
3010 context = pGetThreadDpiAwarenessContext();
3011 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3012 todo_wine
3013 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3014 SetLastError( 0xdeadbeef );
3015 ret = pSetProcessDpiAwarenessContext( NULL );
3016 ok( !ret, "got %d\n", ret );
3017 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3018 SetLastError( 0xdeadbeef );
3019 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3020 ok( !ret, "got %d\n", ret );
3021 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3022 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3023 ok( ret, "got %d\n", ret );
3024 SetLastError( 0xdeadbeef );
3025 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3026 ok( !ret, "got %d\n", ret );
3027 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3028 SetLastError( 0xdeadbeef );
3029 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3030 ok( !ret, "got %d\n", ret );
3031 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3033 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_INVALID );
3034 ok( !ret, "got %d\n", ret );
3035 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3036 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_UNAWARE );
3037 ok( !ret, "got %d\n", ret );
3038 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3039 ret = pGetProcessDpiAwarenessInternal( 0, &awareness );
3040 ok( ret, "got %d\n", ret );
3041 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3042 ret = pGetProcessDpiAwarenessInternal( GetCurrentProcess(), &awareness );
3043 ok( ret, "got %d\n", ret );
3044 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3045 ret = pGetProcessDpiAwarenessInternal( (HANDLE)0xdeadbeef, &awareness );
3046 ok( ret, "got %d\n", ret );
3047 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong value %d\n", awareness );
3049 ret = pIsProcessDPIAware();
3050 ok(ret, "got %d\n", ret);
3051 context = pGetThreadDpiAwarenessContext();
3052 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3053 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3054 SetLastError( 0xdeadbeef );
3055 context = pSetThreadDpiAwarenessContext( 0 );
3056 ok( !context, "got %p\n", context );
3057 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3058 SetLastError( 0xdeadbeef );
3059 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3060 ok( !context, "got %p\n", context );
3061 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3062 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3063 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3064 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3065 context = pGetThreadDpiAwarenessContext();
3066 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3067 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3068 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3069 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3070 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3071 context = pGetThreadDpiAwarenessContext();
3072 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3073 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3074 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3075 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3076 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3078 else win_skip( "SetProcessDPIAware not supported\n" );
3080 ret = pSetProcessDPIAware();
3081 ok(ret, "got %d\n", ret);
3083 ret = pIsProcessDPIAware();
3084 ok(ret, "got %d\n", ret);
3086 dpi = real_dpi;
3087 test_GetSystemMetrics();
3090 static void test_window_dpi(void)
3092 DPI_AWARENESS_CONTEXT context, orig;
3093 DPI_AWARENESS awareness;
3094 HWND hwnd;
3096 if (!pGetWindowDpiAwarenessContext)
3098 win_skip( "GetWindowDpiAwarenessContext not supported\n" );
3099 return;
3101 orig = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3102 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3103 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3104 ok( hwnd != 0, "failed to create window\n" );
3105 context = pGetWindowDpiAwarenessContext( hwnd );
3106 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3107 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3108 DestroyWindow( hwnd );
3110 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3111 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3112 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3113 ok( hwnd != 0, "failed to create window\n" );
3114 context = pGetWindowDpiAwarenessContext( hwnd );
3115 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3116 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3117 DestroyWindow( hwnd );
3119 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3120 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3121 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3122 ok( hwnd != 0, "failed to create window\n" );
3123 context = pGetWindowDpiAwarenessContext( hwnd );
3124 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3125 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3126 DestroyWindow( hwnd );
3128 SetLastError( 0xdeadbeef );
3129 context = pGetWindowDpiAwarenessContext( (HWND)0xdeadbeef );
3130 ok( !context, "got %p\n", context );
3131 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
3133 SetLastError( 0xdeadbeef );
3134 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3135 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3136 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3138 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3139 SetLastError( 0xdeadbeef );
3140 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3141 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3142 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3144 pSetThreadDpiAwarenessContext( orig );
3147 START_TEST(sysparams)
3149 int argc;
3150 char** argv;
3151 WNDCLASSA wc;
3152 MSG msg;
3153 HANDLE hThread;
3154 DWORD dwThreadId;
3155 HANDLE hInstance, hdll;
3157 hdll = GetModuleHandleA("user32.dll");
3158 pChangeDisplaySettingsExA = (void*)GetProcAddress(hdll, "ChangeDisplaySettingsExA");
3159 pIsProcessDPIAware = (void*)GetProcAddress(hdll, "IsProcessDPIAware");
3160 pSetProcessDPIAware = (void*)GetProcAddress(hdll, "SetProcessDPIAware");
3161 pSetProcessDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessContext");
3162 pGetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "GetProcessDpiAwarenessInternal");
3163 pSetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessInternal");
3164 pGetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetThreadDpiAwarenessContext");
3165 pSetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetThreadDpiAwarenessContext");
3166 pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetWindowDpiAwarenessContext");
3167 pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetAwarenessFromDpiAwarenessContext");
3169 hInstance = GetModuleHandleA( NULL );
3170 hdc = GetDC(0);
3171 dpi = GetDeviceCaps( hdc, LOGPIXELSY);
3172 real_dpi = get_real_dpi();
3173 trace("dpi %d real_dpi %d\n", dpi, real_dpi);
3174 iswin9x = GetVersion() & 0x80000000;
3176 /* This test requires interactivity, if we don't have it, give up */
3177 if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) &&
3178 GetLastError()==ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) return;
3180 argc = winetest_get_mainargs(&argv);
3181 strict=(argc >= 3 && strcmp(argv[2],"strict")==0);
3182 trace("strict=%d\n",strict);
3184 trace("testing GetSystemMetrics with your current desktop settings\n");
3185 test_GetSystemMetrics( );
3186 trace("testing EnumDisplaySettings vs GetDeviceCaps\n");
3187 test_EnumDisplaySettings( );
3188 test_GetSysColorBrush( );
3190 change_counter = 0;
3191 change_last_param = 0;
3193 wc.lpszClassName = "SysParamsTestClass";
3194 wc.lpfnWndProc = SysParamsTestWndProc;
3195 wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
3196 wc.hInstance = hInstance;
3197 wc.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
3198 wc.hCursor = LoadCursorA( 0, (LPCSTR)IDC_ARROW );
3199 wc.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
3200 wc.lpszMenuName = 0;
3201 wc.cbClsExtra = 0;
3202 wc.cbWndExtra = 0;
3203 RegisterClassA( &wc );
3205 ghTestWnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3206 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, hInstance, NULL );
3208 hThread = CreateThread( NULL, 0, SysParamsThreadFunc, 0, 0, &dwThreadId );
3209 assert( hThread );
3210 CloseHandle( hThread );
3212 while( GetMessageA( &msg, 0, 0, 0 )) {
3213 TranslateMessage( &msg );
3214 DispatchMessageA( &msg );
3216 ReleaseDC( 0, hdc);
3218 test_dpi_aware();
3219 test_window_dpi();