user32/tests: Avoid calling a potentially missing function.
[wine.git] / dlls / user32 / tests / sysparams.c
blob815cb79ddcb479b06cc48f1b06683537fab7952e
1 /* Unit test suite for functions SystemParametersInfo and GetSystemMetrics.
3 * Copyright 2002 Andriy Palamarchuk
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define _WIN32_WINNT 0x0600 /* For SPI_GETMOUSEHOVERWIDTH and more */
21 #define _WIN32_IE 0x0700
22 #define WINVER 0x0600 /* For COLOR_MENUBAR, NONCLIENTMETRICS with padding */
24 #include <assert.h>
25 #include <stdlib.h>
26 #include <stdarg.h>
27 #include <stdio.h>
29 #include "wine/test.h"
30 #include "windef.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winreg.h"
34 #include "winuser.h"
35 #include "winnls.h"
37 #ifndef SPI_GETDESKWALLPAPER
38 # define SPI_GETDESKWALLPAPER 0x0073
39 #endif
41 static LONG (WINAPI *pChangeDisplaySettingsExA)(LPCSTR, LPDEVMODEA, HWND, DWORD, LPVOID);
42 static BOOL (WINAPI *pIsProcessDPIAware)(void);
43 static BOOL (WINAPI *pSetProcessDPIAware)(void);
44 static BOOL (WINAPI *pSetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
45 static BOOL (WINAPI *pGetProcessDpiAwarenessInternal)(HANDLE,DPI_AWARENESS*);
46 static BOOL (WINAPI *pSetProcessDpiAwarenessInternal)(DPI_AWARENESS);
47 static UINT (WINAPI *pGetDpiForSystem)(void);
48 static UINT (WINAPI *pGetDpiForWindow)(HWND);
49 static DPI_AWARENESS_CONTEXT (WINAPI *pGetThreadDpiAwarenessContext)(void);
50 static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
51 static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
52 static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
53 static BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
54 static INT (WINAPI *pGetSystemMetricsForDpi)(INT,UINT);
55 static BOOL (WINAPI *pSystemParametersInfoForDpi)(UINT,UINT,void*,UINT,UINT);
56 static BOOL (WINAPI *pLogicalToPhysicalPointForPerMonitorDPI)(HWND,POINT*);
57 static BOOL (WINAPI *pPhysicalToLogicalPointForPerMonitorDPI)(HWND,POINT*);
59 static BOOL strict;
60 static int dpi, real_dpi;
62 #define eq(received, expected, label, type) \
63 ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
66 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
67 #define SPI_SETBEEP_VALNAME "Beep"
68 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
69 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
70 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
71 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
72 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop\\WindowMetrics"
73 #define SPI_SETBORDER_REGKEY2 "Control Panel\\Desktop"
74 #define SPI_SETBORDER_VALNAME "BorderWidth"
75 #define SPI_METRIC_REGKEY "Control Panel\\Desktop\\WindowMetrics"
76 #define SPI_SCROLLWIDTH_VALNAME "ScrollWidth"
77 #define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight"
78 #define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth"
79 #define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight"
80 #define SPI_CAPTIONFONT_VALNAME "CaptionFont"
81 #define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth"
82 #define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight"
83 #define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont"
84 #define SPI_MENUWIDTH_VALNAME "MenuWidth"
85 #define SPI_MENUHEIGHT_VALNAME "MenuHeight"
86 #define SPI_MENUFONT_VALNAME "MenuFont"
87 #define SPI_STATUSFONT_VALNAME "StatusFont"
88 #define SPI_MESSAGEFONT_VALNAME "MessageFont"
90 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
91 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
92 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
93 #define SPI_ICONHORIZONTALSPACING_REGKEY2 "Control Panel\\Desktop"
94 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
95 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
96 #define SPI_ICONVERTICALSPACING_REGKEY2 "Control Panel\\Desktop"
97 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
98 #define SPI_MINIMIZEDMETRICS_REGKEY "Control Panel\\Desktop\\WindowMetrics"
99 #define SPI_MINWIDTH_VALNAME "MinWidth"
100 #define SPI_MINHORZGAP_VALNAME "MinHorzGap"
101 #define SPI_MINVERTGAP_VALNAME "MinVertGap"
102 #define SPI_MINARRANGE_VALNAME "MinArrange"
103 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
104 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
105 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
106 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
107 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
108 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
109 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
110 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
111 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
112 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
113 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
114 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
115 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
116 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
117 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
118 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
119 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
120 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
121 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
122 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
123 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
124 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
125 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
126 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
127 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
128 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
129 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
130 #define SPI_SETSHOWSOUNDS_VALNAME "On"
131 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Accessibility\\Keyboard Preference"
132 #define SPI_SETKEYBOARDPREF_VALNAME "On"
133 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY "Control Panel\\Accessibility"
134 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY "Keyboard Preference"
135 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Accessibility\\Blind Access"
136 #define SPI_SETSCREENREADER_VALNAME "On"
137 #define SPI_SETSCREENREADER_REGKEY_LEGACY "Control Panel\\Accessibility"
138 #define SPI_SETSCREENREADER_VALNAME_LEGACY "Blind Access"
139 #define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\\Desktop"
140 #define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing"
141 #define SPI_SETFONTSMOOTHINGTYPE_VALNAME "FontSmoothingType"
142 #define SPI_SETFONTSMOOTHINGCONTRAST_VALNAME "FontSmoothingGamma"
143 #define SPI_SETFONTSMOOTHINGORIENTATION_VALNAME "FontSmoothingOrientation"
144 #define SPI_SETLOWPOWERACTIVE_REGKEY "Control Panel\\Desktop"
145 #define SPI_SETLOWPOWERACTIVE_VALNAME "LowPowerActive"
146 #define SPI_SETPOWEROFFACTIVE_REGKEY "Control Panel\\Desktop"
147 #define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive"
148 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
149 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
150 #define SPI_SETSNAPTODEFBUTTON_REGKEY "Control Panel\\Mouse"
151 #define SPI_SETSNAPTODEFBUTTON_VALNAME "SnapToDefaultButton"
152 #define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse"
153 #define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth"
154 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse"
155 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight"
156 #define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse"
157 #define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime"
158 #define SPI_SETMOUSESCROLLCHARS_REGKEY "Control Panel\\Desktop"
159 #define SPI_SETMOUSESCROLLCHARS_VALNAME "WheelScrollChars"
160 #define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop"
161 #define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines"
162 #define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop"
163 #define SPI_SETMENUSHOWDELAY_VALNAME "MenuShowDelay"
164 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
165 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
167 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
168 #define WINE_CURRENT_USER_REGKEY "Wine"
170 static HWND ghTestWnd;
172 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
173 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
174 LPARAM lParam );
175 static int change_counter;
176 static int change_setworkarea_param, change_iconverticalspacing_param;
177 static int change_last_param;
178 static int last_bpp;
179 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
180 static HANDLE displaychange_sem = 0;
182 static BOOL get_reg_dword(HKEY base, const char *key_name, const char *value_name, DWORD *value)
184 HKEY key;
185 DWORD type, data, size = sizeof(data);
186 BOOL ret = FALSE;
188 if (RegOpenKeyA(base, key_name, &key) == ERROR_SUCCESS)
190 if (RegQueryValueExA(key, value_name, NULL, &type, (void *)&data, &size) == ERROR_SUCCESS &&
191 type == REG_DWORD)
193 *value = data;
194 ret = TRUE;
196 RegCloseKey(key);
198 return ret;
201 static DWORD get_real_dpi(void)
203 DWORD dpi;
205 if (pSetThreadDpiAwarenessContext)
207 DPI_AWARENESS_CONTEXT context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
208 dpi = pGetDpiForSystem();
209 pSetThreadDpiAwarenessContext( context );
210 return dpi;
212 if (get_reg_dword(HKEY_CURRENT_USER, "Control Panel\\Desktop", "LogPixels", &dpi))
213 return dpi;
214 if (get_reg_dword(HKEY_CURRENT_CONFIG, "Software\\Fonts", "LogPixels", &dpi))
215 return dpi;
216 return USER_DEFAULT_SCREEN_DPI;
219 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
220 LPARAM lParam )
222 switch (msg) {
224 case WM_DISPLAYCHANGE:
225 ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
226 last_bpp = wParam;
227 displaychange_ok = FALSE;
228 ReleaseSemaphore(displaychange_sem, 1, 0);
229 break;
231 case WM_SETTINGCHANGE:
232 if (change_counter>0) {
233 /* ignore these messages caused by resizing of toolbars */
234 if( wParam == SPI_SETWORKAREA){
235 change_setworkarea_param = 1;
236 break;
237 } else if( wParam == SPI_ICONVERTICALSPACING) {
238 change_iconverticalspacing_param = 1;
239 break;
240 } else if( displaychange_test_active)
241 break;
242 if( !change_last_param){
243 change_last_param = wParam;
244 break;
246 ok(0,"too many changes counter=%d last change=%d\n",
247 change_counter,change_last_param);
248 change_counter++;
249 change_last_param = wParam;
250 break;
252 change_counter++;
253 change_last_param = change_setworkarea_param = change_iconverticalspacing_param =0;
254 if( wParam == SPI_SETWORKAREA)
255 change_setworkarea_param = 1;
256 else if( wParam == SPI_ICONVERTICALSPACING)
257 change_iconverticalspacing_param = 1;
258 else
259 change_last_param = wParam;
260 break;
262 case WM_DESTROY:
263 PostQuitMessage( 0 );
264 break;
266 /* drop through */
267 default:
268 return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
271 return 0;
275 Performs testing for system parameters messages
276 params:
277 - system parameter id
278 - supposed value of the registry key
280 static void test_change_message( int action, int optional )
282 if (change_counter==0 && optional==1)
283 return;
284 ok( 1 == change_counter,
285 "Missed a message: change_counter=%d\n", change_counter );
286 change_counter = 0;
287 ok( action == change_last_param ||
288 ( change_setworkarea_param && action == SPI_SETWORKAREA) ||
289 ( change_iconverticalspacing_param && action == SPI_ICONVERTICALSPACING),
290 "Wrong action got %d expected %d\n", change_last_param, action );
291 change_last_param = 0;
294 static BOOL test_error_msg ( int rc, const char *name )
296 DWORD last_error = GetLastError();
298 if (rc==0)
300 if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
302 skip("%s not supported on this platform\n", name);
304 else if (last_error==ERROR_ACCESS_DENIED)
306 skip("%s does not have privileges to run\n", name);
308 else
310 trace("%s failed for reason: %d. Indicating test failure and skipping remainder of test\n",name,last_error);
311 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
313 return FALSE;
315 else
317 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
318 return TRUE;
323 * Tests the HKEY_CURRENT_USER subkey value.
324 * The value should contain string value.
326 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2,
327 const void *exp_value, DWORD exp_type, BOOL optional )
329 CHAR value[MAX_PATH];
330 DWORD valueLen;
331 DWORD type;
332 HKEY hKey;
333 LONG rc;
334 int found=0;
336 *value='\0';
337 valueLen=sizeof(value);
338 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
339 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
340 RegCloseKey( hKey );
341 if (rc==ERROR_SUCCESS)
343 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
344 switch (exp_type)
346 case REG_DWORD:
347 ok( *(DWORD *)value == *(DWORD *)exp_value,
348 "Wrong value in registry: %s %s %08x/%08x\n",
349 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
350 break;
351 case REG_SZ:
352 ok( !strcmp( exp_value, value ),
353 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
354 subKey1, valName1, value, (const char *)exp_value );
355 break;
357 found++;
359 else if (strict)
361 ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
362 subKey1, valName1);
364 if (valName2)
366 *value='\0';
367 valueLen=sizeof(value);
368 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
369 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
370 RegCloseKey( hKey );
371 if (rc==ERROR_SUCCESS)
373 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
374 switch (exp_type)
376 case REG_DWORD:
377 ok( *(DWORD *)value == *(DWORD *)exp_value,
378 "Wrong value in registry: %s %s %08x/%08x\n",
379 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
380 break;
381 case REG_SZ:
382 ok( !strcmp( exp_value, value ),
383 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
384 subKey1, valName1, value, (const char *)exp_value );
385 break;
387 found++;
389 else if (strict)
391 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
392 subKey1, valName2 );
395 if (subKey2 && !strict)
397 *value='\0';
398 valueLen=sizeof(value);
399 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
400 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
401 RegCloseKey( hKey );
402 if (rc==ERROR_SUCCESS)
404 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
405 switch (exp_type)
407 case REG_DWORD:
408 ok( *(DWORD *)value == *(DWORD *)exp_value,
409 "Wrong value in registry: %s %s %08x/%08x\n",
410 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
411 break;
412 case REG_SZ:
413 ok( !strcmp( exp_value, value ),
414 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
415 subKey1, valName1, value, (const char *)exp_value );
416 break;
418 found++;
420 else if (strict)
422 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
423 subKey2, valName1 );
425 if (valName2)
427 *value='\0';
428 valueLen=sizeof(value);
429 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
430 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
431 RegCloseKey( hKey );
432 if (rc==ERROR_SUCCESS)
434 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
435 switch (exp_type)
437 case REG_DWORD:
438 ok( *(DWORD *)value == *(DWORD *)exp_value,
439 "Wrong value in registry: %s %s %08x/%08x\n",
440 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
441 break;
442 case REG_SZ:
443 ok( !strcmp( exp_value, value ),
444 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
445 subKey1, valName1, value, (const char *)exp_value );
446 break;
448 found++;
450 else if (strict)
452 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
453 subKey2, valName2 );
457 ok(found || optional,
458 "Missing registry values: %s or %s in keys: %s or %s\n",
459 valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
462 #define test_reg_key( subKey, valName, testValue ) \
463 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, FALSE )
464 #define test_reg_key_optional( subKey, valName, testValue ) \
465 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, TRUE )
466 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
467 _test_reg_key( subKey1, subKey2, valName, NULL, testValue, REG_SZ, FALSE )
468 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
469 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, FALSE )
470 #define test_reg_key_ex2_optional( subKey1, subKey2, valName1, valName2, testValue ) \
471 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, TRUE )
472 #define test_reg_key_dword( subKey, valName, testValue ) \
473 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_DWORD, FALSE )
475 /* get a metric from the registry. If the value is negative
476 * it is assumed to be in twips and converted to pixels */
477 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
479 HKEY hkey;
480 char buf[64];
481 DWORD ret;
482 DWORD size, type;
483 int value;
485 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
486 size = sizeof(buf);
487 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
488 RegCloseKey( hkey );
489 if( ret != ERROR_SUCCESS) return -1;
490 value = atoi( buf);
491 if( value < 0)
492 value = ( -value * dpi + 720) / 1440;
493 return value;
496 typedef struct
498 INT16 lfHeight;
499 INT16 lfWidth;
500 INT16 lfEscapement;
501 INT16 lfOrientation;
502 INT16 lfWeight;
503 BYTE lfItalic;
504 BYTE lfUnderline;
505 BYTE lfStrikeOut;
506 BYTE lfCharSet;
507 BYTE lfOutPrecision;
508 BYTE lfClipPrecision;
509 BYTE lfQuality;
510 BYTE lfPitchAndFamily;
511 CHAR lfFaceName[LF_FACESIZE];
512 } LOGFONT16, *LPLOGFONT16;
514 /* get logfont from the registry */
515 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
517 HKEY hkey;
518 LOGFONTW lfw;
519 DWORD ret, size, type;
521 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
522 size = sizeof( lfw);
523 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
524 RegCloseKey( hkey );
525 ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
526 if( ret != ERROR_SUCCESS)
527 return FALSE;
528 if( size <= sizeof( LOGFONT16)) {
529 LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
530 plf->lfHeight = plf16->lfHeight;
531 plf->lfWidth = plf16->lfWidth;
532 plf->lfEscapement = plf16->lfEscapement;
533 plf->lfOrientation = plf16->lfOrientation;
534 plf->lfWeight = plf16->lfWeight;
535 plf->lfItalic = plf16->lfItalic;
536 plf->lfUnderline = plf16->lfUnderline;
537 plf->lfStrikeOut = plf16->lfStrikeOut;
538 plf->lfCharSet = plf16->lfCharSet;
539 plf->lfOutPrecision = plf16->lfOutPrecision;
540 plf->lfClipPrecision = plf16->lfClipPrecision;
541 plf->lfQuality = plf16->lfQuality;
542 plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
543 memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
544 } else if( size <= sizeof( LOGFONTA)) {
545 plf = (LOGFONTA*) &lfw;
546 } else {
547 plf->lfHeight = lfw.lfHeight;
548 plf->lfWidth = lfw.lfWidth;
549 plf->lfEscapement = lfw.lfEscapement;
550 plf->lfOrientation = lfw.lfOrientation;
551 plf->lfWeight = lfw.lfWeight;
552 plf->lfItalic = lfw.lfItalic;
553 plf->lfUnderline = lfw.lfUnderline;
554 plf->lfStrikeOut = lfw.lfStrikeOut;
555 plf->lfCharSet = lfw.lfCharSet;
556 plf->lfOutPrecision = lfw.lfOutPrecision;
557 plf->lfClipPrecision = lfw.lfClipPrecision;
558 plf->lfQuality = lfw.lfQuality;
559 plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
560 WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
561 LF_FACESIZE, NULL, NULL);
564 return TRUE;
567 static void test_SPI_SETBEEP( void ) /* 2 */
569 BOOL rc;
570 BOOL old_b;
571 BOOL b;
572 BOOL curr_val;
574 trace("testing SPI_{GET,SET}BEEP\n");
575 SetLastError(0xdeadbeef);
576 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
577 if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
578 return;
580 curr_val = TRUE;
581 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
582 if (!test_error_msg(rc,"SPI_SETBEEP")) return;
583 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
584 test_change_message( SPI_SETBEEP, 0 );
585 test_reg_key( SPI_SETBEEP_REGKEY,
586 SPI_SETBEEP_VALNAME,
587 curr_val ? "Yes" : "No" );
588 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
589 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
590 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
591 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
592 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
594 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
595 eq( b, curr_val, "SystemParametersInfoW", "%d" );
598 /* is a message sent for the second change? */
599 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
600 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
601 test_change_message( SPI_SETBEEP, 0 );
603 curr_val = FALSE;
604 rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
605 if (rc == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
606 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
607 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
608 test_change_message( SPI_SETBEEP, 0 );
609 test_reg_key( SPI_SETBEEP_REGKEY,
610 SPI_SETBEEP_VALNAME,
611 curr_val ? "Yes" : "No" );
612 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
613 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
614 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
615 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
616 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
618 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
619 eq( b, curr_val, "SystemParametersInfoW", "%d" );
621 ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
623 rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
624 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
627 static const char *setmouse_valuenames[3] = {
628 SPI_SETMOUSE_VALNAME1,
629 SPI_SETMOUSE_VALNAME2,
630 SPI_SETMOUSE_VALNAME3
634 * Runs check for one setting of spi_setmouse.
636 static BOOL run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change, int nchange )
638 BOOL rc;
639 INT mi[3];
640 static int aw_turn = 0;
642 char buf[20];
643 int i;
645 aw_turn++;
646 rc = FALSE;
647 SetLastError(0xdeadbeef);
648 if (aw_turn % 2) /* call unicode on odd (non even) calls */
649 rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
650 else
651 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
652 if (!test_error_msg(rc,"SPI_SETMOUSE")) return FALSE;
654 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
655 test_change_message( SPI_SETMOUSE, 0 );
656 for (i = 0; i < 3; i++)
658 sprintf( buf, "%d", curr_val[i] );
659 test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
662 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
663 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
664 for (i = 0; i < 3; i++)
666 ok(mi[i] == curr_val[i],
667 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
670 rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
671 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
672 for (i = 0; i < 3; i++)
674 ok(mi[i] == curr_val[i],
675 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
678 if (0)
680 /* FIXME: this always fails for me - AJ */
681 for (i = 0; i < nchange; i++)
683 POINT mv;
684 mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
685 mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
686 GetCursorPos( &mv );
687 ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
688 ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
691 return TRUE;
694 static void test_SPI_SETMOUSE( void ) /* 4 */
696 BOOL rc;
697 INT old_mi[3];
699 /* win nt default values - 6, 10, 1 */
700 INT curr_val[3] = {6, 10, 1};
702 /* requested and projected mouse movements */
703 POINT req_change[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
704 POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
705 POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
706 POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
707 POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
708 POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
709 POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
710 POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
711 POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
713 int nchange = sizeof( req_change ) / sizeof( POINT );
715 trace("testing SPI_{GET,SET}MOUSE\n");
716 SetLastError(0xdeadbeef);
717 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
718 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
719 return;
721 if (!run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange )) return;
723 /* acceleration change */
724 curr_val[2] = 2;
725 run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
727 /* acceleration change */
728 curr_val[2] = 3;
729 run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
731 /* acceleration change */
732 curr_val[2] = 0;
733 run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
735 /* threshold change */
736 curr_val[2] = 1;
737 curr_val[0] = 7;
738 run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
740 /* threshold change */
741 curr_val[2] = 2;
742 curr_val[0] = 6;
743 curr_val[1] = 6;
744 run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
746 /* threshold change */
747 curr_val[1] = 7;
748 run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
750 /* threshold change */
751 curr_val[1] = 5;
752 run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
754 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
755 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
758 static BOOL test_setborder(UINT curr_val, int usesetborder, int dpi)
760 BOOL rc;
761 UINT border, regval;
762 INT frame;
763 NONCLIENTMETRICSA ncm;
765 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
766 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
767 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
768 if( usesetborder) {
769 rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
770 if (!test_error_msg(rc,"SPI_SETBORDER")) return FALSE;
771 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
772 test_change_message( SPI_SETBORDER, 1 );
773 } else { /* set non client metrics */
774 ncm.iBorderWidth = curr_val;
775 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
776 SPIF_SENDCHANGE);
777 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return FALSE;
778 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
779 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
781 if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
782 regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
783 if( regval != curr_val)
784 regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
785 ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
787 /* minimum border width is 1 */
788 if (curr_val == 0) curr_val = 1;
789 /* should be the same as the non client metrics */
790 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
791 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
792 eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
793 /* and from SPI_GETBORDER */
794 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
795 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
796 eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
797 /* test some SystemMetrics */
798 frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
799 eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
800 eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
801 eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
802 eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
803 return TRUE;
806 static void test_SPI_SETBORDER( void ) /* 6 */
808 BOOL rc;
809 UINT old_border;
810 NONCLIENTMETRICSA ncmsave;
811 INT CaptionWidth,
812 PaddedBorderWidth;
814 ncmsave.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
815 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
816 if( !rc) {
817 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
818 return;
820 /* CaptionWidth from the registry may have different value of iCaptionWidth
821 * from the non client metrics (observed on WinXP).
822 * Fix this so we can safely restore settings with the nonclientmetrics */
823 CaptionWidth = metricfromreg(
824 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
825 ncmsave.iCaptionWidth = CaptionWidth;
827 /* These tests hang when XFree86 4.0 for Windows is running (tested on
828 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
829 * running.
831 if (FindWindowA( NULL, "Cygwin/XFree86" ))
832 return;
834 trace("testing SPI_{GET,SET}BORDER\n");
836 SetLastError(0xdeadbeef);
837 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 );
838 if (!test_error_msg(rc,"SPI_{GET,SET}BORDER"))
839 return;
840 /* FIXME: include new PaddedBorderWidth parameter */
841 PaddedBorderWidth = ncmsave.iBorderWidth - old_border;
842 if( PaddedBorderWidth){
843 win_skip( "Cannot reliably restore border width yet (PaddedBorderWidth = %d)\n",
844 PaddedBorderWidth);
845 return;
847 /* This will restore sane values if the test hang previous run. */
848 if ( old_border == 7 || old_border == 20 )
849 old_border = 1;
851 /* win2k3 fails if you set the same border twice, or if size is 0 */
852 if (!test_setborder(2, 1, dpi)) return;
853 test_setborder(1, 1, dpi);
854 test_setborder(3, 1, dpi);
855 if (!test_setborder(1, 0, dpi)) return;
856 test_setborder(0, 0, dpi);
857 test_setborder(3, 0, dpi);
859 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave,
860 SPIF_UPDATEINIFILE| SPIF_SENDCHANGE);
861 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
862 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
865 static void test_SPI_SETKEYBOARDSPEED( void ) /* 10 */
867 BOOL rc;
868 UINT old_speed;
869 const UINT vals[]={0,20,31};
870 unsigned int i;
872 trace("testing SPI_{GET,SET}KEYBOARDSPEED\n");
873 SetLastError(0xdeadbeef);
874 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &old_speed, 0 );
875 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDSPEED"))
876 return;
878 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
880 UINT v;
881 char buf[10];
883 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, vals[i], 0,
884 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
885 if (!test_error_msg(rc,"SPI_SETKEYBOARDSPEED")) return;
886 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
887 test_change_message( SPI_SETKEYBOARDSPEED, 0 );
888 sprintf( buf, "%d", vals[i] );
889 test_reg_key( SPI_SETKEYBOARDSPEED_REGKEY, SPI_SETKEYBOARDSPEED_VALNAME, buf );
891 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &v, 0 );
892 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
893 eq( v, vals[i], "SPI_{GET,SET}KEYBOARDSPEED", "%d" );
896 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, old_speed, 0, SPIF_UPDATEINIFILE );
897 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
900 /* test_SPI_ICONHORIZONTALSPACING helper */
901 static BOOL dotest_spi_iconhorizontalspacing( INT curr_val)
903 BOOL rc;
904 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
905 ICONMETRICSA im;
907 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0,
908 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
909 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING")) return FALSE;
910 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
911 test_change_message( SPI_ICONHORIZONTALSPACING, 0 );
912 curr_val = max( curr_val, min_val );
913 /* The registry keys depend on the Windows version and the values too
914 * let's test (works on win95,ME,NT4,2k,XP)
916 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY2, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
917 if( regval != curr_val)
918 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
919 ok( curr_val == regval,
920 "wrong value in registry %d, expected %d\n", regval, curr_val);
921 /* compare with what SPI_ICONHORIZONTALSPACING returns */
922 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
923 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
924 eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d");
925 /* and with a system metrics */
926 eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" );
927 /* and with what SPI_GETICONMETRICS returns */
928 im.cbSize = sizeof(ICONMETRICSA);
929 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
930 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
931 eq( im.iHorzSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
932 return TRUE;
935 static void test_SPI_ICONHORIZONTALSPACING( void ) /* 13 */
937 BOOL rc;
938 INT old_spacing;
940 trace("testing SPI_ICONHORIZONTALSPACING\n");
941 SetLastError(0xdeadbeef);
942 /* default value: 75 */
943 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &old_spacing, 0 );
944 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING"))
945 return;
946 /* do not increase the value as it would upset the user's icon layout */
947 if (!dotest_spi_iconhorizontalspacing( old_spacing - 1)) return;
948 dotest_spi_iconhorizontalspacing( 10); /* minimum is 32 */
949 /* restore */
950 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, old_spacing, 0, SPIF_UPDATEINIFILE );
951 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
954 static void test_SPI_SETSCREENSAVETIMEOUT( void ) /* 14 */
956 BOOL rc;
957 UINT old_timeout;
958 const UINT vals[]={0,32767};
959 unsigned int i;
961 trace("testing SPI_{GET,SET}SCREENSAVETIMEOUT\n");
962 SetLastError(0xdeadbeef);
963 rc=SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &old_timeout, 0 );
964 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVETIMEOUT"))
965 return;
967 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
969 UINT v;
970 char buf[10];
972 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, vals[i], 0,
973 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
974 if (!test_error_msg(rc,"SPI_SETSCREENSAVETIMEOUT")) return;
975 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
976 test_change_message( SPI_SETSCREENSAVETIMEOUT, 0 );
977 sprintf( buf, "%d", vals[i] );
978 test_reg_key( SPI_SETSCREENSAVETIMEOUT_REGKEY,
979 SPI_SETSCREENSAVETIMEOUT_VALNAME, buf );
981 rc = SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &v, 0 );
982 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
983 eq( v, vals[i], "SPI_{GET,SET}SCREENSAVETIMEOUT", "%d" );
986 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, old_timeout, 0,
987 SPIF_UPDATEINIFILE );
988 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
991 static void test_SPI_SETSCREENSAVEACTIVE( void ) /* 17 */
993 BOOL rc;
994 BOOL old_b;
995 const UINT vals[]={TRUE,FALSE};
996 unsigned int i;
998 trace("testing SPI_{GET,SET}SCREENSAVEACTIVE\n");
999 SetLastError(0xdeadbeef);
1000 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &old_b, 0 );
1001 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVEACTIVE"))
1002 return;
1004 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1006 UINT v;
1008 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, vals[i], 0,
1009 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1010 if (!test_error_msg(rc,"SPI_SETSCREENSAVEACTIVE")) return;
1011 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1012 test_change_message( SPI_SETSCREENSAVEACTIVE, 0 );
1013 test_reg_key( SPI_SETSCREENSAVEACTIVE_REGKEY,
1014 SPI_SETSCREENSAVEACTIVE_VALNAME,
1015 vals[i] ? "1" : "0" );
1017 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &v, 0 );
1018 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1019 ok(v == vals[i] || broken(! v) /* Win 7 */,
1020 "SPI_{GET,SET}SCREENSAVEACTIVE: got %d instead of %d\n", v, vals[i]);
1023 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
1024 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1027 static void test_SPI_SETGRIDGRANULARITY( void ) /* 19 */
1029 /* ??? */;
1032 static void test_SPI_SETKEYBOARDDELAY( void ) /* 23 */
1034 BOOL rc;
1035 UINT old_delay;
1036 const UINT vals[]={0,3};
1037 unsigned int i;
1039 trace("testing SPI_{GET,SET}KEYBOARDDELAY\n");
1040 SetLastError(0xdeadbeef);
1041 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &old_delay, 0 );
1042 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDDELAY"))
1043 return;
1045 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1047 UINT delay;
1048 char buf[10];
1050 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, vals[i], 0,
1051 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1052 if (!test_error_msg(rc,"SPI_SETKEYBOARDDELAY")) return;
1053 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1054 test_change_message( SPI_SETKEYBOARDDELAY, 0 );
1055 sprintf( buf, "%d", vals[i] );
1056 test_reg_key( SPI_SETKEYBOARDDELAY_REGKEY,
1057 SPI_SETKEYBOARDDELAY_VALNAME, buf );
1059 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &delay, 0 );
1060 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1061 eq( delay, vals[i], "SPI_{GET,SET}KEYBOARDDELAY", "%d" );
1064 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, old_delay, 0, SPIF_UPDATEINIFILE );
1065 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1069 /* test_SPI_ICONVERTICALSPACING helper */
1070 static BOOL dotest_spi_iconverticalspacing( INT curr_val)
1072 BOOL rc;
1073 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
1074 ICONMETRICSA im;
1076 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0,
1077 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1078 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING")) return FALSE;
1079 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1080 test_change_message( SPI_ICONVERTICALSPACING, 0 );
1081 curr_val = max( curr_val, min_val );
1082 /* The registry keys depend on the Windows version and the values too
1083 * let's test (works on win95,ME,NT4,2k,XP)
1085 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY2, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1086 if( regval != curr_val)
1087 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1088 ok( curr_val == regval,
1089 "wrong value in registry %d, expected %d\n", regval, curr_val);
1090 /* compare with what SPI_ICONVERTICALSPACING returns */
1091 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1092 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1093 eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" );
1094 /* and with a system metrics */
1095 eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" );
1096 /* and with what SPI_GETICONMETRICS returns */
1097 im.cbSize = sizeof(ICONMETRICSA);
1098 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1099 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1100 eq( im.iVertSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
1101 return TRUE;
1104 static void test_SPI_ICONVERTICALSPACING( void ) /* 24 */
1106 BOOL rc;
1107 INT old_spacing;
1109 trace("testing SPI_ICONVERTICALSPACING\n");
1110 SetLastError(0xdeadbeef);
1111 /* default value: 75 */
1112 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &old_spacing, 0 );
1113 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING"))
1114 return;
1115 /* do not increase the value as it would upset the user's icon layout */
1116 if (!dotest_spi_iconverticalspacing( old_spacing - 1)) return;
1117 /* same tests with a value less than the minimum 32 */
1118 dotest_spi_iconverticalspacing( 10);
1119 /* restore */
1120 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, old_spacing, 0,
1121 SPIF_UPDATEINIFILE );
1122 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1125 static void test_SPI_SETICONTITLEWRAP( void ) /* 26 */
1127 BOOL rc;
1128 BOOL old_b;
1129 const UINT vals[]={TRUE,FALSE};
1130 unsigned int i;
1131 ICONMETRICSA im;
1133 /* These tests hang when XFree86 4.0 for Windows is running (tested on
1134 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
1135 * running.
1137 if (FindWindowA( NULL, "Cygwin/XFree86" ))
1138 return;
1140 trace("testing SPI_{GET,SET}ICONTITLEWRAP\n");
1141 SetLastError(0xdeadbeef);
1142 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &old_b, 0 );
1143 if (!test_error_msg(rc,"SPI_{GET,SET}ICONTITLEWRAP"))
1144 return;
1146 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1148 UINT v;
1149 UINT regval;
1151 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, vals[i], 0,
1152 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1153 if (!test_error_msg(rc,"SPI_SETICONTITLEWRAP")) return;
1154 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1155 test_change_message( SPI_SETICONTITLEWRAP, 1 );
1156 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2,
1157 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1158 if( regval != vals[i])
1159 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1,
1160 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1161 ok( regval == vals[i], "wrong value in registry %d, expected %d\n", regval, vals[i] );
1163 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &v, 0 );
1164 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1165 eq( v, vals[i], "SPI_{GET,SET}ICONTITLEWRAP", "%d" );
1166 /* and test with what SPI_GETICONMETRICS returns */
1167 im.cbSize = sizeof(ICONMETRICSA);
1168 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1169 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1170 eq( im.iTitleWrap, (BOOL)vals[i], "SPI_GETICONMETRICS", "%d" );
1173 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, old_b, 0, SPIF_UPDATEINIFILE );
1174 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1177 static void test_SPI_SETMENUDROPALIGNMENT( void ) /* 28 */
1179 BOOL rc;
1180 BOOL old_b;
1181 const UINT vals[]={TRUE,FALSE};
1182 unsigned int i;
1184 trace("testing SPI_{GET,SET}MENUDROPALIGNMENT\n");
1185 SetLastError(0xdeadbeef);
1186 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &old_b, 0 );
1187 if (!test_error_msg(rc,"SPI_{GET,SET}MENUDROPALIGNMENT"))
1188 return;
1190 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1192 UINT v;
1194 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, vals[i], 0,
1195 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1196 if (!test_error_msg(rc,"SPI_SETMENUDROPALIGNMENT")) return;
1197 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1198 test_change_message( SPI_SETMENUDROPALIGNMENT, 0 );
1199 test_reg_key_ex( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1200 SPI_SETMENUDROPALIGNMENT_REGKEY2,
1201 SPI_SETMENUDROPALIGNMENT_VALNAME,
1202 vals[i] ? "1" : "0" );
1204 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &v, 0 );
1205 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1206 eq( v, vals[i], "SPI_{GET,SET}MENUDROPALIGNMENT", "%d" );
1207 eq( GetSystemMetrics( SM_MENUDROPALIGNMENT ), (int)vals[i],
1208 "SM_MENUDROPALIGNMENT", "%d" );
1211 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, old_b, 0,
1212 SPIF_UPDATEINIFILE );
1213 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1216 static void test_SPI_SETDOUBLECLKWIDTH( void ) /* 29 */
1218 BOOL rc;
1219 INT old_width;
1220 const UINT vals[]={0,10000};
1221 unsigned int i;
1223 trace("testing SPI_{GET,SET}DOUBLECLKWIDTH\n");
1224 old_width = GetSystemMetrics( SM_CXDOUBLECLK );
1226 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1228 char buf[10];
1230 SetLastError(0xdeadbeef);
1231 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, vals[i], 0,
1232 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1233 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKWIDTH"))
1234 return;
1236 test_change_message( SPI_SETDOUBLECLKWIDTH, 0 );
1237 sprintf( buf, "%d", vals[i] );
1238 test_reg_key_ex( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1239 SPI_SETDOUBLECLKWIDTH_REGKEY2,
1240 SPI_SETDOUBLECLKWIDTH_VALNAME, buf );
1241 eq( GetSystemMetrics( SM_CXDOUBLECLK ), (int)vals[i],
1242 "SM_CXDOUBLECLK", "%d" );
1245 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, old_width, 0,
1246 SPIF_UPDATEINIFILE );
1247 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1250 static void test_SPI_SETDOUBLECLKHEIGHT( void ) /* 30 */
1252 BOOL rc;
1253 INT old_height;
1254 const UINT vals[]={0,10000};
1255 unsigned int i;
1257 trace("testing SPI_{GET,SET}DOUBLECLKHEIGHT\n");
1258 old_height = GetSystemMetrics( SM_CYDOUBLECLK );
1260 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1262 char buf[10];
1264 SetLastError(0xdeadbeef);
1265 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, vals[i], 0,
1266 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1267 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKHEIGHT"))
1268 return;
1270 test_change_message( SPI_SETDOUBLECLKHEIGHT, 0 );
1271 sprintf( buf, "%d", vals[i] );
1272 test_reg_key_ex( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1273 SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1274 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf );
1275 eq( GetSystemMetrics( SM_CYDOUBLECLK ), (int)vals[i],
1276 "SM_CYDOUBLECLK", "%d" );
1279 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, old_height, 0,
1280 SPIF_UPDATEINIFILE );
1281 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1284 static void test_SPI_SETDOUBLECLICKTIME( void ) /* 32 */
1286 BOOL rc;
1287 UINT curr_val;
1288 UINT saved_val;
1289 UINT old_time;
1290 char buf[10];
1292 trace("testing SPI_{GET,SET}DOUBLECLICKTIME\n");
1293 old_time = GetDoubleClickTime();
1295 curr_val = 0;
1296 SetLastError(0xdeadbeef);
1297 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1298 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1299 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLICKTIME"))
1300 return;
1302 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1303 sprintf( buf, "%d", curr_val );
1304 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1305 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1306 curr_val = 500; /* used value for 0 */
1307 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1309 curr_val = 1000;
1310 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1311 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1312 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1313 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1314 sprintf( buf, "%d", curr_val );
1315 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1316 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1317 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1319 saved_val = curr_val;
1321 curr_val = 0;
1322 SetDoubleClickTime( curr_val );
1323 sprintf( buf, "%d", saved_val );
1324 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1325 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1326 curr_val = 500; /* used value for 0 */
1327 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1329 curr_val = 1000;
1330 SetDoubleClickTime( curr_val );
1331 sprintf( buf, "%d", saved_val );
1332 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1333 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1334 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1336 rc=SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, old_time, 0, SPIF_UPDATEINIFILE);
1337 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1340 static void test_SPI_SETMOUSEBUTTONSWAP( void ) /* 33 */
1342 BOOL rc;
1343 BOOL old_b;
1344 const UINT vals[]={TRUE,FALSE};
1345 unsigned int i;
1347 trace("testing SPI_{GET,SET}MOUSEBUTTONSWAP\n");
1348 old_b = GetSystemMetrics( SM_SWAPBUTTON );
1350 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1352 SetLastError(0xdeadbeef);
1353 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[i], 0,
1354 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1355 if (!test_error_msg(rc,"SPI_SETMOUSEBUTTONSWAP")) return;
1357 test_change_message( SPI_SETMOUSEBUTTONSWAP, 0 );
1358 test_reg_key( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1359 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1360 vals[i] ? "1" : "0" );
1361 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i],
1362 "SM_SWAPBUTTON", "%d" );
1363 rc=SwapMouseButton((BOOL)vals[i^1]);
1364 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i^1],
1365 "SwapMouseButton", "%d" );
1366 ok( rc==(BOOL)vals[i], "SwapMouseButton does not return previous state (really %d)\n", rc );
1369 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, old_b, 0,
1370 SPIF_UPDATEINIFILE );
1371 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1374 static void test_SPI_SETFASTTASKSWITCH( void ) /* 36 */
1376 BOOL rc;
1377 BOOL v;
1379 trace("testing SPI_GETFASTTASKSWITCH\n");
1380 SetLastError(0xdeadbeef);
1381 rc=SystemParametersInfoA( SPI_GETFASTTASKSWITCH, 0, &v, 0 );
1382 if (!test_error_msg(rc,"SPI_{GET,SET}FASTTASKSWITCH"))
1383 return;
1385 /* there is not a single Windows platform on which SPI_GETFASTTASKSWITCH
1386 * works. That sure simplifies testing!
1390 static void test_SPI_SETDRAGFULLWINDOWS( void ) /* 37 */
1392 BOOL rc;
1393 BOOL old_b;
1394 const UINT vals[]={TRUE,FALSE};
1395 unsigned int i;
1397 trace("testing SPI_{GET,SET}DRAGFULLWINDOWS\n");
1398 SetLastError(0xdeadbeef);
1399 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &old_b, 0 );
1401 /* SPI_{GET,SET}DRAGFULLWINDOWS is not implemented on Win95 */
1402 if (!test_error_msg(rc,"SPI_{GET,SET}DRAGFULLWINDOWS"))
1403 return;
1405 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1407 UINT v;
1409 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, vals[i], 0,
1410 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1411 if (!test_error_msg(rc,"SPI_SETDRAGFULLWINDOWS")) return;
1412 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1413 test_change_message( SPI_SETDRAGFULLWINDOWS, 0 );
1414 test_reg_key( SPI_SETDRAGFULLWINDOWS_REGKEY,
1415 SPI_SETDRAGFULLWINDOWS_VALNAME,
1416 vals[i] ? "1" : "0" );
1418 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &v, 0 );
1419 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1420 eq( v, vals[i], "SPI_{GET,SET}DRAGFULLWINDOWS", "%d" );
1423 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, old_b, 0, SPIF_UPDATEINIFILE );
1424 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1427 #define test_reg_metric( KEY, VAL, val) do { \
1428 INT regval;\
1429 regval = metricfromreg( KEY, VAL, dpi);\
1430 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1431 } while(0)
1433 #define test_reg_metric2( KEY1, KEY2, VAL, val) do { \
1434 INT regval;\
1435 regval = metricfromreg( KEY1, VAL, dpi);\
1436 if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\
1437 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1438 } while(0)
1440 #define test_reg_font( KEY, VAL, LF) do { \
1441 LOGFONTA lfreg;\
1442 lffromreg( KEY, VAL, &lfreg);\
1443 ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == MulDiv( lfreg.lfHeight, dpi, real_dpi ) : \
1444 MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\
1445 (LF).lfWidth == lfreg.lfWidth &&\
1446 (LF).lfWeight == lfreg.lfWeight &&\
1447 !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\
1448 , "wrong value \"%s\" in registry %d, %d\n", VAL, (LF).lfHeight, lfreg.lfHeight);\
1449 } while(0)
1451 #define TEST_NONCLIENTMETRICS_REG( ncm) do { \
1452 /*FIXME: test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);*/\
1453 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\
1454 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\
1455 /*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\
1456 test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\
1457 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\
1458 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\
1459 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\
1460 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\
1461 test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\
1462 test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\
1463 test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\
1464 test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\
1465 test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont); } while(0)
1467 /* get text metric height value for the specified logfont */
1468 static int get_tmheight( LOGFONTA *plf, int flag)
1470 TEXTMETRICA tm;
1471 HDC hdc = GetDC(0);
1472 HFONT hfont = CreateFontIndirectA( plf);
1473 hfont = SelectObject( hdc, hfont);
1474 GetTextMetricsA( hdc, &tm);
1475 hfont = SelectObject( hdc, hfont);
1476 ReleaseDC( 0, hdc );
1477 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1480 static int get_tmheightW( LOGFONTW *plf, int flag)
1482 TEXTMETRICW tm;
1483 HDC hdc = GetDC(0);
1484 HFONT hfont = CreateFontIndirectW( plf);
1485 hfont = SelectObject( hdc, hfont);
1486 GetTextMetricsW( hdc, &tm);
1487 hfont = SelectObject( hdc, hfont);
1488 ReleaseDC( 0, hdc );
1489 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1492 static void test_GetSystemMetrics( void);
1493 static UINT smcxsmsize = 999999999;
1495 static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */
1497 BOOL rc;
1498 INT expect;
1499 NONCLIENTMETRICSA Ncmorig;
1500 NONCLIENTMETRICSA Ncmnew;
1501 NONCLIENTMETRICSA Ncmcur;
1502 NONCLIENTMETRICSA Ncmstart;
1504 Ncmorig.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1505 Ncmnew.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1506 Ncmcur.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1507 Ncmstart.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1509 trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n");
1510 change_counter = 0;
1511 SetLastError(0xdeadbeef);
1512 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmorig, FALSE );
1513 if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS"))
1514 return;
1515 Ncmstart = Ncmorig;
1516 smcxsmsize = Ncmstart.iSmCaptionWidth;
1517 /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if
1518 the caption font height is higher than the CaptionHeight field,
1519 the latter is adjusted accordingly. To be able to restore these setting
1520 accurately be restore the raw values. */
1521 Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, real_dpi);
1522 Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi);
1523 Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi);
1524 Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi);
1525 /* test registry entries */
1526 TEST_NONCLIENTMETRICS_REG( Ncmorig);
1528 /* make small changes */
1529 Ncmnew = Ncmstart;
1530 Ncmnew.iBorderWidth += 1;
1531 Ncmnew.iScrollWidth += 1;
1532 Ncmnew.iScrollHeight -= 1;
1533 Ncmnew.iCaptionWidth -= 2;
1534 Ncmnew.iCaptionHeight += 2;
1535 Ncmnew.lfCaptionFont.lfHeight +=1;
1536 Ncmnew.lfCaptionFont.lfWidth +=2;
1537 Ncmnew.lfCaptionFont.lfWeight +=1;
1538 Ncmnew.iSmCaptionWidth += 1;
1539 Ncmnew.iSmCaptionHeight += 2;
1540 Ncmnew.lfSmCaptionFont.lfHeight +=3;
1541 Ncmnew.lfSmCaptionFont.lfWidth -=1;
1542 Ncmnew.lfSmCaptionFont.lfWeight +=3;
1543 Ncmnew.iMenuWidth += 1;
1544 Ncmnew.iMenuHeight += 2;
1545 Ncmnew.lfMenuFont.lfHeight +=1;
1546 Ncmnew.lfMenuFont.lfWidth +=1;
1547 Ncmnew.lfMenuFont.lfWeight +=2;
1548 Ncmnew.lfStatusFont.lfHeight -=1;
1549 Ncmnew.lfStatusFont.lfWidth -=1;
1550 Ncmnew.lfStatusFont.lfWeight +=3;
1551 Ncmnew.lfMessageFont.lfHeight -=2;
1552 Ncmnew.lfMessageFont.lfWidth -=1;
1553 Ncmnew.lfMessageFont.lfWeight +=4;
1555 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1556 SPIF_SENDCHANGE);
1557 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return;
1558 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1559 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1560 /* get them back */
1561 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1562 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1563 /* test registry entries */
1564 TEST_NONCLIENTMETRICS_REG( Ncmcur );
1565 /* test the system metrics with these settings */
1566 test_GetSystemMetrics();
1567 /* now for something invalid: increase the {menu|caption|smcaption} fonts
1568 by a large amount will increase the {menu|caption|smcaption} height*/
1569 Ncmnew = Ncmstart;
1570 Ncmnew.lfMenuFont.lfHeight -= 8;
1571 Ncmnew.lfCaptionFont.lfHeight =-4;
1572 Ncmnew.lfSmCaptionFont.lfHeight -=10;
1573 /* also show that a few values are lo limited */
1574 Ncmnew.iCaptionWidth = 0;
1575 Ncmnew.iCaptionHeight = 0;
1576 Ncmnew.iScrollHeight = 0;
1577 Ncmnew.iScrollWidth = 0;
1579 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1580 SPIF_SENDCHANGE);
1581 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1582 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1583 /* raw values are in registry */
1584 TEST_NONCLIENTMETRICS_REG( Ncmnew );
1585 /* get them back */
1586 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1587 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1588 /* cooked values are returned */
1589 expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1));
1590 ok( Ncmcur.iMenuHeight == expect,
1591 "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect);
1592 expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0));
1593 ok( Ncmcur.iCaptionHeight == expect,
1594 "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect);
1595 expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0));
1596 ok( Ncmcur.iSmCaptionHeight == expect,
1597 "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect);
1599 /* iCaptionWidth depends on a version, could be 8, 12 (Vista, Win7), 13 */
1600 ok( (Ncmcur.iCaptionWidth >= 8 && Ncmcur.iCaptionWidth <= 13) ||
1601 Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */
1602 "CaptionWidth: %d expected from [8, 13] or %d\n", Ncmcur.iCaptionWidth, Ncmstart.iCaptionWidth);
1603 ok( Ncmcur.iScrollWidth == 8,
1604 "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth);
1605 ok( Ncmcur.iScrollHeight == 8,
1606 "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight);
1607 /* test the system metrics with these settings */
1608 test_GetSystemMetrics();
1609 /* restore */
1610 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA),
1611 &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1612 test_change_message( SPI_SETNONCLIENTMETRICS, 0 );
1613 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1614 /* test the system metrics with these settings */
1615 test_GetSystemMetrics();
1618 static void test_SPI_SETMINIMIZEDMETRICS( void ) /* 44 */
1620 BOOL rc;
1621 INT regval;
1622 MINIMIZEDMETRICS lpMm_orig;
1623 MINIMIZEDMETRICS lpMm_new;
1624 MINIMIZEDMETRICS lpMm_cur;
1626 lpMm_orig.cbSize = sizeof(MINIMIZEDMETRICS);
1627 lpMm_new.cbSize = sizeof(MINIMIZEDMETRICS);
1628 lpMm_cur.cbSize = sizeof(MINIMIZEDMETRICS);
1630 trace("testing SPI_{GET,SET}MINIMIZEDMETRICS\n");
1631 SetLastError(0xdeadbeef);
1632 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_orig, FALSE );
1633 if (!test_error_msg(rc,"SPI_{GET,SET}MINIMIZEDMETRICS"))
1634 return;
1635 /* Test registry. Note that it is perfectly valid for some fields to
1636 * not be set.
1638 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1639 ok( regval == -1 || regval == lpMm_orig.iWidth, "wrong value in registry %d, expected %d\n",
1640 regval, lpMm_orig.iWidth);
1641 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1642 ok( regval == -1 || regval == lpMm_orig.iHorzGap, "wrong value in registry %d, expected %d\n",
1643 regval, lpMm_orig.iHorzGap);
1644 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1645 ok( regval == -1 || regval == lpMm_orig.iVertGap, "wrong value in registry %d, expected %d\n",
1646 regval, lpMm_orig.iVertGap);
1647 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1648 ok( regval == -1 || regval == lpMm_orig.iArrange, "wrong value in registry %d, expected %d\n",
1649 regval, lpMm_orig.iArrange);
1650 /* set some new values */
1651 lpMm_cur.iWidth = 180;
1652 lpMm_cur.iHorzGap = 1;
1653 lpMm_cur.iVertGap = 1;
1654 lpMm_cur.iArrange = 5;
1655 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1656 &lpMm_cur, SPIF_UPDATEINIFILE );
1657 if (!test_error_msg(rc,"SPI_SETMINIMIZEDMETRICS")) return;
1658 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1659 /* read them back */
1660 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1661 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1662 /* and compare */
1663 eq( lpMm_new.iWidth, lpMm_cur.iWidth, "iWidth", "%d" );
1664 eq( lpMm_new.iHorzGap, lpMm_cur.iHorzGap, "iHorzGap", "%d" );
1665 eq( lpMm_new.iVertGap, lpMm_cur.iVertGap, "iVertGap", "%d" );
1666 eq( lpMm_new.iArrange, lpMm_cur.iArrange, "iArrange", "%d" );
1667 /* test registry */
1668 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1669 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1670 regval, lpMm_new.iWidth);
1671 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1672 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1673 regval, lpMm_new.iHorzGap);
1674 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1675 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1676 regval, lpMm_new.iVertGap);
1677 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1678 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1679 regval, lpMm_new.iArrange);
1680 /* test some system metrics */
1681 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1682 lpMm_new.iWidth, "iWidth", "%d" );
1683 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1684 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1685 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1686 lpMm_new.iVertGap, "iVertGap", "%d" );
1687 eq( GetSystemMetrics( SM_ARRANGE ),
1688 lpMm_new.iArrange, "iArrange", "%d" );
1689 /* now some really invalid settings */
1690 lpMm_cur.iWidth = -1;
1691 lpMm_cur.iHorzGap = -1;
1692 lpMm_cur.iVertGap = -1;
1693 lpMm_cur.iArrange = - 1;
1694 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1695 &lpMm_cur, SPIF_UPDATEINIFILE );
1696 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1697 /* read back */
1698 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1699 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1700 /* the width and H/V gaps have minimum 0, arrange is and'd with 0xf */
1701 eq( lpMm_new.iWidth, 0, "iWidth", "%d" );
1702 eq( lpMm_new.iHorzGap, 0, "iHorzGap", "%d" );
1703 eq( lpMm_new.iVertGap, 0, "iVertGap", "%d" );
1704 eq( lpMm_new.iArrange, 0xf & lpMm_cur.iArrange, "iArrange", "%d" );
1705 /* test registry */
1706 if (0)
1708 /* FIXME: cannot understand the results of this (11, 11, 11, 0) */
1709 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1710 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1711 regval, lpMm_new.iWidth);
1712 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1713 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1714 regval, lpMm_new.iHorzGap);
1715 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1716 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1717 regval, lpMm_new.iVertGap);
1718 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1719 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1720 regval, lpMm_new.iArrange);
1722 /* test some system metrics */
1723 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1724 lpMm_new.iWidth, "iWidth", "%d" );
1725 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1726 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1727 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1728 lpMm_new.iVertGap, "iVertGap", "%d" );
1729 eq( GetSystemMetrics( SM_ARRANGE ),
1730 lpMm_new.iArrange, "iArrange", "%d" );
1731 /* restore */
1732 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1733 &lpMm_orig, SPIF_UPDATEINIFILE );
1734 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1735 /* check that */
1736 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1737 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1738 eq( lpMm_new.iWidth, lpMm_orig.iWidth, "iWidth", "%d" );
1739 eq( lpMm_new.iHorzGap, lpMm_orig.iHorzGap, "iHorzGap", "%d" );
1740 eq( lpMm_new.iVertGap, lpMm_orig.iVertGap, "iVertGap", "%d" );
1741 eq( lpMm_new.iArrange, lpMm_orig.iArrange, "iArrange", "%d" );
1744 static void test_SPI_SETICONMETRICS( void ) /* 46 */
1746 BOOL rc, wrap;
1747 INT spacing;
1748 ICONMETRICSA im_orig;
1749 ICONMETRICSA im_new;
1750 ICONMETRICSA im_cur;
1751 INT regval;
1753 im_orig.cbSize = sizeof(ICONMETRICSA);
1754 im_new.cbSize = sizeof(ICONMETRICSA);
1755 im_cur.cbSize = sizeof(ICONMETRICSA);
1757 trace("testing SPI_{GET,SET}ICONMETRICS\n");
1758 SetLastError(0xdeadbeef);
1759 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE );
1760 if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS"))
1761 return;
1762 /* check some registry values */
1763 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1764 ok( regval==im_orig.iHorzSpacing,
1765 "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing);
1766 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1767 ok( regval==im_orig.iVertSpacing,
1768 "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing);
1769 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1770 if( regval != im_orig.iTitleWrap)
1771 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1772 ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap);
1774 /* change everything without creating something invalid ( Win9x would ignore
1775 * an invalid font for instance) */
1776 im_cur = im_orig;
1777 im_cur.iHorzSpacing += 10;
1778 im_cur.iVertSpacing += 6;
1779 im_cur.iTitleWrap = !im_cur.iTitleWrap;
1780 im_cur.lfFont.lfHeight += 1;
1781 im_cur.lfFont.lfWidth += 2;
1782 im_cur.lfFont.lfEscapement = 1;
1783 im_cur.lfFont.lfWeight = im_cur.lfFont.lfWeight > 100 ? 1 : 314;
1784 im_cur.lfFont.lfItalic = !im_cur.lfFont.lfItalic;
1785 im_cur.lfFont.lfStrikeOut = !im_cur.lfFont.lfStrikeOut;
1786 im_cur.lfFont.lfUnderline = !im_cur.lfFont.lfUnderline;
1787 im_cur.lfFont.lfCharSet = im_cur.lfFont.lfCharSet ? 0 : 1;
1788 im_cur.lfFont.lfOutPrecision = im_cur.lfFont.lfOutPrecision == OUT_DEFAULT_PRECIS ?
1789 OUT_TT_PRECIS : OUT_DEFAULT_PRECIS;
1790 im_cur.lfFont.lfClipPrecision ^= CLIP_LH_ANGLES;
1791 im_cur.lfFont.lfPitchAndFamily = im_cur.lfFont.lfPitchAndFamily ? 0 : 1;
1792 im_cur.lfFont.lfQuality = im_cur.lfFont.lfQuality == DEFAULT_QUALITY ?
1793 DRAFT_QUALITY : DEFAULT_QUALITY;
1794 if( strcmp( im_cur.lfFont.lfFaceName, "MS Serif"))
1795 strcpy( im_cur.lfFont.lfFaceName, "MS Serif");
1796 else
1797 strcpy( im_cur.lfFont.lfFaceName, "MS Sans Serif");
1799 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, SPIF_UPDATEINIFILE );
1800 if (!test_error_msg(rc,"SPI_SETICONMETRICS")) return;
1801 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1803 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1804 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1805 /* test GET <-> SETICONMETRICS */
1806 eq( im_new.iHorzSpacing, im_cur.iHorzSpacing, "iHorzSpacing", "%d" );
1807 eq( im_new.iVertSpacing, im_cur.iVertSpacing, "iVertSpacing", "%d" );
1808 eq( im_new.iTitleWrap, im_cur.iTitleWrap, "iTitleWrap", "%d" );
1809 eq( im_new.lfFont.lfHeight, im_cur.lfFont.lfHeight, "lfHeight", "%d" );
1810 eq( im_new.lfFont.lfWidth, im_cur.lfFont.lfWidth, "lfWidth", "%d" );
1811 eq( im_new.lfFont.lfEscapement, im_cur.lfFont.lfEscapement, "lfEscapement", "%d" );
1812 eq( im_new.lfFont.lfWeight, im_cur.lfFont.lfWeight, "lfWeight", "%d" );
1813 eq( im_new.lfFont.lfItalic, im_cur.lfFont.lfItalic, "lfItalic", "%d" );
1814 eq( im_new.lfFont.lfStrikeOut, im_cur.lfFont.lfStrikeOut, "lfStrikeOut", "%d" );
1815 eq( im_new.lfFont.lfUnderline, im_cur.lfFont.lfUnderline, "lfUnderline", "%d" );
1816 eq( im_new.lfFont.lfCharSet, im_cur.lfFont.lfCharSet, "lfCharSet", "%d" );
1817 eq( im_new.lfFont.lfOutPrecision, im_cur.lfFont.lfOutPrecision, "lfOutPrecision", "%d" );
1818 eq( im_new.lfFont.lfClipPrecision, im_cur.lfFont.lfClipPrecision, "lfClipPrecision", "%d" );
1819 eq( im_new.lfFont.lfPitchAndFamily, im_cur.lfFont.lfPitchAndFamily, "lfPitchAndFamily", "%d" );
1820 eq( im_new.lfFont.lfQuality, im_cur.lfFont.lfQuality, "lfQuality", "%d" );
1821 ok( !strcmp( im_new.lfFont.lfFaceName, im_cur.lfFont.lfFaceName),
1822 "wrong facename \"%s\", should be \"%s\"\n", im_new.lfFont.lfFaceName,
1823 im_cur.lfFont.lfFaceName);
1824 /* test some system metrics */
1825 eq( GetSystemMetrics( SM_CXICONSPACING ),
1826 im_new.iHorzSpacing, "iHorzSpacing", "%d" );
1827 eq( GetSystemMetrics( SM_CYICONSPACING ),
1828 im_new.iVertSpacing, "iVertSpacing", "%d" );
1829 /* check some registry values */
1830 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1831 ok( regval==im_cur.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iHorzSpacing);
1832 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1833 ok( regval==im_cur.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iVertSpacing);
1834 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1835 if( regval != im_cur.iTitleWrap)
1836 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1837 ok( regval==im_cur.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_cur.iTitleWrap);
1838 /* test some values from other SPI_GETxxx calls */
1839 rc = SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
1840 ok( rc && spacing == im_cur.iHorzSpacing,
1841 "SystemParametersInfoA( SPI_ICONHORIZONTALSPACING...) failed or returns wrong value %d instead of %d\n",
1842 spacing, im_cur.iHorzSpacing);
1843 rc = SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1844 ok( rc && spacing == im_cur.iVertSpacing,
1845 "SystemParametersInfoA( SPI_ICONVERTICALSPACING...) failed or returns wrong value %d instead of %d\n",
1846 spacing, im_cur.iVertSpacing);
1847 rc = SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &wrap, 0 );
1848 ok( rc && wrap == im_cur.iTitleWrap,
1849 "SystemParametersInfoA( SPI_GETICONTITLEWRAP...) failed or returns wrong value %d instead of %d\n",
1850 wrap, im_cur.iTitleWrap);
1851 /* restore old values */
1852 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig,SPIF_UPDATEINIFILE );
1853 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1855 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1856 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1858 eq( im_new.iHorzSpacing, im_orig.iHorzSpacing, "iHorzSpacing", "%d" );
1859 eq( im_new.iVertSpacing, im_orig.iVertSpacing, "iVertSpacing", "%d" );
1860 eq( im_new.iTitleWrap, im_orig.iTitleWrap, "iTitleWrap", "%d" );
1863 static void test_SPI_SETWORKAREA( void ) /* 47 */
1865 BOOL rc;
1866 RECT old_area;
1867 RECT area;
1868 RECT curr_val;
1870 trace("testing SPI_{GET,SET}WORKAREA\n");
1871 SetLastError(0xdeadbeef);
1872 rc=SystemParametersInfoA(SPI_GETWORKAREA, 0, &old_area, 0);
1873 if (!test_error_msg(rc,"SPI_{GET,SET}WORKAREA"))
1874 return;
1876 /* Modify the work area only minimally as this causes the icons that
1877 * fall outside it to be moved around thus requiring the user to
1878 * reposition them manually one by one.
1879 * Changing the work area by just one pixel should make this occurrence
1880 * reasonably unlikely.
1882 SetRect(&curr_val, old_area.left, old_area.top, old_area.right - 1, old_area.bottom - 1);
1883 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &curr_val,
1884 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1885 if (!test_error_msg(rc,"SPI_SETWORKAREA")) return;
1886 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1887 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1888 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1889 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1890 test_change_message( SPI_SETWORKAREA, 0);
1891 eq( area.left, curr_val.left, "left", "%d" );
1892 eq( area.top, curr_val.top, "top", "%d" );
1893 /* size may be rounded */
1894 ok( area.right >= curr_val.right - 16 && area.right < curr_val.right + 16,
1895 "right: got %d instead of %d\n", area.right, curr_val.right );
1896 ok( area.bottom >= curr_val.bottom - 16 && area.bottom < curr_val.bottom + 16,
1897 "bottom: got %d instead of %d\n", area.bottom, curr_val.bottom );
1898 curr_val = area;
1899 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &old_area,
1900 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1901 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1902 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1903 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1904 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1905 test_change_message( SPI_SETWORKAREA, 0 );
1906 eq( area.left, old_area.left, "left", "%d" );
1907 eq( area.top, old_area.top, "top", "%d" );
1908 /* size may be rounded */
1909 ok( area.right >= old_area.right - 16 && area.right < old_area.right + 16,
1910 "right: got %d instead of %d\n", area.right, old_area.right );
1911 ok( area.bottom >= old_area.bottom - 16 && area.bottom < old_area.bottom + 16,
1912 "bottom: got %d instead of %d\n", area.bottom, old_area.bottom );
1915 static void test_SPI_SETSHOWSOUNDS( void ) /* 57 */
1917 BOOL rc;
1918 BOOL old_b;
1919 const UINT vals[]={TRUE,FALSE};
1920 unsigned int i;
1922 trace("testing SPI_{GET,SET}SHOWSOUNDS\n");
1923 SetLastError(0xdeadbeef);
1924 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &old_b, 0 );
1925 if (!test_error_msg(rc,"SPI_{GET,SET}SHOWSOUNDS"))
1926 return;
1928 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1930 UINT v;
1932 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0,
1933 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1934 if (!test_error_msg(rc,"SPI_SETSHOWSOUNDS")) return;
1935 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1936 test_change_message( SPI_SETSHOWSOUNDS, 1 );
1937 test_reg_key( SPI_SETSHOWSOUNDS_REGKEY,
1938 SPI_SETSHOWSOUNDS_VALNAME,
1939 vals[i] ? "1" : "0" );
1941 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &v, 0 );
1942 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1943 eq( v, vals[i], "SPI_GETSHOWSOUNDS", "%d" );
1944 eq( GetSystemMetrics( SM_SHOWSOUNDS ), (int)vals[i],
1945 "SM_SHOWSOUNDS", "%d" );
1948 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, old_b, 0, SPIF_UPDATEINIFILE );
1949 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1952 static void test_SPI_SETKEYBOARDPREF( void ) /* 69 */
1954 BOOL rc;
1955 BOOL old_b;
1956 const UINT vals[]={TRUE,FALSE};
1957 unsigned int i;
1959 trace("testing SPI_{GET,SET}KEYBOARDPREF\n");
1960 SetLastError(0xdeadbeef);
1961 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &old_b, 0 );
1962 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDPREF"))
1963 return;
1965 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
1967 BOOL v;
1969 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0,
1970 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1971 if (!test_error_msg(rc,"SPI_SETKEYBOARDPREF")) return;
1972 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1973 test_change_message( SPI_SETKEYBOARDPREF, 1 );
1974 test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY,
1975 SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY,
1976 vals[i] ? "1" : "0" );
1978 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &v, 0 );
1979 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1980 eq( v, (BOOL)vals[i], "SPI_GETKEYBOARDPREF", "%d" );
1983 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, old_b, 0, SPIF_UPDATEINIFILE );
1984 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1987 static void test_SPI_SETSCREENREADER( void ) /* 71 */
1989 BOOL rc;
1990 BOOL old_b;
1991 const UINT vals[]={TRUE,FALSE};
1992 unsigned int i;
1994 trace("testing SPI_{GET,SET}SCREENREADER\n");
1995 SetLastError(0xdeadbeef);
1996 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &old_b, 0 );
1997 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENREADER"))
1998 return;
2000 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2002 BOOL v;
2004 rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0,
2005 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2006 if (!test_error_msg(rc,"SPI_SETSCREENREADER")) return;
2007 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2008 test_change_message( SPI_SETSCREENREADER, 1 );
2009 test_reg_key_ex2_optional( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY,
2010 SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY,
2011 vals[i] ? "1" : "0" );
2013 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &v, 0 );
2014 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2015 eq( v, (BOOL)vals[i], "SPI_GETSCREENREADER", "%d" );
2018 rc=SystemParametersInfoA( SPI_SETSCREENREADER, old_b, 0, SPIF_UPDATEINIFILE );
2019 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2022 static void test_SPI_SETFONTSMOOTHING( void ) /* 75 */
2024 BOOL rc;
2025 BOOL old_b;
2026 DWORD old_type, old_contrast, old_orient;
2027 const UINT vals[]={0xffffffff,0,1,2};
2028 unsigned int i;
2030 trace("testing SPI_{GET,SET}FONTSMOOTHING\n");
2031 SetLastError(0xdeadbeef);
2032 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &old_b, 0 );
2033 if (!test_error_msg(rc,"SPI_{GET,SET}FONTSMOOTHING"))
2034 return;
2035 SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &old_type, 0 );
2036 SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &old_contrast, 0 );
2037 SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &old_orient, 0 );
2039 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2041 UINT v;
2043 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, vals[i], 0,
2044 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2045 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHING")) return;
2046 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2047 test_change_message( SPI_SETFONTSMOOTHING, 0 );
2048 test_reg_key( SPI_SETFONTSMOOTHING_REGKEY,
2049 SPI_SETFONTSMOOTHING_VALNAME,
2050 vals[i] ? "2" : "0" );
2052 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, 0, UlongToPtr(vals[i]),
2053 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2054 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGTYPE")) return;
2055 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2056 test_change_message( SPI_SETFONTSMOOTHINGTYPE, 0 );
2057 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2058 SPI_SETFONTSMOOTHINGTYPE_VALNAME, &vals[i] );
2060 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, 0, UlongToPtr(vals[i]),
2061 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2062 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGCONTRAST")) return;
2063 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2064 test_change_message( SPI_SETFONTSMOOTHINGCONTRAST, 0 );
2065 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2066 SPI_SETFONTSMOOTHINGCONTRAST_VALNAME, &vals[i] );
2068 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, 0, UlongToPtr(vals[i]),
2069 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2070 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGORIENTATION")) return;
2071 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2072 test_change_message( SPI_SETFONTSMOOTHINGORIENTATION, 0 );
2073 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2074 SPI_SETFONTSMOOTHINGORIENTATION_VALNAME, &vals[i] );
2076 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &v, 0 );
2077 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2078 eq( v, vals[i] ? 1 : 0, "SPI_GETFONTSMOOTHING", "%d" );
2080 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &v, 0 );
2081 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2082 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2084 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &v, 0 );
2085 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2086 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2088 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &v, 0 );
2089 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2090 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2093 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, old_b, 0, SPIF_UPDATEINIFILE );
2094 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2095 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, old_type, 0, SPIF_UPDATEINIFILE );
2096 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2097 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, old_contrast, 0, SPIF_UPDATEINIFILE );
2098 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2099 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, old_orient, 0, SPIF_UPDATEINIFILE );
2100 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2103 static void test_SPI_SETLOWPOWERACTIVE( void ) /* 85 */
2105 BOOL rc;
2106 BOOL old_b;
2107 const UINT vals[]={TRUE,FALSE};
2108 unsigned int i;
2110 trace("testing SPI_{GET,SET}LOWPOWERACTIVE\n");
2111 SetLastError(0xdeadbeef);
2112 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &old_b, 0 );
2113 if (!test_error_msg(rc,"SPI_{GET,SET}LOWPOWERACTIVE"))
2114 return;
2116 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2118 UINT v;
2120 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0,
2121 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2122 if (!test_error_msg(rc,"SPI_SETLOWPOWERACTIVE")) return;
2123 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2124 test_change_message( SPI_SETLOWPOWERACTIVE, 1 );
2125 test_reg_key_optional( SPI_SETLOWPOWERACTIVE_REGKEY,
2126 SPI_SETLOWPOWERACTIVE_VALNAME,
2127 vals[i] ? "1" : "0" );
2129 /* SPI_SETLOWPOWERACTIVE is not persistent in win2k3 and above */
2130 v = 0xdeadbeef;
2131 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 );
2132 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2133 ok(v == vals[i] || v == 0, /* win2k3 */
2134 "SPI_GETLOWPOWERACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2137 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2138 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2141 static void test_SPI_SETPOWEROFFACTIVE( void ) /* 86 */
2143 BOOL rc;
2144 BOOL old_b;
2145 const UINT vals[]={TRUE,FALSE};
2146 unsigned int i;
2148 trace("testing SPI_{GET,SET}POWEROFFACTIVE\n");
2149 SetLastError(0xdeadbeef);
2150 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &old_b, 0 );
2151 if (!test_error_msg(rc,"SPI_{GET,SET}POWEROFFACTIVE"))
2152 return;
2154 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2156 UINT v;
2158 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0,
2159 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2160 if (!test_error_msg(rc,"SPI_SETPOWEROFFACTIVE")) return;
2161 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2162 test_change_message( SPI_SETPOWEROFFACTIVE, 1 );
2163 test_reg_key_optional( SPI_SETPOWEROFFACTIVE_REGKEY,
2164 SPI_SETPOWEROFFACTIVE_VALNAME,
2165 vals[i] ? "1" : "0" );
2167 /* SPI_SETPOWEROFFACTIVE is not persistent in win2k3 and above */
2168 v = 0xdeadbeef;
2169 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 );
2170 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2171 ok(v == vals[i] || v == 0, /* win2k3 */
2172 "SPI_GETPOWEROFFACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2175 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2176 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2179 static void test_SPI_SETSNAPTODEFBUTTON( void ) /* 95 */
2181 BOOL rc;
2182 BOOL old_b;
2183 const UINT vals[]={TRUE,FALSE};
2184 unsigned int i;
2186 trace("testing SPI_{GET,SET}SNAPTODEFBUTTON\n");
2187 SetLastError(0xdeadbeef);
2188 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &old_b, 0 );
2189 if (!test_error_msg(rc,"SPI_GETSNAPTODEFBUTTON"))
2190 return;
2192 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2194 UINT v;
2196 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, vals[i], 0,
2197 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2198 if (!test_error_msg(rc,"SPI_SETSNAPTODEFBUTTON")) return;
2199 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2200 test_change_message( SPI_SETSNAPTODEFBUTTON, 0 );
2201 test_reg_key_optional( SPI_SETSNAPTODEFBUTTON_REGKEY,
2202 SPI_SETSNAPTODEFBUTTON_VALNAME,
2203 vals[i] ? "1" : "0" );
2205 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &v, 0 );
2206 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2207 eq( v, vals[i], "SPI_GETSNAPTODEFBUTTON", "%d" );
2210 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, old_b, 0, SPIF_UPDATEINIFILE );
2211 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2214 static void test_SPI_SETMOUSEHOVERWIDTH( void ) /* 99 */
2216 BOOL rc;
2217 UINT old_width;
2218 const UINT vals[]={0,32767};
2219 unsigned int i;
2221 trace("testing SPI_{GET,SET}MOUSEHOVERWIDTH\n");
2222 SetLastError(0xdeadbeef);
2223 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &old_width, 0 );
2224 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERWIDTH"))
2225 return;
2227 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2229 UINT v;
2230 char buf[10];
2232 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, vals[i], 0,
2233 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2234 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERWIDTH")) return;
2235 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2236 test_change_message( SPI_SETMOUSEHOVERWIDTH, 0 );
2237 sprintf( buf, "%d", vals[i] );
2238 test_reg_key( SPI_SETMOUSEHOVERWIDTH_REGKEY,
2239 SPI_SETMOUSEHOVERWIDTH_VALNAME, buf );
2241 SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &v, 0 );
2242 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2243 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERWIDTH", "%d" );
2246 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, old_width, 0,
2247 SPIF_UPDATEINIFILE );
2248 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2251 static void test_SPI_SETMOUSEHOVERHEIGHT( void ) /* 101 */
2253 BOOL rc;
2254 UINT old_height;
2255 const UINT vals[]={0,32767};
2256 unsigned int i;
2258 trace("testing SPI_{GET,SET}MOUSEHOVERHEIGHT\n");
2259 SetLastError(0xdeadbeef);
2260 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &old_height, 0 );
2261 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERHEIGHT"))
2262 return;
2264 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2266 UINT v;
2267 char buf[10];
2269 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, vals[i], 0,
2270 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2271 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERHEIGHT")) return;
2272 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2273 test_change_message( SPI_SETMOUSEHOVERHEIGHT, 0 );
2274 sprintf( buf, "%d", vals[i] );
2275 test_reg_key( SPI_SETMOUSEHOVERHEIGHT_REGKEY,
2276 SPI_SETMOUSEHOVERHEIGHT_VALNAME, buf );
2278 SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &v, 0 );
2279 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2280 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERHEIGHT", "%d" );
2283 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, old_height, 0,
2284 SPIF_UPDATEINIFILE );
2285 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2288 static void test_SPI_SETMOUSEHOVERTIME( void ) /* 103 */
2290 BOOL rc;
2291 UINT old_time;
2293 /* Windows XP accepts 10 as the minimum hover time. Any value below will be
2294 * defaulted to a value of 10 automatically.
2296 const UINT vals[]={10,32767};
2297 unsigned int i;
2299 trace("testing SPI_{GET,SET}MOUSEHOVERTIME\n");
2300 SetLastError(0xdeadbeef);
2301 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &old_time, 0 );
2302 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERTIME"))
2303 return;
2305 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2307 UINT v;
2308 char buf[10];
2310 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, vals[i], 0,
2311 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2312 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERTIME")) return;
2313 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2314 test_change_message( SPI_SETMOUSEHOVERTIME, 0 );
2315 sprintf( buf, "%d", vals[i] );
2316 test_reg_key( SPI_SETMOUSEHOVERTIME_REGKEY,
2317 SPI_SETMOUSEHOVERTIME_VALNAME, buf );
2319 SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &v, 0 );
2320 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2321 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERTIME", "%d" );
2324 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, old_time, 0,
2325 SPIF_UPDATEINIFILE );
2326 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2329 static void test_SPI_SETWHEELSCROLLLINES( void ) /* 105 */
2331 BOOL rc;
2332 UINT old_lines;
2333 const UINT vals[]={0,32767};
2334 unsigned int i;
2336 trace("testing SPI_{GET,SET}WHEELSCROLLLINES\n");
2337 SetLastError(0xdeadbeef);
2338 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &old_lines, 0 );
2340 /* SPI_{GET,SET}WHEELSCROLLLINES not supported on Windows 95 */
2341 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLLINES"))
2342 return;
2344 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2346 UINT v;
2347 char buf[10];
2349 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, vals[i], 0,
2350 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2351 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLLINES")) return;
2352 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2353 test_change_message( SPI_SETWHEELSCROLLLINES, 0 );
2354 sprintf( buf, "%d", vals[i] );
2355 test_reg_key( SPI_SETMOUSESCROLLLINES_REGKEY,
2356 SPI_SETMOUSESCROLLLINES_VALNAME, buf );
2358 SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &v, 0 );
2359 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2360 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLLINES", "%d" );
2363 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, old_lines, 0,
2364 SPIF_UPDATEINIFILE );
2365 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2368 static void test_SPI_SETMENUSHOWDELAY( void ) /* 107 */
2370 BOOL rc;
2371 UINT old_delay;
2372 const UINT vals[]={0,32767};
2373 unsigned int i;
2375 trace("testing SPI_{GET,SET}MENUSHOWDELAY\n");
2376 SetLastError(0xdeadbeef);
2377 rc=SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &old_delay, 0 );
2379 /* SPI_{GET,SET}MENUSHOWDELAY not supported on Windows 95 */
2380 if (!test_error_msg(rc,"SPI_{GET,SET}MENUSHOWDELAY"))
2381 return;
2383 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2385 UINT v;
2386 char buf[10];
2388 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, vals[i], 0,
2389 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2390 if (!test_error_msg(rc,"SPI_SETMENUSHOWDELAY")) return;
2391 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2392 test_change_message( SPI_SETMENUSHOWDELAY, 0 );
2393 sprintf( buf, "%d", vals[i] );
2394 test_reg_key( SPI_SETMENUSHOWDELAY_REGKEY,
2395 SPI_SETMENUSHOWDELAY_VALNAME, buf );
2397 SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &v, 0 );
2398 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2399 eq( v, vals[i], "SPI_{GET,SET}MENUSHOWDELAY", "%d" );
2402 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, old_delay, 0,
2403 SPIF_UPDATEINIFILE );
2404 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2407 static void test_SPI_SETWHEELSCROLLCHARS( void ) /* 108 */
2409 BOOL rc;
2410 UINT old_chars;
2411 const UINT vals[]={32767,0};
2412 unsigned int i;
2414 trace("testing SPI_{GET,SET}WHEELSCROLLCHARS\n");
2415 SetLastError(0xdeadbeef);
2416 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &old_chars, 0 );
2418 /* SPI_{GET,SET}WHEELSCROLLCHARS not supported on Windows 95 */
2419 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLCHARS"))
2420 return;
2422 for (i=0;i<sizeof(vals)/sizeof(*vals);i++)
2424 UINT v;
2425 char buf[10];
2427 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, vals[i], 0,
2428 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2429 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLCHARS")) return;
2430 test_change_message( SPI_SETWHEELSCROLLCHARS, 0 );
2431 sprintf( buf, "%d", vals[i] );
2432 test_reg_key( SPI_SETMOUSESCROLLCHARS_REGKEY,
2433 SPI_SETMOUSESCROLLCHARS_VALNAME, buf );
2435 SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &v, 0 );
2436 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2437 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLCHARS", "%d" );
2440 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, old_chars, 0,
2441 SPIF_UPDATEINIFILE );
2442 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2445 static void test_SPI_SETWALLPAPER( void ) /* 115 */
2447 BOOL rc;
2448 char oldval[260];
2449 char newval[260];
2451 trace("testing SPI_{GET,SET}DESKWALLPAPER\n");
2452 SetLastError(0xdeadbeef);
2453 rc=SystemParametersInfoA(SPI_GETDESKWALLPAPER, 260, oldval, 0);
2454 if (!test_error_msg(rc,"SPI_{GET,SET}DESKWALLPAPER"))
2455 return;
2457 strcpy(newval, "");
2458 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, newval, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
2459 if (!test_error_msg(rc,"SPI_SETDESKWALLPAPER")) return;
2460 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
2461 test_change_message(SPI_SETDESKWALLPAPER, 0);
2463 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, oldval, SPIF_UPDATEINIFILE);
2464 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2466 test_reg_key(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, oldval);
2469 static void test_WM_DISPLAYCHANGE(void)
2471 DEVMODEA mode, startmode;
2472 int start_bpp, last_set_bpp = 0;
2473 int test_bpps[] = {8, 16, 24, 32}, i;
2474 LONG change_ret;
2475 DWORD wait_ret;
2477 if (!pChangeDisplaySettingsExA)
2479 win_skip("ChangeDisplaySettingsExA is not available\n");
2480 return;
2483 displaychange_test_active = TRUE;
2485 memset(&startmode, 0, sizeof(startmode));
2486 startmode.dmSize = sizeof(startmode);
2487 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &startmode);
2488 start_bpp = startmode.dmBitsPerPel;
2490 displaychange_sem = CreateSemaphoreW(NULL, 0, 1, NULL);
2492 for(i = 0; i < sizeof(test_bpps)/sizeof(test_bpps[0]); i++) {
2493 last_bpp = -1;
2495 memset(&mode, 0, sizeof(mode));
2496 mode.dmSize = sizeof(mode);
2497 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2498 mode.dmBitsPerPel = test_bpps[i];
2499 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2500 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2502 change_counter = 0; /* This sends a SETTINGSCHANGE message as well in which we aren't interested */
2503 displaychange_ok = TRUE;
2504 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2505 /* Wait quite long for the message, screen setting changes can take some time */
2506 if(change_ret == DISP_CHANGE_SUCCESSFUL) {
2507 wait_ret = WaitForSingleObject(displaychange_sem, 10000);
2508 /* we may not get a notification if nothing changed */
2509 if (wait_ret == WAIT_TIMEOUT && !last_set_bpp && start_bpp == test_bpps[i])
2510 continue;
2511 ok(wait_ret == WAIT_OBJECT_0, "Waiting for the WM_DISPLAYCHANGE message timed out\n");
2513 displaychange_ok = FALSE;
2515 if(change_ret != DISP_CHANGE_SUCCESSFUL) {
2516 skip("Setting depth %d failed(ret = %d)\n", test_bpps[i], change_ret);
2517 ok(last_bpp == -1, "WM_DISPLAYCHANGE was sent with wParam %d despite mode change failure\n", last_bpp);
2518 continue;
2521 todo_wine_if(start_bpp != test_bpps[i]) {
2522 ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
2524 last_set_bpp = test_bpps[i];
2527 if(start_bpp != last_set_bpp && last_set_bpp != 0) {
2528 memset(&mode, 0, sizeof(mode));
2529 mode.dmSize = sizeof(mode);
2530 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2531 mode.dmBitsPerPel = start_bpp;
2532 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2533 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2535 displaychange_ok = TRUE;
2536 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2537 WaitForSingleObject(displaychange_sem, 10000);
2538 displaychange_ok = FALSE;
2539 CloseHandle(displaychange_sem);
2540 displaychange_sem = 0;
2543 displaychange_test_active = FALSE;
2547 * Registry entries for the system parameters.
2548 * Names are created by 'SET' flags names.
2549 * We assume that corresponding 'GET' entries use the same registry keys.
2551 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
2553 test_SPI_SETBEEP(); /* 1 */
2554 test_SPI_SETMOUSE(); /* 4 */
2555 test_SPI_SETBORDER(); /* 6 */
2556 test_SPI_SETKEYBOARDSPEED(); /* 10 */
2557 test_SPI_ICONHORIZONTALSPACING(); /* 13 */
2558 test_SPI_SETSCREENSAVETIMEOUT(); /* 14 */
2559 test_SPI_SETSCREENSAVEACTIVE(); /* 17 */
2560 test_SPI_SETGRIDGRANULARITY(); /* 19 */
2561 test_SPI_SETKEYBOARDDELAY(); /* 23 */
2562 test_SPI_ICONVERTICALSPACING(); /* 24 */
2563 test_SPI_SETICONTITLEWRAP(); /* 26 */
2564 test_SPI_SETMENUDROPALIGNMENT(); /* 28 */
2565 test_SPI_SETDOUBLECLKWIDTH(); /* 29 */
2566 test_SPI_SETDOUBLECLKHEIGHT(); /* 30 */
2567 test_SPI_SETDOUBLECLICKTIME(); /* 32 */
2568 test_SPI_SETMOUSEBUTTONSWAP(); /* 33 */
2569 test_SPI_SETFASTTASKSWITCH(); /* 36 */
2570 test_SPI_SETDRAGFULLWINDOWS(); /* 37 */
2571 /* test_WM_DISPLAYCHANGE seems to be somewhat buggy on
2572 * some versions of Windows (Vista, Win2k8, Win7B) in that
2573 * not all metrics are properly restored. Problems are
2574 * SM_CXMAXTRACK, SM_CYMAXTRACK
2575 * Fortunately setting the Non-Client metrics like in
2576 * test_SPI_SETNONCLIENTMETRICS will correct this. That is why
2577 * we do the DISPLAY change now... */
2578 test_WM_DISPLAYCHANGE();
2579 test_SPI_SETNONCLIENTMETRICS(); /* 42 */
2580 test_SPI_SETMINIMIZEDMETRICS(); /* 44 */
2581 test_SPI_SETICONMETRICS(); /* 46 */
2582 test_SPI_SETWORKAREA(); /* 47 */
2583 test_SPI_SETSHOWSOUNDS(); /* 57 */
2584 test_SPI_SETKEYBOARDPREF(); /* 69 */
2585 test_SPI_SETSCREENREADER(); /* 71 */
2586 test_SPI_SETFONTSMOOTHING(); /* 75 */
2587 test_SPI_SETLOWPOWERACTIVE(); /* 85 */
2588 test_SPI_SETPOWEROFFACTIVE(); /* 86 */
2589 test_SPI_SETSNAPTODEFBUTTON(); /* 95 */
2590 test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */
2591 test_SPI_SETMOUSEHOVERHEIGHT(); /* 101 */
2592 test_SPI_SETMOUSEHOVERTIME(); /* 103 */
2593 test_SPI_SETWHEELSCROLLLINES(); /* 105 */
2594 test_SPI_SETMENUSHOWDELAY(); /* 107 */
2595 test_SPI_SETWHEELSCROLLCHARS(); /* 108 */
2596 test_SPI_SETWALLPAPER(); /* 115 */
2599 SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
2600 return 0;
2603 /* test calculation of GetSystemMetrics values (mostly) from non client metrics,
2604 * icon metrics and minimized metrics.
2607 /* copied from wine's GdiGetCharDimensions, which is not available on most
2608 * windows versions */
2609 static LONG _GdiGetCharDimensions(HDC hdc, LPTEXTMETRICA lptm, LONG *height)
2611 SIZE sz;
2612 static const CHAR alphabet[] = {
2613 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
2614 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
2615 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
2617 if(lptm && !GetTextMetricsA(hdc, lptm)) return 0;
2619 if(!GetTextExtentPointA(hdc, alphabet, 52, &sz)) return 0;
2621 if (height) *height = sz.cy;
2622 return (sz.cx / 26 + 1) / 2;
2625 /* get text metrics and/or "average" char width of the specified logfont
2626 * for the specified dc */
2627 static void get_text_metr_size( HDC hdc, LOGFONTA *plf, TEXTMETRICA * ptm, UINT *psz)
2629 HFONT hfont, hfontsav;
2630 TEXTMETRICA tm;
2631 if( !ptm) ptm = &tm;
2632 hfont = CreateFontIndirectA( plf);
2633 if( !hfont || ( hfontsav = SelectObject( hdc, hfont)) == NULL ) {
2634 ptm->tmHeight = -1;
2635 if( psz) *psz = 10;
2636 if( hfont) DeleteObject( hfont);
2637 return;
2639 GetTextMetricsA( hdc, ptm);
2640 if( psz)
2641 if( !(*psz = _GdiGetCharDimensions( hdc, ptm, NULL)))
2642 *psz = 10;
2643 SelectObject( hdc, hfontsav);
2644 DeleteObject( hfont);
2647 static int gsm_error_ctr;
2649 #define ok_gsm( i, e)\
2651 int exp = (e);\
2652 int act = GetSystemMetrics( (i));\
2653 if( exp != act) gsm_error_ctr++;\
2654 ok( !( exp != act),"GetSystemMetrics(%s): expected %d actual %d\n", #i, exp,act);\
2656 #define ok_gsm_2( i, e1, e2)\
2658 int exp1 = (e1);\
2659 int exp2 = (e2);\
2660 int act = GetSystemMetrics( (i));\
2661 if( exp1 != act && exp2 != act) gsm_error_ctr++;\
2662 ok( !( exp1 != act && exp2 != act), "GetSystemMetrics(%s): expected %d or %d actual %d\n", #i, exp1, exp2, act);\
2664 #define ok_gsm_3( i, e1, e2, e3)\
2666 int exp1 = (e1);\
2667 int exp2 = (e2);\
2668 int exp3 = (e3);\
2669 int act = GetSystemMetrics( (i));\
2670 if( exp1 != act && exp2 != act && exp3 != act) gsm_error_ctr++;\
2671 ok( !( exp1 != act && exp2 != act && exp3 != act),"GetSystemMetrics(%s): expected %d or %d or %d actual %d\n", #i, exp1, exp2, exp3, act);\
2674 static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
2676 return lstrcmpiA(elf->lfFaceName, (const char *)lparam);
2679 static BOOL is_font_enumerated(const char *name)
2681 HDC hdc = CreateCompatibleDC(0);
2682 BOOL ret = FALSE;
2684 if (!EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)name))
2685 ret = TRUE;
2687 DeleteDC(hdc);
2688 return ret;
2691 static int get_cursor_size( int size )
2693 /* only certain sizes are allowed for cursors */
2694 if (size >= 64) return 64;
2695 if (size >= 48) return 48;
2696 return 32;
2699 static void test_GetSystemMetrics( void)
2701 TEXTMETRICA tmMenuFont;
2702 UINT IconSpacing, IconVerticalSpacing;
2703 BOOL rc;
2705 HDC hdc = CreateICA( "Display", 0, 0, 0);
2706 UINT avcwCaption;
2707 INT CaptionWidthfromreg, smicon, broken_val;
2708 MINIMIZEDMETRICS minim;
2709 NONCLIENTMETRICSA ncm;
2710 SIZE screen;
2712 assert(sizeof(ncm) == 344);
2714 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2715 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2716 ok(rc, "SystemParametersInfoA failed\n");
2718 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) - 1;
2719 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2720 ok(!rc, "SystemParametersInfoA should fail\n");
2722 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) + 1;
2723 SetLastError(0xdeadbeef);
2724 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2725 ok(!rc, "SystemParametersInfoA should fail\n");
2727 ncm.cbSize = sizeof(ncm); /* Vista added padding */
2728 SetLastError(0xdeadbeef);
2729 ncm.iPaddedBorderWidth = 0xcccc;
2730 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2731 ok(rc || broken(!rc) /* before Vista */, "SystemParametersInfoA failed\n");
2732 if (rc) ok( ncm.iPaddedBorderWidth == 0, "wrong iPaddedBorderWidth %u\n", ncm.iPaddedBorderWidth );
2734 minim.cbSize = sizeof( minim);
2735 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2736 SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0);
2737 rc = SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2738 if( !rc) {
2739 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
2740 return;
2743 ok(is_font_enumerated(ncm.lfCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfCaptionFont.lfFaceName);
2744 ok(is_font_enumerated(ncm.lfSmCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfSmCaptionFont.lfFaceName);
2745 ok(is_font_enumerated(ncm.lfMenuFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMenuFont.lfFaceName);
2746 ok(is_font_enumerated(ncm.lfStatusFont.lfFaceName), "font %s should be enumerated\n", ncm.lfStatusFont.lfFaceName);
2747 ok(is_font_enumerated(ncm.lfMessageFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMessageFont.lfFaceName);
2749 /* CaptionWidth from the registry may have different value of iCaptionWidth
2750 * from the non client metrics (observed on WinXP) */
2751 CaptionWidthfromreg = metricfromreg(
2752 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
2753 get_text_metr_size( hdc, &ncm.lfMenuFont, &tmMenuFont, NULL);
2754 get_text_metr_size( hdc, &ncm.lfCaptionFont, NULL, &avcwCaption);
2755 /* FIXME: use icon metric */
2756 if( !SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &IconVerticalSpacing, 0))
2757 IconVerticalSpacing = 0;
2758 if( !SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &IconSpacing, 0 ))
2759 IconSpacing = 0;
2760 /* reset error counters */
2761 gsm_error_ctr = 0;
2763 /* the tests: */
2765 /* SM_CXSCREEN, cannot test these two */
2766 /* SM_CYSCREEN */
2767 ok_gsm( SM_CXVSCROLL, ncm.iScrollWidth);
2768 ok_gsm( SM_CYHSCROLL, ncm.iScrollWidth);
2769 ok_gsm( SM_CYCAPTION, ncm.iCaptionHeight+1);
2770 ok_gsm( SM_CXBORDER, 1);
2771 ok_gsm( SM_CYBORDER, 1);
2772 ok_gsm( SM_CXDLGFRAME, 3);
2773 ok_gsm( SM_CYDLGFRAME, 3);
2774 ok_gsm( SM_CYVTHUMB, ncm.iScrollHeight);
2775 ok_gsm( SM_CXHTHUMB, ncm.iScrollHeight);
2776 /* These don't depend on the Shell Icon Size registry value */
2777 ok_gsm( SM_CXICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2778 ok_gsm( SM_CYICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2779 ok_gsm( SM_CXCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2780 ok_gsm( SM_CYCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2781 ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1);
2782 ok_gsm( SM_CXFULLSCREEN,
2783 GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME));
2784 ok_gsm( SM_CYFULLSCREEN,
2785 GetSystemMetrics( SM_CYMAXIMIZED) - GetSystemMetrics( SM_CYMIN));
2786 /* SM_CYKANJIWINDOW */
2787 /* SM_MOUSEPRESENT */
2788 ok_gsm( SM_CYVSCROLL, ncm.iScrollHeight);
2789 ok_gsm( SM_CXHSCROLL, ncm.iScrollHeight);
2790 /* SM_DEBUG */
2791 /* SM_SWAPBUTTON */
2792 /* SM_RESERVED1 */
2793 /* SM_RESERVED2 */
2794 /* SM_RESERVED3 */
2795 /* SM_RESERVED4 */
2796 ok_gsm( SM_CXMIN, 3 * max( CaptionWidthfromreg >= 0 ? CaptionWidthfromreg : ncm.iCaptionWidth, 8) +
2797 GetSystemMetrics( SM_CYSIZE) + 4 + 4 * avcwCaption + 2 * GetSystemMetrics( SM_CXFRAME));
2798 ok_gsm( SM_CYMIN, GetSystemMetrics( SM_CYCAPTION) +
2799 2 * GetSystemMetrics( SM_CYFRAME));
2800 ok_gsm_2( SM_CXSIZE,
2801 ncm.iCaptionWidth, /* classic/standard windows style */
2802 GetSystemMetrics( SM_CYCAPTION) - 1 /* WinXP style */
2804 ok_gsm( SM_CYSIZE, ncm.iCaptionHeight);
2805 ok_gsm( SM_CXFRAME, ncm.iBorderWidth + 3);
2806 ok_gsm( SM_CYFRAME, ncm.iBorderWidth + 3);
2807 ok_gsm( SM_CXMINTRACK, GetSystemMetrics( SM_CXMIN));
2808 ok_gsm( SM_CYMINTRACK, GetSystemMetrics( SM_CYMIN));
2809 /* SM_CXDOUBLECLK */
2810 /* SM_CYDOUBLECLK */
2811 if( IconSpacing) ok_gsm( SM_CXICONSPACING, IconSpacing);
2812 if( IconVerticalSpacing) ok_gsm( SM_CYICONSPACING, IconVerticalSpacing);
2813 /* SM_MENUDROPALIGNMENT */
2814 /* SM_PENWINDOWS */
2815 /* SM_DBCSENABLED */
2816 /* SM_CMOUSEBUTTONS */
2817 /* SM_SECURE */
2818 ok_gsm( SM_CXEDGE, 2);
2819 ok_gsm( SM_CYEDGE, 2);
2820 /* sign-extension for iHorzGap/iVertGap is broken on Win9x */
2821 ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + (short)minim.iHorzGap );
2822 ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + (short)minim.iVertGap );
2824 smicon = MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI );
2825 if (!pIsProcessDPIAware || pIsProcessDPIAware())
2826 smicon = max( min( smicon, CaptionWidthfromreg - 2), 4 ) & ~1;
2827 todo_wine_if( real_dpi == dpi && smicon != (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI) & ~1) )
2829 broken_val = (min( ncm.iCaptionHeight, CaptionWidthfromreg ) - 2) & ~1;
2830 broken_val = min( broken_val, 20 );
2832 if (smicon == 4)
2834 ok_gsm_2( SM_CXSMICON, smicon, 6 );
2835 ok_gsm_2( SM_CYSMICON, smicon, 6 );
2837 else if (smicon < broken_val)
2839 ok_gsm_2( SM_CXSMICON, smicon, broken_val );
2840 ok_gsm_2( SM_CYSMICON, smicon, broken_val );
2842 else
2844 ok_gsm( SM_CXSMICON, smicon );
2845 ok_gsm( SM_CYSMICON, smicon );
2849 ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1);
2850 ok_gsm_3( SM_CXSMSIZE,
2851 ncm.iSmCaptionWidth, /* classic/standard windows style */
2852 GetSystemMetrics( SM_CYSMCAPTION) - 1, /* WinXP style */
2853 smcxsmsize /* winXP seems to cache this value: setnonclientmetric
2854 does not change it */
2856 ok_gsm( SM_CYSMSIZE, GetSystemMetrics( SM_CYSMCAPTION) - 1);
2857 ok_gsm( SM_CXMENUSIZE, ncm.iMenuWidth);
2858 ok_gsm( SM_CYMENUSIZE, ncm.iMenuHeight);
2859 /* SM_ARRANGE */
2860 ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6);
2861 ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5);
2862 screen.cx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
2863 screen.cy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
2864 if (!screen.cx || !screen.cy) /* not supported on NT4 */
2866 screen.cx = GetSystemMetrics( SM_CXSCREEN );
2867 screen.cy = GetSystemMetrics( SM_CYSCREEN );
2869 ok_gsm_3( SM_CXMAXTRACK, screen.cx + 4 + 2 * GetSystemMetrics(SM_CXFRAME),
2870 screen.cx - 4 + 2 * GetSystemMetrics(SM_CXFRAME), /* Vista */
2871 screen.cx + 2 * GetSystemMetrics(SM_CXFRAME)); /* Win8 */
2872 ok_gsm_3( SM_CYMAXTRACK, screen.cy + 4 + 2 * GetSystemMetrics(SM_CYFRAME),
2873 screen.cy - 4 + 2 * GetSystemMetrics(SM_CYFRAME), /* Vista */
2874 screen.cy + 2 * GetSystemMetrics(SM_CYFRAME)); /* Win8 */
2875 /* the next two cannot really be tested as they depend on (application)
2876 * toolbars */
2877 /* SM_CXMAXIMIZED */
2878 /* SM_CYMAXIMIZED */
2879 /* SM_NETWORK */
2880 /* */
2881 /* */
2882 /* */
2883 /* SM_CLEANBOOT */
2884 /* SM_CXDRAG */
2885 /* SM_CYDRAG */
2886 /* SM_SHOWSOUNDS */
2887 ok_gsm( SM_CXMENUCHECK,
2888 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2889 ok_gsm( SM_CYMENUCHECK,
2890 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2891 /* SM_SLOWMACHINE */
2892 /* SM_MIDEASTENABLED */
2893 /* SM_MOUSEWHEELPRESENT */
2894 /* SM_XVIRTUALSCREEN */
2895 /* SM_YVIRTUALSCREEN */
2896 /* SM_CXVIRTUALSCREEN */
2897 /* SM_CYVIRTUALSCREEN */
2898 /* SM_CMONITORS */
2899 /* SM_SAMEDISPLAYFORMAT */
2900 /* SM_IMMENABLED */
2901 /* SM_CXFOCUSBORDER */
2902 /* SM_CYFOCUSBORDER */
2903 /* SM_TABLETPC */
2904 /* SM_MEDIACENTER */
2905 /* SM_CMETRICS */
2906 /* end of tests */
2907 if( gsm_error_ctr ) { /* if any errors where found */
2908 trace( "BorderWidth %d CaptionWidth %d CaptionHeight %d IconSpacing %d IconVerticalSpacing %d\n",
2909 ncm.iBorderWidth, ncm.iCaptionWidth, ncm.iCaptionHeight, IconSpacing, IconVerticalSpacing);
2910 trace( "MenuHeight %d MenuWidth %d ScrollHeight %d ScrollWidth %d SmCaptionHeight %d SmCaptionWidth %d\n",
2911 ncm.iMenuHeight, ncm.iMenuWidth, ncm.iScrollHeight, ncm.iScrollWidth, ncm.iSmCaptionHeight, ncm.iSmCaptionWidth);
2912 trace( "Captionfontchar width %d MenuFont %d,%d CaptionWidth from registry: %d screen %d,%d\n",
2913 avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidthfromreg, screen.cx, screen.cy);
2916 DeleteDC(hdc);
2919 static void compare_font( const LOGFONTW *lf1, const LOGFONTW *lf2, int dpi, int custom_dpi, int line )
2921 ok_(__FILE__,line)( lf1->lfHeight == MulDiv( lf2->lfHeight, dpi, custom_dpi ),
2922 "wrong lfHeight %d vs %d\n", lf1->lfHeight, lf2->lfHeight );
2923 ok_(__FILE__,line)( abs( lf1->lfWidth - MulDiv( lf2->lfWidth, dpi, custom_dpi )) <= 1,
2924 "wrong lfWidth %d vs %d\n", lf1->lfWidth, lf2->lfWidth );
2925 ok_(__FILE__,line)( !memcmp( &lf1->lfEscapement, &lf2->lfEscapement,
2926 offsetof( LOGFONTW, lfFaceName ) - offsetof( LOGFONTW, lfEscapement )),
2927 "font differs\n" );
2928 ok_(__FILE__,line)( !lstrcmpW( lf1->lfFaceName, lf2->lfFaceName ), "wrong face name %s vs %s\n",
2929 wine_dbgstr_w( lf1->lfFaceName ), wine_dbgstr_w( lf2->lfFaceName ));
2932 static void test_metrics_for_dpi( int custom_dpi )
2934 int i, val;
2935 NONCLIENTMETRICSW ncm1, ncm2;
2936 ICONMETRICSW im1, im2;
2937 LOGFONTW lf1, lf2;
2938 BOOL ret;
2940 if (!pSystemParametersInfoForDpi)
2942 win_skip( "custom dpi metrics not supported\n" );
2943 return;
2946 ncm1.cbSize = sizeof(ncm1);
2947 ret = SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof(ncm1), &ncm1, FALSE );
2948 ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
2949 ncm2.cbSize = sizeof(ncm2);
2950 ret = pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof(ncm2), &ncm2, FALSE, custom_dpi );
2951 ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
2953 for (i = 0; i < 92; i++)
2955 int ret1 = GetSystemMetrics( i );
2956 int ret2 = pGetSystemMetricsForDpi( i, custom_dpi );
2957 switch (i)
2959 case SM_CXVSCROLL:
2960 case SM_CYHSCROLL:
2961 case SM_CYVTHUMB:
2962 case SM_CXHTHUMB:
2963 case SM_CXICON:
2964 case SM_CYICON:
2965 case SM_CYVSCROLL:
2966 case SM_CXHSCROLL:
2967 case SM_CYSIZE:
2968 case SM_CXICONSPACING:
2969 case SM_CYICONSPACING:
2970 case SM_CXSMSIZE:
2971 case SM_CYSMSIZE:
2972 case SM_CYMENUSIZE:
2973 ok( ret1 == MulDiv( ret2, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2974 break;
2975 case SM_CXSIZE:
2976 ok( ret1 == ncm1.iCaptionWidth && ret2 == ncm2.iCaptionWidth,
2977 "%u: wrong value %u vs %u caption %u vs %u\n",
2978 i, ret1, ret2, ncm1.iCaptionWidth, ncm2.iCaptionWidth );
2979 break;
2980 case SM_CXCURSOR:
2981 case SM_CYCURSOR:
2982 val = MulDiv( 32, custom_dpi, USER_DEFAULT_SCREEN_DPI );
2983 if (val < 48) val = 32;
2984 else if (val < 64) val = 48;
2985 else val = 64;
2986 ok( val == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2987 break;
2988 case SM_CYCAPTION:
2989 case SM_CYSMCAPTION:
2990 case SM_CYMENU:
2991 ok( ret1 - 1 == MulDiv( ret2 - 1, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2992 break;
2993 case SM_CXMENUSIZE:
2994 ok( ret1 / 8 == MulDiv( ret2, dpi, custom_dpi ) / 8, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2995 break;
2996 case SM_CXFRAME:
2997 case SM_CYFRAME:
2998 ok( ret1 == ncm1.iBorderWidth + 3 && ret2 == ncm2.iBorderWidth + 3,
2999 "%u: wrong value %u vs %u borders %u+%u vs %u+%u\n", i, ret1, ret2,
3000 ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
3001 break;
3002 case SM_CXSMICON:
3003 case SM_CYSMICON:
3004 ok( ret1 == (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI ) & ~1) &&
3005 ret2 == (MulDiv( 16, custom_dpi, USER_DEFAULT_SCREEN_DPI ) & ~1),
3006 "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3007 break;
3008 case SM_CXMENUCHECK:
3009 case SM_CYMENUCHECK:
3010 ok( ret1 == ((get_tmheightW( &ncm1.lfMenuFont, 1 ) - 1) | 1) &&
3011 ret2 == ((get_tmheightW( &ncm2.lfMenuFont, 1 ) - 1) | 1),
3012 "%u: wrong value %u vs %u font %u vs %u\n", i, ret1, ret2,
3013 get_tmheightW( &ncm1.lfMenuFont, 1 ), get_tmheightW( &ncm2.lfMenuFont, 1 ));
3014 break;
3015 default:
3016 ok( ret1 == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3017 break;
3020 im1.cbSize = sizeof(im1);
3021 ret = SystemParametersInfoW( SPI_GETICONMETRICS, sizeof(im1), &im1, FALSE );
3022 ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
3023 im2.cbSize = sizeof(im2);
3024 ret = pSystemParametersInfoForDpi( SPI_GETICONMETRICS, sizeof(im2), &im2, FALSE, custom_dpi );
3025 ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
3026 ok( im1.iHorzSpacing == MulDiv( im2.iHorzSpacing, dpi, custom_dpi ), "wrong iHorzSpacing %u vs %u\n",
3027 im1.iHorzSpacing, im2.iHorzSpacing );
3028 ok( im1.iVertSpacing == MulDiv( im2.iVertSpacing, dpi, custom_dpi ), "wrong iVertSpacing %u vs %u\n",
3029 im1.iVertSpacing, im2.iVertSpacing );
3030 ok( im1.iTitleWrap == im2.iTitleWrap, "wrong iTitleWrap %u vs %u\n",
3031 im1.iTitleWrap, im2.iTitleWrap );
3032 compare_font( &im1.lfFont, &im2.lfFont, dpi, custom_dpi, __LINE__ );
3034 ret = SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf1), &lf1, FALSE );
3035 ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
3036 ret = pSystemParametersInfoForDpi( SPI_GETICONTITLELOGFONT, sizeof(lf2), &lf2, FALSE, custom_dpi );
3037 ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
3038 compare_font( &lf1, &lf2, dpi, custom_dpi, __LINE__ );
3040 /* on high-dpi iPaddedBorderWidth is used in addition to iBorderWidth */
3041 ok( ncm1.iBorderWidth + ncm1.iPaddedBorderWidth == MulDiv( ncm2.iBorderWidth + ncm2.iPaddedBorderWidth, dpi, custom_dpi ),
3042 "wrong iBorderWidth %u+%u vs %u+%u\n",
3043 ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
3044 ok( ncm1.iScrollWidth == MulDiv( ncm2.iScrollWidth, dpi, custom_dpi ),
3045 "wrong iScrollWidth %u vs %u\n", ncm1.iScrollWidth, ncm2.iScrollWidth );
3046 ok( ncm1.iScrollHeight == MulDiv( ncm2.iScrollHeight, dpi, custom_dpi ),
3047 "wrong iScrollHeight %u vs %u\n", ncm1.iScrollHeight, ncm2.iScrollHeight );
3048 ok( ((ncm1.iCaptionWidth + 1) & ~1) == ((MulDiv( ncm2.iCaptionWidth, dpi, custom_dpi ) + 1) & ~1),
3049 "wrong iCaptionWidth %u vs %u\n", ncm1.iCaptionWidth, ncm2.iCaptionWidth );
3050 ok( ncm1.iCaptionHeight == MulDiv( ncm2.iCaptionHeight, dpi, custom_dpi ),
3051 "wrong iCaptionHeight %u vs %u\n", ncm1.iCaptionHeight, ncm2.iCaptionHeight );
3052 compare_font( &ncm1.lfCaptionFont, &ncm2.lfCaptionFont, dpi, custom_dpi, __LINE__ );
3053 ok( ncm1.iSmCaptionHeight == MulDiv( ncm2.iSmCaptionHeight, dpi, custom_dpi ),
3054 "wrong iSmCaptionHeight %u vs %u\n", ncm1.iSmCaptionHeight, ncm2.iSmCaptionHeight );
3055 compare_font( &ncm1.lfSmCaptionFont, &ncm2.lfSmCaptionFont, dpi, custom_dpi, __LINE__ );
3056 ok( ncm1.iMenuHeight == MulDiv( ncm2.iMenuHeight, dpi, custom_dpi ),
3057 "wrong iMenuHeight %u vs %u\n", ncm1.iMenuHeight, ncm2.iMenuHeight );
3058 /* iSmCaptionWidth and iMenuWidth apparently need to be multiples of 8 */
3059 ok( ncm1.iSmCaptionWidth / 8 == MulDiv( ncm2.iSmCaptionWidth, dpi, custom_dpi ) / 8,
3060 "wrong iSmCaptionWidth %u vs %u\n", ncm1.iSmCaptionWidth, ncm2.iSmCaptionWidth );
3061 ok( ncm1.iMenuWidth / 8 == MulDiv( ncm2.iMenuWidth, dpi, custom_dpi ) / 8,
3062 "wrong iMenuWidth %u vs %u\n", ncm1.iMenuWidth, ncm2.iMenuWidth );
3063 compare_font( &ncm1.lfMenuFont, &ncm2.lfMenuFont, dpi, custom_dpi, __LINE__ );
3064 compare_font( &ncm1.lfStatusFont, &ncm2.lfStatusFont, dpi, custom_dpi, __LINE__ );
3065 compare_font( &ncm1.lfMessageFont, &ncm2.lfMessageFont, dpi, custom_dpi, __LINE__ );
3067 for (i = 1; i < 120; i++)
3069 if (i == SPI_GETICONTITLELOGFONT || i == SPI_GETNONCLIENTMETRICS || i == SPI_GETICONMETRICS)
3070 continue;
3071 SetLastError( 0xdeadbeef );
3072 ret = pSystemParametersInfoForDpi( i, 0, &val, 0, custom_dpi );
3073 ok( !ret, "%u: SystemParametersInfoForDpi succeeded\n", i );
3074 ok( GetLastError() == ERROR_INVALID_PARAMETER, "%u: wrong error %u\n", i, GetLastError() );
3078 static void test_EnumDisplaySettings(void)
3080 DEVMODEA devmode;
3081 DWORD val;
3082 HDC hdc;
3083 DWORD num;
3085 memset(&devmode, 0, sizeof(devmode));
3086 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3088 hdc = GetDC(0);
3089 val = GetDeviceCaps(hdc, BITSPIXEL);
3090 ok(devmode.dmBitsPerPel == val,
3091 "GetDeviceCaps(BITSPIXEL) returned %d, EnumDisplaySettings returned %d\n",
3092 val, devmode.dmBitsPerPel);
3094 val = GetDeviceCaps(hdc, NUMCOLORS);
3095 if(devmode.dmBitsPerPel <= 8) {
3096 ok(val == 256, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
3097 } else {
3098 ok(val == -1, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
3101 ReleaseDC(0, hdc);
3103 num = 1;
3104 while (1) {
3105 SetLastError (0xdeadbeef);
3106 if (!EnumDisplaySettingsA(NULL, num, &devmode)) {
3107 DWORD le = GetLastError();
3108 ok(le == ERROR_NO_MORE_FILES ||
3109 le == ERROR_MOD_NOT_FOUND /* Win8 */ ||
3110 le == 0xdeadbeef, /* XP, 2003 */
3111 "Expected ERROR_NO_MORE_FILES, ERROR_MOD_NOT_FOUND or 0xdeadbeef, got %d for %d\n", le, num);
3112 break;
3114 num++;
3118 static void test_GetSysColorBrush(void)
3120 HBRUSH hbr;
3122 SetLastError(0xdeadbeef);
3123 hbr = GetSysColorBrush(-1);
3124 ok(hbr == NULL, "Expected NULL brush\n");
3125 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
3126 /* greater than max index */
3127 hbr = GetSysColorBrush(COLOR_MENUBAR);
3128 if (hbr)
3130 SetLastError(0xdeadbeef);
3131 hbr = GetSysColorBrush(COLOR_MENUBAR + 1);
3132 ok(hbr == NULL, "Expected NULL brush\n");
3133 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
3135 else
3136 win_skip("COLOR_MENUBAR unsupported\n");
3139 static void test_dpi_stock_objects( HDC hdc )
3141 DPI_AWARENESS_CONTEXT context;
3142 HGDIOBJ obj[STOCK_LAST + 1], obj2[STOCK_LAST + 1];
3143 LOGFONTW lf, lf2;
3144 UINT i, dpi;
3146 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3147 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3148 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3149 ok( !pIsProcessDPIAware(), "not aware\n" );
3150 for (i = 0; i <= STOCK_LAST; i++) obj[i] = GetStockObject( i );
3152 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3153 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3154 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3155 ok( pIsProcessDPIAware(), "not aware\n" );
3156 for (i = 0; i <= STOCK_LAST; i++) obj2[i] = GetStockObject( i );
3158 for (i = 0; i <= STOCK_LAST; i++)
3160 switch (i)
3162 case OEM_FIXED_FONT:
3163 case SYSTEM_FIXED_FONT:
3164 ok( obj[i] != obj2[i], "%u: same object\n", i );
3165 break;
3166 case SYSTEM_FONT:
3167 case DEFAULT_GUI_FONT:
3168 ok( obj[i] != obj2[i], "%u: same object\n", i );
3169 GetObjectW( obj[i], sizeof(lf), &lf );
3170 GetObjectW( obj2[i], sizeof(lf2), &lf2 );
3171 ok( lf.lfHeight == MulDiv( lf2.lfHeight, USER_DEFAULT_SCREEN_DPI, real_dpi ),
3172 "%u: wrong height %d / %d\n", i, lf.lfHeight, lf2.lfHeight );
3173 break;
3174 default:
3175 ok( obj[i] == obj2[i], "%u: different object\n", i );
3176 break;
3180 pSetThreadDpiAwarenessContext( context );
3183 static void scale_rect_dpi( RECT *rect, UINT src_dpi, UINT target_dpi )
3185 rect->left = MulDiv( rect->left, target_dpi, src_dpi );
3186 rect->top = MulDiv( rect->top, target_dpi, src_dpi );
3187 rect->right = MulDiv( rect->right, target_dpi, src_dpi );
3188 rect->bottom = MulDiv( rect->bottom, target_dpi, src_dpi );
3191 static void test_dpi_mapping(void)
3193 HWND hwnd;
3194 UINT win_dpi;
3195 POINT point;
3196 BOOL ret, todo;
3197 RECT rect, orig, client, expect;
3198 ULONG_PTR i, j;
3199 DPI_AWARENESS_CONTEXT context;
3201 if (!pLogicalToPhysicalPointForPerMonitorDPI)
3203 win_skip( "LogicalToPhysicalPointForPerMonitorDPI not supported\n" );
3204 return;
3206 context = pGetThreadDpiAwarenessContext();
3207 for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
3209 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3210 hwnd = CreateWindowA( "SysParamsTestClass", "test", WS_OVERLAPPEDWINDOW,
3211 193, 177, 295, 303, 0, 0, GetModuleHandleA(0), NULL );
3212 ok( hwnd != 0, "creating window failed err %u\n", GetLastError());
3213 GetWindowRect( hwnd, &orig );
3214 GetClientRect( hwnd, &client );
3215 for (j = DPI_AWARENESS_UNAWARE; j <= DPI_AWARENESS_PER_MONITOR_AWARE; j++)
3217 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3218 GetWindowRect( hwnd, &rect );
3219 expect = orig;
3220 todo = (real_dpi != USER_DEFAULT_SCREEN_DPI);
3221 if (i == DPI_AWARENESS_UNAWARE && j != DPI_AWARENESS_UNAWARE)
3222 scale_rect_dpi( &expect, USER_DEFAULT_SCREEN_DPI, real_dpi );
3223 else if (i != DPI_AWARENESS_UNAWARE && j == DPI_AWARENESS_UNAWARE)
3224 scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3225 else
3226 todo = FALSE;
3227 todo_wine_if (todo)
3228 ok( EqualRect( &expect, &rect ), "%lu/%lu: wrong window rect %s expected %s\n",
3229 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3230 GetClientRect( hwnd, &rect );
3231 expect = client;
3232 MapWindowPoints( hwnd, 0, (POINT *)&expect, 2 );
3233 if (i == DPI_AWARENESS_UNAWARE && j != DPI_AWARENESS_UNAWARE)
3234 scale_rect_dpi( &expect, USER_DEFAULT_SCREEN_DPI, real_dpi );
3235 else if (i != DPI_AWARENESS_UNAWARE && j == DPI_AWARENESS_UNAWARE)
3236 scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3237 MapWindowPoints( 0, hwnd, (POINT *)&expect, 2 );
3238 OffsetRect( &expect, -expect.left, -expect.top );
3239 todo_wine_if (todo)
3240 ok( EqualRect( &expect, &rect ), "%lu/%lu: wrong client rect %s expected %s\n",
3241 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3242 win_dpi = pGetDpiForWindow( hwnd );
3243 if (i == DPI_AWARENESS_UNAWARE)
3244 ok( win_dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", win_dpi );
3245 else if (i == DPI_AWARENESS_SYSTEM_AWARE)
3246 ok( win_dpi == real_dpi, "wrong dpi %u / %u\n", win_dpi, real_dpi );
3247 point.x = 373;
3248 point.y = 377;
3249 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3250 ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3251 ok( point.x == MulDiv( 373, real_dpi, win_dpi ) &&
3252 point.y == MulDiv( 377, real_dpi, win_dpi ),
3253 "%lu/%lu: wrong pos %d,%d dpi %u\n", i, j, point.x, point.y, win_dpi );
3254 point.x = 405;
3255 point.y = 423;
3256 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3257 ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3258 ok( point.x == MulDiv( 405, win_dpi, real_dpi ) &&
3259 point.y == MulDiv( 423, win_dpi, real_dpi ),
3260 "%lu/%lu: wrong pos %d,%d dpi %u\n", i, j, point.x, point.y, win_dpi );
3261 /* point outside the window fails, but note that Windows (wrongly) checks against the
3262 * window rect transformed relative to the thread's awareness */
3263 GetWindowRect( hwnd, &rect );
3264 point.x = rect.left - 1;
3265 point.y = rect.top;
3266 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3267 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3268 point.x++;
3269 point.y--;
3270 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3271 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3272 point.y++;
3273 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3274 ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3275 point.x = rect.right;
3276 point.y = rect.bottom + 1;
3277 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3278 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3279 point.x++;
3280 point.y--;
3281 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3282 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3283 point.x--;
3284 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3285 ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3286 /* get physical window rect */
3287 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3288 GetWindowRect( hwnd, &rect );
3289 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3290 point.x = rect.left - 1;
3291 point.y = rect.top;
3292 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3293 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3294 point.x++;
3295 point.y--;
3296 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3297 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3298 point.y++;
3299 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3300 ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3301 point.x = rect.right;
3302 point.y = rect.bottom + 1;
3303 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3304 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3305 point.x++;
3306 point.y--;
3307 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3308 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3309 point.x--;
3310 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3311 ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3313 DestroyWindow( hwnd );
3315 pSetThreadDpiAwarenessContext( context );
3318 static void test_dpi_aware(void)
3320 BOOL ret;
3322 if (!pIsProcessDPIAware)
3324 win_skip("IsProcessDPIAware not available\n");
3325 return;
3328 if (pSetProcessDpiAwarenessContext)
3330 DPI_AWARENESS awareness;
3331 DPI_AWARENESS_CONTEXT context;
3332 ULONG_PTR i;
3333 UINT dpi;
3334 HDC hdc = GetDC( 0 );
3336 context = pGetThreadDpiAwarenessContext();
3337 todo_wine
3338 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3339 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3340 todo_wine
3341 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3342 todo_wine
3343 ok( !pIsProcessDPIAware(), "already aware\n" );
3344 dpi = pGetDpiForSystem();
3345 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
3346 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3347 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3348 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
3349 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3350 SetLastError( 0xdeadbeef );
3351 ret = pSetProcessDpiAwarenessContext( NULL );
3352 ok( !ret, "got %d\n", ret );
3353 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3354 SetLastError( 0xdeadbeef );
3355 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3356 ok( !ret, "got %d\n", ret );
3357 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3358 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3359 ok( ret, "got %d\n", ret );
3360 ok( pIsProcessDPIAware(), "not aware\n" );
3361 real_dpi = pGetDpiForSystem();
3362 SetLastError( 0xdeadbeef );
3363 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3364 ok( !ret, "got %d\n", ret );
3365 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3366 SetLastError( 0xdeadbeef );
3367 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3368 ok( !ret, "got %d\n", ret );
3369 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3371 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_INVALID );
3372 ok( !ret, "got %d\n", ret );
3373 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3374 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_UNAWARE );
3375 ok( !ret, "got %d\n", ret );
3376 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3377 ret = pGetProcessDpiAwarenessInternal( 0, &awareness );
3378 ok( ret, "got %d\n", ret );
3379 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3380 ret = pGetProcessDpiAwarenessInternal( GetCurrentProcess(), &awareness );
3381 ok( ret, "got %d\n", ret );
3382 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3383 ret = pGetProcessDpiAwarenessInternal( (HANDLE)0xdeadbeef, &awareness );
3384 ok( ret, "got %d\n", ret );
3385 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong value %d\n", awareness );
3387 ret = pIsProcessDPIAware();
3388 ok(ret, "got %d\n", ret);
3389 context = pGetThreadDpiAwarenessContext();
3390 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3391 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3392 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3393 SetLastError( 0xdeadbeef );
3394 context = pSetThreadDpiAwarenessContext( 0 );
3395 ok( !context, "got %p\n", context );
3396 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3397 SetLastError( 0xdeadbeef );
3398 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3399 ok( !context, "got %p\n", context );
3400 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3401 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3402 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3403 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3404 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3405 dpi = pGetDpiForSystem();
3406 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3407 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3408 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3409 ok( !pIsProcessDPIAware(), "still aware\n" );
3410 context = pGetThreadDpiAwarenessContext();
3411 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3412 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3413 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3414 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3415 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3416 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3417 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3418 dpi = pGetDpiForSystem();
3419 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
3420 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3421 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3422 context = pGetThreadDpiAwarenessContext();
3423 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3424 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3425 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3426 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3427 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3428 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3429 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3430 dpi = pGetDpiForSystem();
3431 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
3432 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3433 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3434 ok( pIsProcessDPIAware(), "not aware\n" );
3435 context = pGetThreadDpiAwarenessContext();
3436 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3437 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000010 );
3438 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3439 context = pGetThreadDpiAwarenessContext();
3440 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3441 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000011 );
3442 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3443 context = pGetThreadDpiAwarenessContext();
3444 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3445 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
3446 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3447 context = pSetThreadDpiAwarenessContext( context );
3448 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3449 context = pGetThreadDpiAwarenessContext();
3450 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3451 for (i = 0; i < 0x100; i++)
3453 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i );
3454 switch (i)
3456 case 0x10:
3457 case 0x11:
3458 case 0x12:
3459 ok( awareness == (i & ~0x10), "%lx: wrong value %u\n", i, awareness );
3460 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i ), "%lx: not valid\n", i );
3461 break;
3462 default:
3463 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", i, awareness );
3464 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i ), "%lx: valid\n", i );
3465 break;
3467 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) );
3468 switch (i)
3470 case 0x10:
3471 case 0x11:
3472 case 0x12:
3473 ok( awareness == (i & ~0x10), "%lx: wrong value %u\n", i | 0x80000000, awareness );
3474 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) ),
3475 "%lx: not valid\n", i | 0x80000000 );
3476 break;
3477 default:
3478 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", i | 0x80000000, awareness );
3479 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) ),
3480 "%lx: valid\n", i | 0x80000000 );
3481 break;
3483 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3484 switch (~i)
3486 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE:
3487 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE:
3488 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE:
3489 ok( awareness == i, "%lx: wrong value %u\n", ~i, awareness );
3490 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i ), "%lx: not valid\n", ~i );
3491 break;
3492 default:
3493 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", ~i, awareness );
3494 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i ), "%lx: valid\n", ~i );
3495 break;
3498 if (real_dpi != USER_DEFAULT_SCREEN_DPI) test_dpi_stock_objects( hdc );
3499 ReleaseDC( 0, hdc );
3501 else win_skip( "SetProcessDpiAwarenessContext not supported\n" );
3503 ret = pSetProcessDPIAware();
3504 ok(ret, "got %d\n", ret);
3506 ret = pIsProcessDPIAware();
3507 ok(ret, "got %d\n", ret);
3509 if (pGetDpiForSystem) real_dpi = pGetDpiForSystem();
3510 dpi = real_dpi;
3511 test_GetSystemMetrics();
3512 test_metrics_for_dpi( 96 );
3513 test_metrics_for_dpi( 192 );
3514 test_dpi_mapping();
3517 static void test_window_dpi(void)
3519 DPI_AWARENESS_CONTEXT context, orig;
3520 DPI_AWARENESS awareness;
3521 HWND hwnd;
3523 if (!pGetWindowDpiAwarenessContext)
3525 win_skip( "GetWindowDpiAwarenessContext not supported\n" );
3526 return;
3528 orig = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3529 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3530 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3531 ok( hwnd != 0, "failed to create window\n" );
3532 context = pGetWindowDpiAwarenessContext( hwnd );
3533 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3534 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3535 DestroyWindow( hwnd );
3537 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3538 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3539 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3540 ok( hwnd != 0, "failed to create window\n" );
3541 context = pGetWindowDpiAwarenessContext( hwnd );
3542 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3543 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3544 DestroyWindow( hwnd );
3546 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3547 hwnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3548 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3549 ok( hwnd != 0, "failed to create window\n" );
3550 context = pGetWindowDpiAwarenessContext( hwnd );
3551 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3552 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3553 DestroyWindow( hwnd );
3555 SetLastError( 0xdeadbeef );
3556 context = pGetWindowDpiAwarenessContext( (HWND)0xdeadbeef );
3557 ok( !context, "got %p\n", context );
3558 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
3560 SetLastError( 0xdeadbeef );
3561 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3562 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3563 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3565 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3566 SetLastError( 0xdeadbeef );
3567 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3568 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3569 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3571 pSetThreadDpiAwarenessContext( orig );
3574 START_TEST(sysparams)
3576 int argc;
3577 char** argv;
3578 WNDCLASSA wc;
3579 MSG msg;
3580 HDC hdc;
3581 HANDLE hThread;
3582 DWORD dwThreadId;
3583 HANDLE hInstance, hdll;
3585 hdll = GetModuleHandleA("user32.dll");
3586 pChangeDisplaySettingsExA = (void*)GetProcAddress(hdll, "ChangeDisplaySettingsExA");
3587 pIsProcessDPIAware = (void*)GetProcAddress(hdll, "IsProcessDPIAware");
3588 pSetProcessDPIAware = (void*)GetProcAddress(hdll, "SetProcessDPIAware");
3589 pGetDpiForSystem = (void*)GetProcAddress(hdll, "GetDpiForSystem");
3590 pGetDpiForWindow = (void*)GetProcAddress(hdll, "GetDpiForWindow");
3591 pSetProcessDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessContext");
3592 pGetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "GetProcessDpiAwarenessInternal");
3593 pSetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessInternal");
3594 pGetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetThreadDpiAwarenessContext");
3595 pSetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetThreadDpiAwarenessContext");
3596 pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetWindowDpiAwarenessContext");
3597 pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetAwarenessFromDpiAwarenessContext");
3598 pIsValidDpiAwarenessContext = (void*)GetProcAddress(hdll, "IsValidDpiAwarenessContext");
3599 pGetSystemMetricsForDpi = (void*)GetProcAddress(hdll, "GetSystemMetricsForDpi");
3600 pSystemParametersInfoForDpi = (void*)GetProcAddress(hdll, "SystemParametersInfoForDpi");
3601 pLogicalToPhysicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "LogicalToPhysicalPointForPerMonitorDPI");
3602 pPhysicalToLogicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "PhysicalToLogicalPointForPerMonitorDPI");
3604 hInstance = GetModuleHandleA( NULL );
3605 hdc = GetDC(0);
3606 dpi = GetDeviceCaps( hdc, LOGPIXELSY);
3607 real_dpi = get_real_dpi();
3608 trace("dpi %d real_dpi %d\n", dpi, real_dpi);
3609 ReleaseDC( 0, hdc);
3611 /* This test requires interactivity, if we don't have it, give up */
3612 if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) &&
3613 GetLastError()==ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) return;
3615 argc = winetest_get_mainargs(&argv);
3616 strict=(argc >= 3 && strcmp(argv[2],"strict")==0);
3617 trace("strict=%d\n",strict);
3619 trace("testing GetSystemMetrics with your current desktop settings\n");
3620 test_GetSystemMetrics( );
3621 test_metrics_for_dpi( 192 );
3622 test_EnumDisplaySettings( );
3623 test_GetSysColorBrush( );
3625 change_counter = 0;
3626 change_last_param = 0;
3628 wc.lpszClassName = "SysParamsTestClass";
3629 wc.lpfnWndProc = SysParamsTestWndProc;
3630 wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
3631 wc.hInstance = hInstance;
3632 wc.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
3633 wc.hCursor = LoadCursorA( 0, (LPCSTR)IDC_ARROW );
3634 wc.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
3635 wc.lpszMenuName = 0;
3636 wc.cbClsExtra = 0;
3637 wc.cbWndExtra = 0;
3638 RegisterClassA( &wc );
3640 ghTestWnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3641 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, hInstance, NULL );
3643 hThread = CreateThread( NULL, 0, SysParamsThreadFunc, 0, 0, &dwThreadId );
3644 assert( hThread );
3645 CloseHandle( hThread );
3647 while( GetMessageA( &msg, 0, 0, 0 )) {
3648 TranslateMessage( &msg );
3649 DispatchMessageA( &msg );
3652 test_dpi_aware();
3653 test_window_dpi();