user32/tests: Add tests for desktop size and DPI scaling.
[wine.git] / dlls / user32 / tests / sysparams.c
blob36a9ef890e6f390c21b529374a9c21b4c1df4654
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 BOOL (WINAPI *pGetDpiForMonitorInternal)(HMONITOR,UINT,UINT*,UINT*);
50 static DPI_AWARENESS_CONTEXT (WINAPI *pGetThreadDpiAwarenessContext)(void);
51 static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
52 static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
53 static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
54 static BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
55 static INT (WINAPI *pGetSystemMetricsForDpi)(INT,UINT);
56 static BOOL (WINAPI *pSystemParametersInfoForDpi)(UINT,UINT,void*,UINT,UINT);
57 static BOOL (WINAPI *pLogicalToPhysicalPointForPerMonitorDPI)(HWND,POINT*);
58 static BOOL (WINAPI *pPhysicalToLogicalPointForPerMonitorDPI)(HWND,POINT*);
59 static LONG (WINAPI *pGetAutoRotationState)(PAR_STATE);
61 static BOOL strict;
62 static int dpi, real_dpi;
64 #define eq(received, expected, label, type) \
65 ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
68 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
69 #define SPI_SETBEEP_VALNAME "Beep"
70 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
71 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
72 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
73 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
74 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop\\WindowMetrics"
75 #define SPI_SETBORDER_REGKEY2 "Control Panel\\Desktop"
76 #define SPI_SETBORDER_VALNAME "BorderWidth"
77 #define SPI_METRIC_REGKEY "Control Panel\\Desktop\\WindowMetrics"
78 #define SPI_SCROLLWIDTH_VALNAME "ScrollWidth"
79 #define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight"
80 #define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth"
81 #define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight"
82 #define SPI_CAPTIONFONT_VALNAME "CaptionFont"
83 #define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth"
84 #define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight"
85 #define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont"
86 #define SPI_MENUWIDTH_VALNAME "MenuWidth"
87 #define SPI_MENUHEIGHT_VALNAME "MenuHeight"
88 #define SPI_MENUFONT_VALNAME "MenuFont"
89 #define SPI_STATUSFONT_VALNAME "StatusFont"
90 #define SPI_MESSAGEFONT_VALNAME "MessageFont"
92 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
93 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
94 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
95 #define SPI_ICONHORIZONTALSPACING_REGKEY2 "Control Panel\\Desktop"
96 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
97 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
98 #define SPI_ICONVERTICALSPACING_REGKEY2 "Control Panel\\Desktop"
99 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
100 #define SPI_MINIMIZEDMETRICS_REGKEY "Control Panel\\Desktop\\WindowMetrics"
101 #define SPI_MINWIDTH_VALNAME "MinWidth"
102 #define SPI_MINHORZGAP_VALNAME "MinHorzGap"
103 #define SPI_MINVERTGAP_VALNAME "MinVertGap"
104 #define SPI_MINARRANGE_VALNAME "MinArrange"
105 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
106 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
107 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
108 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
109 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
110 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
111 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
112 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
113 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
114 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
115 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
116 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
117 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
118 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
119 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
120 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
121 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
122 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
123 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
124 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
125 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
126 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
127 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
128 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
129 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
130 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
131 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
132 #define SPI_SETSHOWSOUNDS_VALNAME "On"
133 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Accessibility\\Keyboard Preference"
134 #define SPI_SETKEYBOARDPREF_VALNAME "On"
135 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY "Control Panel\\Accessibility"
136 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY "Keyboard Preference"
137 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Accessibility\\Blind Access"
138 #define SPI_SETSCREENREADER_VALNAME "On"
139 #define SPI_SETSCREENREADER_REGKEY_LEGACY "Control Panel\\Accessibility"
140 #define SPI_SETSCREENREADER_VALNAME_LEGACY "Blind Access"
141 #define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\\Desktop"
142 #define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing"
143 #define SPI_SETFONTSMOOTHINGTYPE_VALNAME "FontSmoothingType"
144 #define SPI_SETFONTSMOOTHINGCONTRAST_VALNAME "FontSmoothingGamma"
145 #define SPI_SETFONTSMOOTHINGORIENTATION_VALNAME "FontSmoothingOrientation"
146 #define SPI_SETLOWPOWERACTIVE_REGKEY "Control Panel\\Desktop"
147 #define SPI_SETLOWPOWERACTIVE_VALNAME "LowPowerActive"
148 #define SPI_SETPOWEROFFACTIVE_REGKEY "Control Panel\\Desktop"
149 #define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive"
150 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
151 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
152 #define SPI_SETSNAPTODEFBUTTON_REGKEY "Control Panel\\Mouse"
153 #define SPI_SETSNAPTODEFBUTTON_VALNAME "SnapToDefaultButton"
154 #define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse"
155 #define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth"
156 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse"
157 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight"
158 #define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse"
159 #define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime"
160 #define SPI_SETMOUSESCROLLCHARS_REGKEY "Control Panel\\Desktop"
161 #define SPI_SETMOUSESCROLLCHARS_VALNAME "WheelScrollChars"
162 #define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop"
163 #define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines"
164 #define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop"
165 #define SPI_SETMENUSHOWDELAY_VALNAME "MenuShowDelay"
166 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
167 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
169 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
170 #define WINE_CURRENT_USER_REGKEY "Wine"
172 static HWND ghTestWnd;
174 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
175 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
176 LPARAM lParam );
177 static int change_counter;
178 static int change_setworkarea_param, change_iconverticalspacing_param;
179 static int change_last_param;
180 static int last_bpp;
181 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
182 static HANDLE displaychange_sem = 0;
184 static BOOL get_reg_dword(HKEY base, const char *key_name, const char *value_name, DWORD *value)
186 HKEY key;
187 DWORD type, data, size = sizeof(data);
188 BOOL ret = FALSE;
190 if (RegOpenKeyA(base, key_name, &key) == ERROR_SUCCESS)
192 if (RegQueryValueExA(key, value_name, NULL, &type, (void *)&data, &size) == ERROR_SUCCESS &&
193 type == REG_DWORD)
195 *value = data;
196 ret = TRUE;
198 RegCloseKey(key);
200 return ret;
203 static DWORD get_real_dpi(void)
205 DWORD dpi;
207 if (pSetThreadDpiAwarenessContext)
209 DPI_AWARENESS_CONTEXT context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
210 dpi = pGetDpiForSystem();
211 pSetThreadDpiAwarenessContext( context );
212 return dpi;
214 if (get_reg_dword(HKEY_CURRENT_USER, "Control Panel\\Desktop", "LogPixels", &dpi))
215 return dpi;
216 if (get_reg_dword(HKEY_CURRENT_CONFIG, "Software\\Fonts", "LogPixels", &dpi))
217 return dpi;
218 return USER_DEFAULT_SCREEN_DPI;
221 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
222 LPARAM lParam )
224 switch (msg) {
226 case WM_DISPLAYCHANGE:
227 ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
228 last_bpp = wParam;
229 displaychange_ok = FALSE;
230 ReleaseSemaphore(displaychange_sem, 1, 0);
231 break;
233 case WM_SETTINGCHANGE:
234 if (change_counter>0) {
235 /* ignore these messages caused by resizing of toolbars */
236 if( wParam == SPI_SETWORKAREA){
237 change_setworkarea_param = 1;
238 break;
239 } else if( wParam == SPI_ICONVERTICALSPACING) {
240 change_iconverticalspacing_param = 1;
241 break;
242 } else if( displaychange_test_active)
243 break;
244 if( !change_last_param){
245 change_last_param = wParam;
246 break;
248 ok(0,"too many changes counter=%d last change=%d\n",
249 change_counter,change_last_param);
250 change_counter++;
251 change_last_param = wParam;
252 break;
254 change_counter++;
255 change_last_param = change_setworkarea_param = change_iconverticalspacing_param =0;
256 if( wParam == SPI_SETWORKAREA)
257 change_setworkarea_param = 1;
258 else if( wParam == SPI_ICONVERTICALSPACING)
259 change_iconverticalspacing_param = 1;
260 else
261 change_last_param = wParam;
262 break;
264 case WM_DESTROY:
265 PostQuitMessage( 0 );
266 break;
268 /* drop through */
269 default:
270 return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
273 return 0;
277 Performs testing for system parameters messages
278 params:
279 - system parameter id
280 - supposed value of the registry key
282 static void test_change_message( int action, int optional )
284 if (change_counter==0 && optional==1)
285 return;
286 ok( 1 == change_counter,
287 "Missed a message: change_counter=%d\n", change_counter );
288 change_counter = 0;
289 ok( action == change_last_param ||
290 ( change_setworkarea_param && action == SPI_SETWORKAREA) ||
291 ( change_iconverticalspacing_param && action == SPI_ICONVERTICALSPACING),
292 "Wrong action got %d expected %d\n", change_last_param, action );
293 change_last_param = 0;
296 static BOOL test_error_msg ( int rc, const char *name )
298 DWORD last_error = GetLastError();
300 if (rc==0)
302 if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
304 skip("%s not supported on this platform\n", name);
306 else if (last_error==ERROR_ACCESS_DENIED)
308 skip("%s does not have privileges to run\n", name);
310 else
312 trace("%s failed for reason: %d. Indicating test failure and skipping remainder of test\n",name,last_error);
313 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
315 return FALSE;
317 else
319 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%d\n",rc,last_error);
320 return TRUE;
325 * Tests the HKEY_CURRENT_USER subkey value.
326 * The value should contain string value.
328 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2,
329 const void *exp_value, DWORD exp_type, BOOL optional )
331 CHAR value[MAX_PATH];
332 DWORD valueLen;
333 DWORD type;
334 HKEY hKey;
335 LONG rc;
336 int found=0;
338 *value='\0';
339 valueLen=sizeof(value);
340 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
341 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
342 RegCloseKey( hKey );
343 if (rc==ERROR_SUCCESS)
345 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
346 switch (exp_type)
348 case REG_DWORD:
349 ok( *(DWORD *)value == *(DWORD *)exp_value,
350 "Wrong value in registry: %s %s %08x/%08x\n",
351 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
352 break;
353 case REG_SZ:
354 ok( !strcmp( exp_value, value ),
355 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
356 subKey1, valName1, value, (const char *)exp_value );
357 break;
359 found++;
361 else if (strict)
363 ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
364 subKey1, valName1);
366 if (valName2)
368 *value='\0';
369 valueLen=sizeof(value);
370 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
371 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
372 RegCloseKey( hKey );
373 if (rc==ERROR_SUCCESS)
375 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
376 switch (exp_type)
378 case REG_DWORD:
379 ok( *(DWORD *)value == *(DWORD *)exp_value,
380 "Wrong value in registry: %s %s %08x/%08x\n",
381 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
382 break;
383 case REG_SZ:
384 ok( !strcmp( exp_value, value ),
385 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
386 subKey1, valName1, value, (const char *)exp_value );
387 break;
389 found++;
391 else if (strict)
393 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
394 subKey1, valName2 );
397 if (subKey2 && !strict)
399 *value='\0';
400 valueLen=sizeof(value);
401 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
402 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
403 RegCloseKey( hKey );
404 if (rc==ERROR_SUCCESS)
406 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
407 switch (exp_type)
409 case REG_DWORD:
410 ok( *(DWORD *)value == *(DWORD *)exp_value,
411 "Wrong value in registry: %s %s %08x/%08x\n",
412 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
413 break;
414 case REG_SZ:
415 ok( !strcmp( exp_value, value ),
416 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
417 subKey1, valName1, value, (const char *)exp_value );
418 break;
420 found++;
422 else if (strict)
424 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
425 subKey2, valName1 );
427 if (valName2)
429 *value='\0';
430 valueLen=sizeof(value);
431 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
432 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
433 RegCloseKey( hKey );
434 if (rc==ERROR_SUCCESS)
436 ok( type == exp_type, "wrong type %u/%u\n", type, exp_type );
437 switch (exp_type)
439 case REG_DWORD:
440 ok( *(DWORD *)value == *(DWORD *)exp_value,
441 "Wrong value in registry: %s %s %08x/%08x\n",
442 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
443 break;
444 case REG_SZ:
445 ok( !strcmp( exp_value, value ),
446 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
447 subKey1, valName1, value, (const char *)exp_value );
448 break;
450 found++;
452 else if (strict)
454 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
455 subKey2, valName2 );
459 ok(found || optional,
460 "Missing registry values: %s or %s in keys: %s or %s\n",
461 valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
464 #define test_reg_key( subKey, valName, testValue ) \
465 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, FALSE )
466 #define test_reg_key_optional( subKey, valName, testValue ) \
467 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, TRUE )
468 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
469 _test_reg_key( subKey1, subKey2, valName, NULL, testValue, REG_SZ, FALSE )
470 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
471 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, FALSE )
472 #define test_reg_key_ex2_optional( subKey1, subKey2, valName1, valName2, testValue ) \
473 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, TRUE )
474 #define test_reg_key_dword( subKey, valName, testValue ) \
475 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_DWORD, FALSE )
477 /* get a metric from the registry. If the value is negative
478 * it is assumed to be in twips and converted to pixels */
479 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
481 HKEY hkey;
482 char buf[64];
483 DWORD ret;
484 DWORD size, type;
485 int value;
487 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
488 size = sizeof(buf);
489 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
490 RegCloseKey( hkey );
491 if( ret != ERROR_SUCCESS) return -1;
492 value = atoi( buf);
493 if( value < 0)
494 value = ( -value * dpi + 720) / 1440;
495 return value;
498 typedef struct
500 INT16 lfHeight;
501 INT16 lfWidth;
502 INT16 lfEscapement;
503 INT16 lfOrientation;
504 INT16 lfWeight;
505 BYTE lfItalic;
506 BYTE lfUnderline;
507 BYTE lfStrikeOut;
508 BYTE lfCharSet;
509 BYTE lfOutPrecision;
510 BYTE lfClipPrecision;
511 BYTE lfQuality;
512 BYTE lfPitchAndFamily;
513 CHAR lfFaceName[LF_FACESIZE];
514 } LOGFONT16, *LPLOGFONT16;
516 /* get logfont from the registry */
517 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
519 HKEY hkey;
520 LOGFONTW lfw;
521 DWORD ret, size, type;
523 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
524 size = sizeof( lfw);
525 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
526 RegCloseKey( hkey );
527 ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
528 if( ret != ERROR_SUCCESS)
529 return FALSE;
530 if( size <= sizeof( LOGFONT16)) {
531 LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
532 plf->lfHeight = plf16->lfHeight;
533 plf->lfWidth = plf16->lfWidth;
534 plf->lfEscapement = plf16->lfEscapement;
535 plf->lfOrientation = plf16->lfOrientation;
536 plf->lfWeight = plf16->lfWeight;
537 plf->lfItalic = plf16->lfItalic;
538 plf->lfUnderline = plf16->lfUnderline;
539 plf->lfStrikeOut = plf16->lfStrikeOut;
540 plf->lfCharSet = plf16->lfCharSet;
541 plf->lfOutPrecision = plf16->lfOutPrecision;
542 plf->lfClipPrecision = plf16->lfClipPrecision;
543 plf->lfQuality = plf16->lfQuality;
544 plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
545 memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
546 } else if( size <= sizeof( LOGFONTA)) {
547 plf = (LOGFONTA*) &lfw;
548 } else {
549 plf->lfHeight = lfw.lfHeight;
550 plf->lfWidth = lfw.lfWidth;
551 plf->lfEscapement = lfw.lfEscapement;
552 plf->lfOrientation = lfw.lfOrientation;
553 plf->lfWeight = lfw.lfWeight;
554 plf->lfItalic = lfw.lfItalic;
555 plf->lfUnderline = lfw.lfUnderline;
556 plf->lfStrikeOut = lfw.lfStrikeOut;
557 plf->lfCharSet = lfw.lfCharSet;
558 plf->lfOutPrecision = lfw.lfOutPrecision;
559 plf->lfClipPrecision = lfw.lfClipPrecision;
560 plf->lfQuality = lfw.lfQuality;
561 plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
562 WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
563 LF_FACESIZE, NULL, NULL);
566 return TRUE;
569 static void test_SPI_SETBEEP( void ) /* 2 */
571 BOOL rc;
572 BOOL old_b;
573 BOOL b;
574 BOOL curr_val;
576 trace("testing SPI_{GET,SET}BEEP\n");
577 SetLastError(0xdeadbeef);
578 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
579 if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
580 return;
582 curr_val = TRUE;
583 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
584 if (!test_error_msg(rc,"SPI_SETBEEP")) return;
585 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
586 test_change_message( SPI_SETBEEP, 0 );
587 test_reg_key( SPI_SETBEEP_REGKEY,
588 SPI_SETBEEP_VALNAME,
589 curr_val ? "Yes" : "No" );
590 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
591 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
592 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
593 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
594 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
596 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
597 eq( b, curr_val, "SystemParametersInfoW", "%d" );
600 /* is a message sent for the second change? */
601 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
602 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
603 test_change_message( SPI_SETBEEP, 0 );
605 curr_val = FALSE;
606 rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
607 if (rc == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
608 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
609 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
610 test_change_message( SPI_SETBEEP, 0 );
611 test_reg_key( SPI_SETBEEP_REGKEY,
612 SPI_SETBEEP_VALNAME,
613 curr_val ? "Yes" : "No" );
614 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
615 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
616 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
617 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
618 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
620 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
621 eq( b, curr_val, "SystemParametersInfoW", "%d" );
623 ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
625 rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
626 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
629 static const char *setmouse_valuenames[3] = {
630 SPI_SETMOUSE_VALNAME1,
631 SPI_SETMOUSE_VALNAME2,
632 SPI_SETMOUSE_VALNAME3
636 * Runs check for one setting of spi_setmouse.
638 static BOOL run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change, int nchange )
640 BOOL rc;
641 INT mi[3];
642 static int aw_turn = 0;
644 char buf[20];
645 int i;
647 aw_turn++;
648 rc = FALSE;
649 SetLastError(0xdeadbeef);
650 if (aw_turn % 2) /* call unicode on odd (non even) calls */
651 rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
652 else
653 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
654 if (!test_error_msg(rc,"SPI_SETMOUSE")) return FALSE;
656 ok(rc, "SystemParametersInfo: rc=%d err=%d\n", rc, GetLastError());
657 test_change_message( SPI_SETMOUSE, 0 );
658 for (i = 0; i < 3; i++)
660 sprintf( buf, "%d", curr_val[i] );
661 test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
664 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
665 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
666 for (i = 0; i < 3; i++)
668 ok(mi[i] == curr_val[i],
669 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
672 rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
673 ok(rc, "SystemParametersInfoW: rc=%d err=%d\n", rc, GetLastError());
674 for (i = 0; i < 3; i++)
676 ok(mi[i] == curr_val[i],
677 "incorrect value for %d: %d != %d\n", i, mi[i], curr_val[i]);
680 if (0)
682 /* FIXME: this always fails for me - AJ */
683 for (i = 0; i < nchange; i++)
685 POINT mv;
686 mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
687 mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
688 GetCursorPos( &mv );
689 ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
690 ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
693 return TRUE;
696 static void test_SPI_SETMOUSE( void ) /* 4 */
698 BOOL rc;
699 INT old_mi[3];
701 /* win nt default values - 6, 10, 1 */
702 INT curr_val[3] = {6, 10, 1};
704 /* requested and projected mouse movements */
705 POINT req_change[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
706 POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
707 POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
708 POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
709 POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
710 POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
711 POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
712 POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
713 POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
715 int nchange = ARRAY_SIZE(req_change);
717 trace("testing SPI_{GET,SET}MOUSE\n");
718 SetLastError(0xdeadbeef);
719 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
720 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
721 return;
723 if (!run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange )) return;
725 /* acceleration change */
726 curr_val[2] = 2;
727 run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
729 /* acceleration change */
730 curr_val[2] = 3;
731 run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
733 /* acceleration change */
734 curr_val[2] = 0;
735 run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
737 /* threshold change */
738 curr_val[2] = 1;
739 curr_val[0] = 7;
740 run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
742 /* threshold change */
743 curr_val[2] = 2;
744 curr_val[0] = 6;
745 curr_val[1] = 6;
746 run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
748 /* threshold change */
749 curr_val[1] = 7;
750 run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
752 /* threshold change */
753 curr_val[1] = 5;
754 run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
756 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
757 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
760 static BOOL test_setborder(UINT curr_val, int usesetborder, int dpi)
762 BOOL rc;
763 UINT border, regval;
764 INT frame;
765 NONCLIENTMETRICSA ncm;
767 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
768 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
769 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
770 if( usesetborder) {
771 rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
772 if (!test_error_msg(rc,"SPI_SETBORDER")) return FALSE;
773 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
774 test_change_message( SPI_SETBORDER, 1 );
775 } else { /* set non client metrics */
776 ncm.iBorderWidth = curr_val;
777 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
778 SPIF_SENDCHANGE);
779 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return FALSE;
780 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
781 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
783 if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
784 regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
785 if( regval != curr_val)
786 regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
787 ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
789 /* minimum border width is 1 */
790 if (curr_val == 0) curr_val = 1;
791 /* should be the same as the non client metrics */
792 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
793 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
794 eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
795 /* and from SPI_GETBORDER */
796 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
797 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
798 eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
799 /* test some SystemMetrics */
800 frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
801 eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
802 eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
803 eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
804 eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
805 return TRUE;
808 static void test_SPI_SETBORDER( void ) /* 6 */
810 BOOL rc;
811 UINT old_border;
812 NONCLIENTMETRICSA ncmsave;
813 INT CaptionWidth,
814 PaddedBorderWidth;
816 ncmsave.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
817 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
818 if( !rc) {
819 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
820 return;
822 /* CaptionWidth from the registry may have different value of iCaptionWidth
823 * from the non client metrics (observed on WinXP).
824 * Fix this so we can safely restore settings with the nonclientmetrics */
825 CaptionWidth = metricfromreg(
826 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
827 ncmsave.iCaptionWidth = CaptionWidth;
829 /* These tests hang when XFree86 4.0 for Windows is running (tested on
830 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
831 * running.
833 if (FindWindowA( NULL, "Cygwin/XFree86" ))
834 return;
836 trace("testing SPI_{GET,SET}BORDER\n");
838 SetLastError(0xdeadbeef);
839 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &old_border, 0 );
840 if (!test_error_msg(rc,"SPI_{GET,SET}BORDER"))
841 return;
842 /* FIXME: include new PaddedBorderWidth parameter */
843 PaddedBorderWidth = ncmsave.iBorderWidth - old_border;
844 if( PaddedBorderWidth){
845 win_skip( "Cannot reliably restore border width yet (PaddedBorderWidth = %d)\n",
846 PaddedBorderWidth);
847 return;
849 /* This will restore sane values if the test hang previous run. */
850 if ( old_border == 7 || old_border == 20 )
851 old_border = 1;
853 /* win2k3 fails if you set the same border twice, or if size is 0 */
854 if (!test_setborder(2, 1, dpi)) return;
855 test_setborder(1, 1, dpi);
856 test_setborder(3, 1, dpi);
857 if (!test_setborder(1, 0, dpi)) return;
858 test_setborder(0, 0, dpi);
859 test_setborder(3, 0, dpi);
861 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncmsave,
862 SPIF_UPDATEINIFILE| SPIF_SENDCHANGE);
863 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
864 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
867 static void test_SPI_SETKEYBOARDSPEED( void ) /* 10 */
869 BOOL rc;
870 UINT old_speed;
871 const UINT vals[]={0,20,31};
872 unsigned int i;
874 trace("testing SPI_{GET,SET}KEYBOARDSPEED\n");
875 SetLastError(0xdeadbeef);
876 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &old_speed, 0 );
877 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDSPEED"))
878 return;
880 for (i=0;i<ARRAY_SIZE(vals);i++)
882 UINT v;
883 char buf[10];
885 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, vals[i], 0,
886 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
887 if (!test_error_msg(rc,"SPI_SETKEYBOARDSPEED")) return;
888 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
889 test_change_message( SPI_SETKEYBOARDSPEED, 0 );
890 sprintf( buf, "%d", vals[i] );
891 test_reg_key( SPI_SETKEYBOARDSPEED_REGKEY, SPI_SETKEYBOARDSPEED_VALNAME, buf );
893 rc=SystemParametersInfoA( SPI_GETKEYBOARDSPEED, 0, &v, 0 );
894 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
895 eq( v, vals[i], "SPI_{GET,SET}KEYBOARDSPEED", "%d" );
898 rc=SystemParametersInfoA( SPI_SETKEYBOARDSPEED, old_speed, 0, SPIF_UPDATEINIFILE );
899 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
902 /* test_SPI_ICONHORIZONTALSPACING helper */
903 static BOOL dotest_spi_iconhorizontalspacing( INT curr_val)
905 BOOL rc;
906 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
907 ICONMETRICSA im;
909 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, curr_val, 0,
910 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
911 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING")) return FALSE;
912 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
913 test_change_message( SPI_ICONHORIZONTALSPACING, 0 );
914 curr_val = max( curr_val, min_val );
915 /* The registry keys depend on the Windows version and the values too
916 * let's test (works on win95,ME,NT4,2k,XP)
918 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY2, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
919 if( regval != curr_val)
920 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
921 ok( curr_val == regval,
922 "wrong value in registry %d, expected %d\n", regval, curr_val);
923 /* compare with what SPI_ICONHORIZONTALSPACING returns */
924 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
925 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
926 eq( spacing, curr_val, "ICONHORIZONTALSPACING", "%d");
927 /* and with a system metrics */
928 eq( GetSystemMetrics( SM_CXICONSPACING ), curr_val, "SM_CXICONSPACING", "%d" );
929 /* and with what SPI_GETICONMETRICS returns */
930 im.cbSize = sizeof(ICONMETRICSA);
931 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
932 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
933 eq( im.iHorzSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
934 return TRUE;
937 static void test_SPI_ICONHORIZONTALSPACING( void ) /* 13 */
939 BOOL rc;
940 INT old_spacing;
942 trace("testing SPI_ICONHORIZONTALSPACING\n");
943 SetLastError(0xdeadbeef);
944 /* default value: 75 */
945 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &old_spacing, 0 );
946 if (!test_error_msg(rc,"SPI_ICONHORIZONTALSPACING"))
947 return;
948 /* do not increase the value as it would upset the user's icon layout */
949 if (!dotest_spi_iconhorizontalspacing( old_spacing - 1)) return;
950 dotest_spi_iconhorizontalspacing( 10); /* minimum is 32 */
951 /* restore */
952 rc=SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, old_spacing, 0, SPIF_UPDATEINIFILE );
953 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
956 static void test_SPI_SETSCREENSAVETIMEOUT( void ) /* 14 */
958 BOOL rc;
959 UINT old_timeout;
960 const UINT vals[]={0,32767};
961 unsigned int i;
963 trace("testing SPI_{GET,SET}SCREENSAVETIMEOUT\n");
964 SetLastError(0xdeadbeef);
965 rc=SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &old_timeout, 0 );
966 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVETIMEOUT"))
967 return;
969 for (i=0;i<ARRAY_SIZE(vals);i++)
971 UINT v;
972 char buf[10];
974 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, vals[i], 0,
975 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
976 if (!test_error_msg(rc,"SPI_SETSCREENSAVETIMEOUT")) return;
977 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
978 test_change_message( SPI_SETSCREENSAVETIMEOUT, 0 );
979 sprintf( buf, "%d", vals[i] );
980 test_reg_key( SPI_SETSCREENSAVETIMEOUT_REGKEY,
981 SPI_SETSCREENSAVETIMEOUT_VALNAME, buf );
983 rc = SystemParametersInfoA( SPI_GETSCREENSAVETIMEOUT, 0, &v, 0 );
984 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
985 eq( v, vals[i], "SPI_{GET,SET}SCREENSAVETIMEOUT", "%d" );
988 rc=SystemParametersInfoA( SPI_SETSCREENSAVETIMEOUT, old_timeout, 0,
989 SPIF_UPDATEINIFILE );
990 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
993 static void test_SPI_SETSCREENSAVEACTIVE( void ) /* 17 */
995 BOOL rc;
996 BOOL old_b;
997 const UINT vals[]={TRUE,FALSE};
998 unsigned int i;
1000 trace("testing SPI_{GET,SET}SCREENSAVEACTIVE\n");
1001 SetLastError(0xdeadbeef);
1002 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &old_b, 0 );
1003 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENSAVEACTIVE"))
1004 return;
1006 for (i=0;i<ARRAY_SIZE(vals);i++)
1008 UINT v;
1010 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, vals[i], 0,
1011 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1012 if (!test_error_msg(rc,"SPI_SETSCREENSAVEACTIVE")) return;
1013 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1014 test_change_message( SPI_SETSCREENSAVEACTIVE, 0 );
1015 test_reg_key( SPI_SETSCREENSAVEACTIVE_REGKEY,
1016 SPI_SETSCREENSAVEACTIVE_VALNAME,
1017 vals[i] ? "1" : "0" );
1019 rc=SystemParametersInfoA( SPI_GETSCREENSAVEACTIVE, 0, &v, 0 );
1020 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1021 ok(v == vals[i] || broken(! v) /* Win 7 */,
1022 "SPI_{GET,SET}SCREENSAVEACTIVE: got %d instead of %d\n", v, vals[i]);
1025 rc=SystemParametersInfoA( SPI_SETSCREENSAVEACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
1026 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1029 static void test_SPI_SETGRIDGRANULARITY( void ) /* 19 */
1031 /* ??? */;
1034 static void test_SPI_SETKEYBOARDDELAY( void ) /* 23 */
1036 BOOL rc;
1037 UINT old_delay;
1038 const UINT vals[]={0,3};
1039 unsigned int i;
1041 trace("testing SPI_{GET,SET}KEYBOARDDELAY\n");
1042 SetLastError(0xdeadbeef);
1043 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &old_delay, 0 );
1044 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDDELAY"))
1045 return;
1047 for (i=0;i<ARRAY_SIZE(vals);i++)
1049 UINT delay;
1050 char buf[10];
1052 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, vals[i], 0,
1053 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1054 if (!test_error_msg(rc,"SPI_SETKEYBOARDDELAY")) return;
1055 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1056 test_change_message( SPI_SETKEYBOARDDELAY, 0 );
1057 sprintf( buf, "%d", vals[i] );
1058 test_reg_key( SPI_SETKEYBOARDDELAY_REGKEY,
1059 SPI_SETKEYBOARDDELAY_VALNAME, buf );
1061 rc=SystemParametersInfoA( SPI_GETKEYBOARDDELAY, 0, &delay, 0 );
1062 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1063 eq( delay, vals[i], "SPI_{GET,SET}KEYBOARDDELAY", "%d" );
1066 rc=SystemParametersInfoA( SPI_SETKEYBOARDDELAY, old_delay, 0, SPIF_UPDATEINIFILE );
1067 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1071 /* test_SPI_ICONVERTICALSPACING helper */
1072 static BOOL dotest_spi_iconverticalspacing( INT curr_val)
1074 BOOL rc;
1075 INT spacing, regval, min_val = MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI );
1076 ICONMETRICSA im;
1078 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, curr_val, 0,
1079 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1080 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING")) return FALSE;
1081 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1082 test_change_message( SPI_ICONVERTICALSPACING, 0 );
1083 curr_val = max( curr_val, min_val );
1084 /* The registry keys depend on the Windows version and the values too
1085 * let's test (works on win95,ME,NT4,2k,XP)
1087 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY2, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1088 if( regval != curr_val)
1089 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1090 ok( curr_val == regval,
1091 "wrong value in registry %d, expected %d\n", regval, curr_val);
1092 /* compare with what SPI_ICONVERTICALSPACING returns */
1093 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1094 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1095 eq( spacing, curr_val, "ICONVERTICALSPACING", "%d" );
1096 /* and with a system metrics */
1097 eq( GetSystemMetrics( SM_CYICONSPACING ), curr_val, "SM_CYICONSPACING", "%d" );
1098 /* and with what SPI_GETICONMETRICS returns */
1099 im.cbSize = sizeof(ICONMETRICSA);
1100 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1101 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1102 eq( im.iVertSpacing, curr_val, "SPI_GETICONMETRICS", "%d" );
1103 return TRUE;
1106 static void test_SPI_ICONVERTICALSPACING( void ) /* 24 */
1108 BOOL rc;
1109 INT old_spacing;
1111 trace("testing SPI_ICONVERTICALSPACING\n");
1112 SetLastError(0xdeadbeef);
1113 /* default value: 75 */
1114 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &old_spacing, 0 );
1115 if (!test_error_msg(rc,"SPI_ICONVERTICALSPACING"))
1116 return;
1117 /* do not increase the value as it would upset the user's icon layout */
1118 if (!dotest_spi_iconverticalspacing( old_spacing - 1)) return;
1119 /* same tests with a value less than the minimum 32 */
1120 dotest_spi_iconverticalspacing( 10);
1121 /* restore */
1122 rc=SystemParametersInfoA( SPI_ICONVERTICALSPACING, old_spacing, 0,
1123 SPIF_UPDATEINIFILE );
1124 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1127 static void test_SPI_SETICONTITLEWRAP( void ) /* 26 */
1129 BOOL rc;
1130 BOOL old_b;
1131 const UINT vals[]={TRUE,FALSE};
1132 unsigned int i;
1133 ICONMETRICSA im;
1135 /* These tests hang when XFree86 4.0 for Windows is running (tested on
1136 * WinNT, SP2, Cygwin/XFree 4.1.0. Skip the test when XFree86 is
1137 * running.
1139 if (FindWindowA( NULL, "Cygwin/XFree86" ))
1140 return;
1142 trace("testing SPI_{GET,SET}ICONTITLEWRAP\n");
1143 SetLastError(0xdeadbeef);
1144 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &old_b, 0 );
1145 if (!test_error_msg(rc,"SPI_{GET,SET}ICONTITLEWRAP"))
1146 return;
1148 for (i=0;i<ARRAY_SIZE(vals);i++)
1150 UINT v;
1151 UINT regval;
1153 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, vals[i], 0,
1154 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1155 if (!test_error_msg(rc,"SPI_SETICONTITLEWRAP")) return;
1156 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1157 test_change_message( SPI_SETICONTITLEWRAP, 1 );
1158 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2,
1159 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1160 if( regval != vals[i])
1161 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1,
1162 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1163 ok( regval == vals[i], "wrong value in registry %d, expected %d\n", regval, vals[i] );
1165 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &v, 0 );
1166 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1167 eq( v, vals[i], "SPI_{GET,SET}ICONTITLEWRAP", "%d" );
1168 /* and test with what SPI_GETICONMETRICS returns */
1169 im.cbSize = sizeof(ICONMETRICSA);
1170 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1171 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1172 eq( im.iTitleWrap, (BOOL)vals[i], "SPI_GETICONMETRICS", "%d" );
1175 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, old_b, 0, SPIF_UPDATEINIFILE );
1176 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1179 static void test_SPI_SETMENUDROPALIGNMENT( void ) /* 28 */
1181 BOOL rc;
1182 BOOL old_b;
1183 const UINT vals[]={TRUE,FALSE};
1184 unsigned int i;
1186 trace("testing SPI_{GET,SET}MENUDROPALIGNMENT\n");
1187 SetLastError(0xdeadbeef);
1188 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &old_b, 0 );
1189 if (!test_error_msg(rc,"SPI_{GET,SET}MENUDROPALIGNMENT"))
1190 return;
1192 for (i=0;i<ARRAY_SIZE(vals);i++)
1194 UINT v;
1196 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, vals[i], 0,
1197 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1198 if (!test_error_msg(rc,"SPI_SETMENUDROPALIGNMENT")) return;
1199 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1200 test_change_message( SPI_SETMENUDROPALIGNMENT, 0 );
1201 test_reg_key_ex( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1202 SPI_SETMENUDROPALIGNMENT_REGKEY2,
1203 SPI_SETMENUDROPALIGNMENT_VALNAME,
1204 vals[i] ? "1" : "0" );
1206 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &v, 0 );
1207 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1208 eq( v, vals[i], "SPI_{GET,SET}MENUDROPALIGNMENT", "%d" );
1209 eq( GetSystemMetrics( SM_MENUDROPALIGNMENT ), (int)vals[i],
1210 "SM_MENUDROPALIGNMENT", "%d" );
1213 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, old_b, 0,
1214 SPIF_UPDATEINIFILE );
1215 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1218 static void test_SPI_SETDOUBLECLKWIDTH( void ) /* 29 */
1220 BOOL rc;
1221 INT old_width;
1222 const UINT vals[]={0,10000};
1223 unsigned int i;
1225 trace("testing SPI_{GET,SET}DOUBLECLKWIDTH\n");
1226 old_width = GetSystemMetrics( SM_CXDOUBLECLK );
1228 for (i=0;i<ARRAY_SIZE(vals);i++)
1230 char buf[10];
1232 SetLastError(0xdeadbeef);
1233 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, vals[i], 0,
1234 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1235 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKWIDTH"))
1236 return;
1238 test_change_message( SPI_SETDOUBLECLKWIDTH, 0 );
1239 sprintf( buf, "%d", vals[i] );
1240 test_reg_key_ex( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1241 SPI_SETDOUBLECLKWIDTH_REGKEY2,
1242 SPI_SETDOUBLECLKWIDTH_VALNAME, buf );
1243 eq( GetSystemMetrics( SM_CXDOUBLECLK ), (int)vals[i],
1244 "SM_CXDOUBLECLK", "%d" );
1247 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, old_width, 0,
1248 SPIF_UPDATEINIFILE );
1249 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1252 static void test_SPI_SETDOUBLECLKHEIGHT( void ) /* 30 */
1254 BOOL rc;
1255 INT old_height;
1256 const UINT vals[]={0,10000};
1257 unsigned int i;
1259 trace("testing SPI_{GET,SET}DOUBLECLKHEIGHT\n");
1260 old_height = GetSystemMetrics( SM_CYDOUBLECLK );
1262 for (i=0;i<ARRAY_SIZE(vals);i++)
1264 char buf[10];
1266 SetLastError(0xdeadbeef);
1267 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, vals[i], 0,
1268 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1269 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKHEIGHT"))
1270 return;
1272 test_change_message( SPI_SETDOUBLECLKHEIGHT, 0 );
1273 sprintf( buf, "%d", vals[i] );
1274 test_reg_key_ex( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1275 SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1276 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf );
1277 eq( GetSystemMetrics( SM_CYDOUBLECLK ), (int)vals[i],
1278 "SM_CYDOUBLECLK", "%d" );
1281 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, old_height, 0,
1282 SPIF_UPDATEINIFILE );
1283 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1286 static void test_SPI_SETDOUBLECLICKTIME( void ) /* 32 */
1288 BOOL rc;
1289 UINT curr_val;
1290 UINT saved_val;
1291 UINT old_time;
1292 char buf[10];
1294 trace("testing SPI_{GET,SET}DOUBLECLICKTIME\n");
1295 old_time = GetDoubleClickTime();
1297 curr_val = 0;
1298 SetLastError(0xdeadbeef);
1299 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1300 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1301 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLICKTIME"))
1302 return;
1304 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1305 sprintf( buf, "%d", curr_val );
1306 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1307 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1308 curr_val = 500; /* used value for 0 */
1309 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1311 curr_val = 1000;
1312 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1313 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1314 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1315 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1316 sprintf( buf, "%d", curr_val );
1317 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1318 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1319 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1321 saved_val = curr_val;
1323 curr_val = 0;
1324 SetDoubleClickTime( curr_val );
1325 sprintf( buf, "%d", saved_val );
1326 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1327 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1328 curr_val = 500; /* used value for 0 */
1329 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1331 curr_val = 1000;
1332 SetDoubleClickTime( curr_val );
1333 sprintf( buf, "%d", saved_val );
1334 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1335 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1336 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1338 rc=SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, old_time, 0, SPIF_UPDATEINIFILE);
1339 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1342 static void test_SPI_SETMOUSEBUTTONSWAP( void ) /* 33 */
1344 BOOL rc;
1345 BOOL old_b;
1346 const UINT vals[]={TRUE,FALSE};
1347 unsigned int i;
1349 trace("testing SPI_{GET,SET}MOUSEBUTTONSWAP\n");
1350 old_b = GetSystemMetrics( SM_SWAPBUTTON );
1352 for (i=0;i<ARRAY_SIZE(vals);i++)
1354 SetLastError(0xdeadbeef);
1355 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[i], 0,
1356 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1357 if (!test_error_msg(rc,"SPI_SETMOUSEBUTTONSWAP")) return;
1359 test_change_message( SPI_SETMOUSEBUTTONSWAP, 0 );
1360 test_reg_key( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1361 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1362 vals[i] ? "1" : "0" );
1363 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i],
1364 "SM_SWAPBUTTON", "%d" );
1365 rc=SwapMouseButton((BOOL)vals[i^1]);
1366 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i^1],
1367 "SwapMouseButton", "%d" );
1368 ok( rc==(BOOL)vals[i], "SwapMouseButton does not return previous state (really %d)\n", rc );
1371 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, old_b, 0,
1372 SPIF_UPDATEINIFILE );
1373 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1376 static void test_SPI_SETFASTTASKSWITCH( void ) /* 36 */
1378 BOOL rc;
1379 BOOL v;
1381 trace("testing SPI_GETFASTTASKSWITCH\n");
1382 SetLastError(0xdeadbeef);
1383 rc=SystemParametersInfoA( SPI_GETFASTTASKSWITCH, 0, &v, 0 );
1384 if (!test_error_msg(rc,"SPI_{GET,SET}FASTTASKSWITCH"))
1385 return;
1387 /* there is not a single Windows platform on which SPI_GETFASTTASKSWITCH
1388 * works. That sure simplifies testing!
1392 static void test_SPI_SETDRAGFULLWINDOWS( void ) /* 37 */
1394 BOOL rc;
1395 BOOL old_b;
1396 const UINT vals[]={TRUE,FALSE};
1397 unsigned int i;
1399 trace("testing SPI_{GET,SET}DRAGFULLWINDOWS\n");
1400 SetLastError(0xdeadbeef);
1401 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &old_b, 0 );
1403 /* SPI_{GET,SET}DRAGFULLWINDOWS is not implemented on Win95 */
1404 if (!test_error_msg(rc,"SPI_{GET,SET}DRAGFULLWINDOWS"))
1405 return;
1407 for (i=0;i<ARRAY_SIZE(vals);i++)
1409 UINT v;
1411 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, vals[i], 0,
1412 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1413 if (!test_error_msg(rc,"SPI_SETDRAGFULLWINDOWS")) return;
1414 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1415 test_change_message( SPI_SETDRAGFULLWINDOWS, 0 );
1416 test_reg_key( SPI_SETDRAGFULLWINDOWS_REGKEY,
1417 SPI_SETDRAGFULLWINDOWS_VALNAME,
1418 vals[i] ? "1" : "0" );
1420 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &v, 0 );
1421 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1422 eq( v, vals[i], "SPI_{GET,SET}DRAGFULLWINDOWS", "%d" );
1425 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, old_b, 0, SPIF_UPDATEINIFILE );
1426 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1429 #define test_reg_metric( KEY, VAL, val) do { \
1430 INT regval;\
1431 regval = metricfromreg( KEY, VAL, dpi);\
1432 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1433 } while(0)
1435 #define test_reg_metric2( KEY1, KEY2, VAL, val) do { \
1436 INT regval;\
1437 regval = metricfromreg( KEY1, VAL, dpi);\
1438 if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\
1439 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1440 } while(0)
1442 #define test_reg_font( KEY, VAL, LF) do { \
1443 LOGFONTA lfreg;\
1444 lffromreg( KEY, VAL, &lfreg);\
1445 ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == MulDiv( lfreg.lfHeight, dpi, real_dpi ) : \
1446 MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\
1447 (LF).lfWidth == lfreg.lfWidth &&\
1448 (LF).lfWeight == lfreg.lfWeight &&\
1449 !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\
1450 , "wrong value \"%s\" in registry %d, %d\n", VAL, (LF).lfHeight, lfreg.lfHeight);\
1451 } while(0)
1453 #define TEST_NONCLIENTMETRICS_REG( ncm) do { \
1454 /*FIXME: test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);*/\
1455 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\
1456 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\
1457 /*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\
1458 test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\
1459 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\
1460 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\
1461 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\
1462 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\
1463 test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\
1464 test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\
1465 test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\
1466 test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\
1467 test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont); } while(0)
1469 /* get text metric height value for the specified logfont */
1470 static int get_tmheight( LOGFONTA *plf, int flag)
1472 TEXTMETRICA tm;
1473 HDC hdc = GetDC(0);
1474 HFONT hfont = CreateFontIndirectA( plf);
1475 hfont = SelectObject( hdc, hfont);
1476 GetTextMetricsA( hdc, &tm);
1477 hfont = SelectObject( hdc, hfont);
1478 ReleaseDC( 0, hdc );
1479 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1482 static int get_tmheightW( LOGFONTW *plf, int flag)
1484 TEXTMETRICW tm;
1485 HDC hdc = GetDC(0);
1486 HFONT hfont = CreateFontIndirectW( plf);
1487 hfont = SelectObject( hdc, hfont);
1488 GetTextMetricsW( hdc, &tm);
1489 hfont = SelectObject( hdc, hfont);
1490 ReleaseDC( 0, hdc );
1491 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1494 static void test_GetSystemMetrics( void);
1495 static UINT smcxsmsize = 999999999;
1497 static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */
1499 BOOL rc;
1500 INT expect;
1501 NONCLIENTMETRICSA Ncmorig;
1502 NONCLIENTMETRICSA Ncmnew;
1503 NONCLIENTMETRICSA Ncmcur;
1504 NONCLIENTMETRICSA Ncmstart;
1506 Ncmorig.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1507 Ncmnew.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1508 Ncmcur.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1509 Ncmstart.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1511 trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n");
1512 change_counter = 0;
1513 SetLastError(0xdeadbeef);
1514 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmorig, FALSE );
1515 if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS"))
1516 return;
1517 Ncmstart = Ncmorig;
1518 smcxsmsize = Ncmstart.iSmCaptionWidth;
1519 /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if
1520 the caption font height is higher than the CaptionHeight field,
1521 the latter is adjusted accordingly. To be able to restore these setting
1522 accurately be restore the raw values. */
1523 Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, real_dpi);
1524 Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi);
1525 Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi);
1526 Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi);
1527 /* test registry entries */
1528 TEST_NONCLIENTMETRICS_REG( Ncmorig);
1530 /* make small changes */
1531 Ncmnew = Ncmstart;
1532 Ncmnew.iBorderWidth += 1;
1533 Ncmnew.iScrollWidth += 1;
1534 Ncmnew.iScrollHeight -= 1;
1535 Ncmnew.iCaptionWidth -= 2;
1536 Ncmnew.iCaptionHeight += 2;
1537 Ncmnew.lfCaptionFont.lfHeight +=1;
1538 Ncmnew.lfCaptionFont.lfWidth +=2;
1539 Ncmnew.lfCaptionFont.lfWeight +=1;
1540 Ncmnew.iSmCaptionWidth += 1;
1541 Ncmnew.iSmCaptionHeight += 2;
1542 Ncmnew.lfSmCaptionFont.lfHeight +=3;
1543 Ncmnew.lfSmCaptionFont.lfWidth -=1;
1544 Ncmnew.lfSmCaptionFont.lfWeight +=3;
1545 Ncmnew.iMenuWidth += 1;
1546 Ncmnew.iMenuHeight += 2;
1547 Ncmnew.lfMenuFont.lfHeight +=1;
1548 Ncmnew.lfMenuFont.lfWidth +=1;
1549 Ncmnew.lfMenuFont.lfWeight +=2;
1550 Ncmnew.lfStatusFont.lfHeight -=1;
1551 Ncmnew.lfStatusFont.lfWidth -=1;
1552 Ncmnew.lfStatusFont.lfWeight +=3;
1553 Ncmnew.lfMessageFont.lfHeight -=2;
1554 Ncmnew.lfMessageFont.lfWidth -=1;
1555 Ncmnew.lfMessageFont.lfWeight +=4;
1557 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1558 SPIF_SENDCHANGE);
1559 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return;
1560 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1561 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1562 /* get them back */
1563 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1564 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1565 /* test registry entries */
1566 TEST_NONCLIENTMETRICS_REG( Ncmcur );
1567 /* test the system metrics with these settings */
1568 test_GetSystemMetrics();
1569 /* now for something invalid: increase the {menu|caption|smcaption} fonts
1570 by a large amount will increase the {menu|caption|smcaption} height*/
1571 Ncmnew = Ncmstart;
1572 Ncmnew.lfMenuFont.lfHeight -= 8;
1573 Ncmnew.lfCaptionFont.lfHeight =-4;
1574 Ncmnew.lfSmCaptionFont.lfHeight -=10;
1575 /* also show that a few values are lo limited */
1576 Ncmnew.iCaptionWidth = 0;
1577 Ncmnew.iCaptionHeight = 0;
1578 Ncmnew.iScrollHeight = 0;
1579 Ncmnew.iScrollWidth = 0;
1581 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1582 SPIF_SENDCHANGE);
1583 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1584 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1585 /* raw values are in registry */
1586 TEST_NONCLIENTMETRICS_REG( Ncmnew );
1587 /* get them back */
1588 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1589 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1590 /* cooked values are returned */
1591 expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1));
1592 ok( Ncmcur.iMenuHeight == expect,
1593 "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect);
1594 expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0));
1595 ok( Ncmcur.iCaptionHeight == expect,
1596 "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect);
1597 expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0));
1598 ok( Ncmcur.iSmCaptionHeight == expect,
1599 "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect);
1601 /* iCaptionWidth depends on a version, could be 8, 12 (Vista, Win7), 13 */
1602 ok( (Ncmcur.iCaptionWidth >= 8 && Ncmcur.iCaptionWidth <= 13) ||
1603 Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */
1604 "CaptionWidth: %d expected from [8, 13] or %d\n", Ncmcur.iCaptionWidth, Ncmstart.iCaptionWidth);
1605 ok( Ncmcur.iScrollWidth == 8,
1606 "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth);
1607 ok( Ncmcur.iScrollHeight == 8,
1608 "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight);
1609 /* test the system metrics with these settings */
1610 test_GetSystemMetrics();
1611 /* restore */
1612 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA),
1613 &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1614 test_change_message( SPI_SETNONCLIENTMETRICS, 0 );
1615 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1616 /* test the system metrics with these settings */
1617 test_GetSystemMetrics();
1620 static void test_SPI_SETMINIMIZEDMETRICS( void ) /* 44 */
1622 BOOL rc;
1623 INT regval;
1624 MINIMIZEDMETRICS lpMm_orig;
1625 MINIMIZEDMETRICS lpMm_new;
1626 MINIMIZEDMETRICS lpMm_cur;
1628 lpMm_orig.cbSize = sizeof(MINIMIZEDMETRICS);
1629 lpMm_new.cbSize = sizeof(MINIMIZEDMETRICS);
1630 lpMm_cur.cbSize = sizeof(MINIMIZEDMETRICS);
1632 trace("testing SPI_{GET,SET}MINIMIZEDMETRICS\n");
1633 SetLastError(0xdeadbeef);
1634 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_orig, FALSE );
1635 if (!test_error_msg(rc,"SPI_{GET,SET}MINIMIZEDMETRICS"))
1636 return;
1637 /* Test registry. Note that it is perfectly valid for some fields to
1638 * not be set.
1640 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1641 ok( regval == -1 || regval == lpMm_orig.iWidth, "wrong value in registry %d, expected %d\n",
1642 regval, lpMm_orig.iWidth);
1643 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1644 ok( regval == -1 || regval == lpMm_orig.iHorzGap, "wrong value in registry %d, expected %d\n",
1645 regval, lpMm_orig.iHorzGap);
1646 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1647 ok( regval == -1 || regval == lpMm_orig.iVertGap, "wrong value in registry %d, expected %d\n",
1648 regval, lpMm_orig.iVertGap);
1649 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1650 ok( regval == -1 || regval == lpMm_orig.iArrange, "wrong value in registry %d, expected %d\n",
1651 regval, lpMm_orig.iArrange);
1652 /* set some new values */
1653 lpMm_cur.iWidth = 180;
1654 lpMm_cur.iHorzGap = 1;
1655 lpMm_cur.iVertGap = 1;
1656 lpMm_cur.iArrange = 5;
1657 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1658 &lpMm_cur, SPIF_UPDATEINIFILE );
1659 if (!test_error_msg(rc,"SPI_SETMINIMIZEDMETRICS")) return;
1660 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1661 /* read them back */
1662 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1663 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1664 /* and compare */
1665 eq( lpMm_new.iWidth, lpMm_cur.iWidth, "iWidth", "%d" );
1666 eq( lpMm_new.iHorzGap, lpMm_cur.iHorzGap, "iHorzGap", "%d" );
1667 eq( lpMm_new.iVertGap, lpMm_cur.iVertGap, "iVertGap", "%d" );
1668 eq( lpMm_new.iArrange, lpMm_cur.iArrange, "iArrange", "%d" );
1669 /* test registry */
1670 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1671 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1672 regval, lpMm_new.iWidth);
1673 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1674 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1675 regval, lpMm_new.iHorzGap);
1676 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1677 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1678 regval, lpMm_new.iVertGap);
1679 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1680 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1681 regval, lpMm_new.iArrange);
1682 /* test some system metrics */
1683 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1684 lpMm_new.iWidth, "iWidth", "%d" );
1685 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1686 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1687 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1688 lpMm_new.iVertGap, "iVertGap", "%d" );
1689 eq( GetSystemMetrics( SM_ARRANGE ),
1690 lpMm_new.iArrange, "iArrange", "%d" );
1691 /* now some really invalid settings */
1692 lpMm_cur.iWidth = -1;
1693 lpMm_cur.iHorzGap = -1;
1694 lpMm_cur.iVertGap = -1;
1695 lpMm_cur.iArrange = - 1;
1696 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1697 &lpMm_cur, SPIF_UPDATEINIFILE );
1698 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1699 /* read back */
1700 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1701 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1702 /* the width and H/V gaps have minimum 0, arrange is and'd with 0xf */
1703 eq( lpMm_new.iWidth, 0, "iWidth", "%d" );
1704 eq( lpMm_new.iHorzGap, 0, "iHorzGap", "%d" );
1705 eq( lpMm_new.iVertGap, 0, "iVertGap", "%d" );
1706 eq( lpMm_new.iArrange, 0xf & lpMm_cur.iArrange, "iArrange", "%d" );
1707 /* test registry */
1708 if (0)
1710 /* FIXME: cannot understand the results of this (11, 11, 11, 0) */
1711 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINWIDTH_VALNAME, dpi);
1712 ok( regval == lpMm_new.iWidth, "wrong value in registry %d, expected %d\n",
1713 regval, lpMm_new.iWidth);
1714 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINHORZGAP_VALNAME, dpi);
1715 ok( regval == lpMm_new.iHorzGap, "wrong value in registry %d, expected %d\n",
1716 regval, lpMm_new.iHorzGap);
1717 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINVERTGAP_VALNAME, dpi);
1718 ok( regval == lpMm_new.iVertGap, "wrong value in registry %d, expected %d\n",
1719 regval, lpMm_new.iVertGap);
1720 regval = metricfromreg( SPI_MINIMIZEDMETRICS_REGKEY, SPI_MINARRANGE_VALNAME, dpi);
1721 ok( regval == lpMm_new.iArrange, "wrong value in registry %d, expected %d\n",
1722 regval, lpMm_new.iArrange);
1724 /* test some system metrics */
1725 eq( GetSystemMetrics( SM_CXMINIMIZED ) - 6,
1726 lpMm_new.iWidth, "iWidth", "%d" );
1727 eq( GetSystemMetrics( SM_CXMINSPACING ) - GetSystemMetrics( SM_CXMINIMIZED ),
1728 lpMm_new.iHorzGap, "iHorzGap", "%d" );
1729 eq( GetSystemMetrics( SM_CYMINSPACING ) - GetSystemMetrics( SM_CYMINIMIZED ),
1730 lpMm_new.iVertGap, "iVertGap", "%d" );
1731 eq( GetSystemMetrics( SM_ARRANGE ),
1732 lpMm_new.iArrange, "iArrange", "%d" );
1733 /* restore */
1734 rc=SystemParametersInfoA( SPI_SETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS),
1735 &lpMm_orig, SPIF_UPDATEINIFILE );
1736 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1737 /* check that */
1738 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1739 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1740 eq( lpMm_new.iWidth, lpMm_orig.iWidth, "iWidth", "%d" );
1741 eq( lpMm_new.iHorzGap, lpMm_orig.iHorzGap, "iHorzGap", "%d" );
1742 eq( lpMm_new.iVertGap, lpMm_orig.iVertGap, "iVertGap", "%d" );
1743 eq( lpMm_new.iArrange, lpMm_orig.iArrange, "iArrange", "%d" );
1746 static void test_SPI_SETICONMETRICS( void ) /* 46 */
1748 BOOL rc, wrap;
1749 INT spacing;
1750 ICONMETRICSA im_orig;
1751 ICONMETRICSA im_new;
1752 ICONMETRICSA im_cur;
1753 INT regval;
1755 im_orig.cbSize = sizeof(ICONMETRICSA);
1756 im_new.cbSize = sizeof(ICONMETRICSA);
1757 im_cur.cbSize = sizeof(ICONMETRICSA);
1759 trace("testing SPI_{GET,SET}ICONMETRICS\n");
1760 SetLastError(0xdeadbeef);
1761 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE );
1762 if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS"))
1763 return;
1764 /* check some registry values */
1765 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1766 ok( regval==im_orig.iHorzSpacing,
1767 "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing);
1768 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1769 ok( regval==im_orig.iVertSpacing,
1770 "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing);
1771 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1772 if( regval != im_orig.iTitleWrap)
1773 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1774 ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap);
1776 /* change everything without creating something invalid ( Win9x would ignore
1777 * an invalid font for instance) */
1778 im_cur = im_orig;
1779 im_cur.iHorzSpacing += 10;
1780 im_cur.iVertSpacing += 6;
1781 im_cur.iTitleWrap = !im_cur.iTitleWrap;
1782 im_cur.lfFont.lfHeight += 1;
1783 im_cur.lfFont.lfWidth += 2;
1784 im_cur.lfFont.lfEscapement = 1;
1785 im_cur.lfFont.lfWeight = im_cur.lfFont.lfWeight > 100 ? 1 : 314;
1786 im_cur.lfFont.lfItalic = !im_cur.lfFont.lfItalic;
1787 im_cur.lfFont.lfStrikeOut = !im_cur.lfFont.lfStrikeOut;
1788 im_cur.lfFont.lfUnderline = !im_cur.lfFont.lfUnderline;
1789 im_cur.lfFont.lfCharSet = im_cur.lfFont.lfCharSet ? 0 : 1;
1790 im_cur.lfFont.lfOutPrecision = im_cur.lfFont.lfOutPrecision == OUT_DEFAULT_PRECIS ?
1791 OUT_TT_PRECIS : OUT_DEFAULT_PRECIS;
1792 im_cur.lfFont.lfClipPrecision ^= CLIP_LH_ANGLES;
1793 im_cur.lfFont.lfPitchAndFamily = im_cur.lfFont.lfPitchAndFamily ? 0 : 1;
1794 im_cur.lfFont.lfQuality = im_cur.lfFont.lfQuality == DEFAULT_QUALITY ?
1795 DRAFT_QUALITY : DEFAULT_QUALITY;
1796 if( strcmp( im_cur.lfFont.lfFaceName, "MS Serif"))
1797 strcpy( im_cur.lfFont.lfFaceName, "MS Serif");
1798 else
1799 strcpy( im_cur.lfFont.lfFaceName, "MS Sans Serif");
1801 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, SPIF_UPDATEINIFILE );
1802 if (!test_error_msg(rc,"SPI_SETICONMETRICS")) return;
1803 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1805 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1806 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1807 /* test GET <-> SETICONMETRICS */
1808 eq( im_new.iHorzSpacing, im_cur.iHorzSpacing, "iHorzSpacing", "%d" );
1809 eq( im_new.iVertSpacing, im_cur.iVertSpacing, "iVertSpacing", "%d" );
1810 eq( im_new.iTitleWrap, im_cur.iTitleWrap, "iTitleWrap", "%d" );
1811 eq( im_new.lfFont.lfHeight, im_cur.lfFont.lfHeight, "lfHeight", "%d" );
1812 eq( im_new.lfFont.lfWidth, im_cur.lfFont.lfWidth, "lfWidth", "%d" );
1813 eq( im_new.lfFont.lfEscapement, im_cur.lfFont.lfEscapement, "lfEscapement", "%d" );
1814 eq( im_new.lfFont.lfWeight, im_cur.lfFont.lfWeight, "lfWeight", "%d" );
1815 eq( im_new.lfFont.lfItalic, im_cur.lfFont.lfItalic, "lfItalic", "%d" );
1816 eq( im_new.lfFont.lfStrikeOut, im_cur.lfFont.lfStrikeOut, "lfStrikeOut", "%d" );
1817 eq( im_new.lfFont.lfUnderline, im_cur.lfFont.lfUnderline, "lfUnderline", "%d" );
1818 eq( im_new.lfFont.lfCharSet, im_cur.lfFont.lfCharSet, "lfCharSet", "%d" );
1819 eq( im_new.lfFont.lfOutPrecision, im_cur.lfFont.lfOutPrecision, "lfOutPrecision", "%d" );
1820 eq( im_new.lfFont.lfClipPrecision, im_cur.lfFont.lfClipPrecision, "lfClipPrecision", "%d" );
1821 eq( im_new.lfFont.lfPitchAndFamily, im_cur.lfFont.lfPitchAndFamily, "lfPitchAndFamily", "%d" );
1822 eq( im_new.lfFont.lfQuality, im_cur.lfFont.lfQuality, "lfQuality", "%d" );
1823 ok( !strcmp( im_new.lfFont.lfFaceName, im_cur.lfFont.lfFaceName),
1824 "wrong facename \"%s\", should be \"%s\"\n", im_new.lfFont.lfFaceName,
1825 im_cur.lfFont.lfFaceName);
1826 /* test some system metrics */
1827 eq( GetSystemMetrics( SM_CXICONSPACING ),
1828 im_new.iHorzSpacing, "iHorzSpacing", "%d" );
1829 eq( GetSystemMetrics( SM_CYICONSPACING ),
1830 im_new.iVertSpacing, "iVertSpacing", "%d" );
1831 /* check some registry values */
1832 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1833 ok( regval==im_cur.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iHorzSpacing);
1834 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1835 ok( regval==im_cur.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iVertSpacing);
1836 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1837 if( regval != im_cur.iTitleWrap)
1838 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1839 ok( regval==im_cur.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_cur.iTitleWrap);
1840 /* test some values from other SPI_GETxxx calls */
1841 rc = SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
1842 ok( rc && spacing == im_cur.iHorzSpacing,
1843 "SystemParametersInfoA( SPI_ICONHORIZONTALSPACING...) failed or returns wrong value %d instead of %d\n",
1844 spacing, im_cur.iHorzSpacing);
1845 rc = SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1846 ok( rc && spacing == im_cur.iVertSpacing,
1847 "SystemParametersInfoA( SPI_ICONVERTICALSPACING...) failed or returns wrong value %d instead of %d\n",
1848 spacing, im_cur.iVertSpacing);
1849 rc = SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &wrap, 0 );
1850 ok( rc && wrap == im_cur.iTitleWrap,
1851 "SystemParametersInfoA( SPI_GETICONTITLEWRAP...) failed or returns wrong value %d instead of %d\n",
1852 wrap, im_cur.iTitleWrap);
1853 /* restore old values */
1854 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig,SPIF_UPDATEINIFILE );
1855 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1857 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1858 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1860 eq( im_new.iHorzSpacing, im_orig.iHorzSpacing, "iHorzSpacing", "%d" );
1861 eq( im_new.iVertSpacing, im_orig.iVertSpacing, "iVertSpacing", "%d" );
1862 eq( im_new.iTitleWrap, im_orig.iTitleWrap, "iTitleWrap", "%d" );
1865 static void test_SPI_SETWORKAREA( void ) /* 47 */
1867 BOOL rc;
1868 RECT old_area;
1869 RECT area;
1870 RECT curr_val;
1872 trace("testing SPI_{GET,SET}WORKAREA\n");
1873 SetLastError(0xdeadbeef);
1874 rc=SystemParametersInfoA(SPI_GETWORKAREA, 0, &old_area, 0);
1875 if (!test_error_msg(rc,"SPI_{GET,SET}WORKAREA"))
1876 return;
1878 /* Modify the work area only minimally as this causes the icons that
1879 * fall outside it to be moved around thus requiring the user to
1880 * reposition them manually one by one.
1881 * Changing the work area by just one pixel should make this occurrence
1882 * reasonably unlikely.
1884 SetRect(&curr_val, old_area.left, old_area.top, old_area.right - 1, old_area.bottom - 1);
1885 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &curr_val,
1886 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1887 if (!test_error_msg(rc,"SPI_SETWORKAREA")) return;
1888 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1889 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1890 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1891 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1892 test_change_message( SPI_SETWORKAREA, 0);
1893 eq( area.left, curr_val.left, "left", "%d" );
1894 eq( area.top, curr_val.top, "top", "%d" );
1895 /* size may be rounded */
1896 ok( area.right >= curr_val.right - 16 && area.right < curr_val.right + 16,
1897 "right: got %d instead of %d\n", area.right, curr_val.right );
1898 ok( area.bottom >= curr_val.bottom - 16 && area.bottom < curr_val.bottom + 16,
1899 "bottom: got %d instead of %d\n", area.bottom, curr_val.bottom );
1900 curr_val = area;
1901 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &old_area,
1902 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1903 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1904 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1905 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
1906 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1907 test_change_message( SPI_SETWORKAREA, 0 );
1908 eq( area.left, old_area.left, "left", "%d" );
1909 eq( area.top, old_area.top, "top", "%d" );
1910 /* size may be rounded */
1911 ok( area.right >= old_area.right - 16 && area.right < old_area.right + 16,
1912 "right: got %d instead of %d\n", area.right, old_area.right );
1913 ok( area.bottom >= old_area.bottom - 16 && area.bottom < old_area.bottom + 16,
1914 "bottom: got %d instead of %d\n", area.bottom, old_area.bottom );
1917 static void test_SPI_SETSHOWSOUNDS( void ) /* 57 */
1919 BOOL rc;
1920 BOOL old_b;
1921 const UINT vals[]={TRUE,FALSE};
1922 unsigned int i;
1924 trace("testing SPI_{GET,SET}SHOWSOUNDS\n");
1925 SetLastError(0xdeadbeef);
1926 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &old_b, 0 );
1927 if (!test_error_msg(rc,"SPI_{GET,SET}SHOWSOUNDS"))
1928 return;
1930 for (i=0;i<ARRAY_SIZE(vals);i++)
1932 UINT v;
1934 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0,
1935 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1936 if (!test_error_msg(rc,"SPI_SETSHOWSOUNDS")) return;
1937 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1938 test_change_message( SPI_SETSHOWSOUNDS, 1 );
1939 test_reg_key( SPI_SETSHOWSOUNDS_REGKEY,
1940 SPI_SETSHOWSOUNDS_VALNAME,
1941 vals[i] ? "1" : "0" );
1943 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &v, 0 );
1944 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1945 eq( v, vals[i], "SPI_GETSHOWSOUNDS", "%d" );
1946 eq( GetSystemMetrics( SM_SHOWSOUNDS ), (int)vals[i],
1947 "SM_SHOWSOUNDS", "%d" );
1950 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, old_b, 0, SPIF_UPDATEINIFILE );
1951 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1954 static void test_SPI_SETKEYBOARDPREF( void ) /* 69 */
1956 BOOL rc;
1957 BOOL old_b;
1958 const UINT vals[]={TRUE,FALSE};
1959 unsigned int i;
1961 trace("testing SPI_{GET,SET}KEYBOARDPREF\n");
1962 SetLastError(0xdeadbeef);
1963 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &old_b, 0 );
1964 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDPREF"))
1965 return;
1967 for (i=0;i<ARRAY_SIZE(vals);i++)
1969 BOOL v;
1971 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0,
1972 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1973 if (!test_error_msg(rc,"SPI_SETKEYBOARDPREF")) return;
1974 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1975 test_change_message( SPI_SETKEYBOARDPREF, 1 );
1976 test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY,
1977 SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY,
1978 vals[i] ? "1" : "0" );
1980 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &v, 0 );
1981 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
1982 eq( v, (BOOL)vals[i], "SPI_GETKEYBOARDPREF", "%d" );
1985 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, old_b, 0, SPIF_UPDATEINIFILE );
1986 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
1989 static void test_SPI_SETSCREENREADER( void ) /* 71 */
1991 BOOL rc;
1992 BOOL old_b;
1993 const UINT vals[]={TRUE,FALSE};
1994 unsigned int i;
1996 trace("testing SPI_{GET,SET}SCREENREADER\n");
1997 SetLastError(0xdeadbeef);
1998 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &old_b, 0 );
1999 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENREADER"))
2000 return;
2002 for (i=0;i<ARRAY_SIZE(vals);i++)
2004 BOOL v;
2006 rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0,
2007 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2008 if (!test_error_msg(rc,"SPI_SETSCREENREADER")) return;
2009 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2010 test_change_message( SPI_SETSCREENREADER, 1 );
2011 test_reg_key_ex2_optional( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY,
2012 SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY,
2013 vals[i] ? "1" : "0" );
2015 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &v, 0 );
2016 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2017 eq( v, (BOOL)vals[i], "SPI_GETSCREENREADER", "%d" );
2020 rc=SystemParametersInfoA( SPI_SETSCREENREADER, old_b, 0, SPIF_UPDATEINIFILE );
2021 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2024 static void test_SPI_SETFONTSMOOTHING( void ) /* 75 */
2026 BOOL rc;
2027 BOOL old_b;
2028 DWORD old_type, old_contrast, old_orient;
2029 const UINT vals[]={0xffffffff,0,1,2};
2030 unsigned int i;
2032 trace("testing SPI_{GET,SET}FONTSMOOTHING\n");
2033 SetLastError(0xdeadbeef);
2034 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &old_b, 0 );
2035 if (!test_error_msg(rc,"SPI_{GET,SET}FONTSMOOTHING"))
2036 return;
2037 SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &old_type, 0 );
2038 SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &old_contrast, 0 );
2039 SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &old_orient, 0 );
2041 for (i=0;i<ARRAY_SIZE(vals);i++)
2043 UINT v;
2045 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, vals[i], 0,
2046 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2047 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHING")) return;
2048 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2049 test_change_message( SPI_SETFONTSMOOTHING, 0 );
2050 test_reg_key( SPI_SETFONTSMOOTHING_REGKEY,
2051 SPI_SETFONTSMOOTHING_VALNAME,
2052 vals[i] ? "2" : "0" );
2054 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, 0, UlongToPtr(vals[i]),
2055 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2056 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGTYPE")) return;
2057 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2058 test_change_message( SPI_SETFONTSMOOTHINGTYPE, 0 );
2059 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2060 SPI_SETFONTSMOOTHINGTYPE_VALNAME, &vals[i] );
2062 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, 0, UlongToPtr(vals[i]),
2063 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2064 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGCONTRAST")) return;
2065 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2066 test_change_message( SPI_SETFONTSMOOTHINGCONTRAST, 0 );
2067 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2068 SPI_SETFONTSMOOTHINGCONTRAST_VALNAME, &vals[i] );
2070 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, 0, UlongToPtr(vals[i]),
2071 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2072 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGORIENTATION")) return;
2073 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2074 test_change_message( SPI_SETFONTSMOOTHINGORIENTATION, 0 );
2075 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2076 SPI_SETFONTSMOOTHINGORIENTATION_VALNAME, &vals[i] );
2078 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &v, 0 );
2079 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2080 eq( v, vals[i] ? 1 : 0, "SPI_GETFONTSMOOTHING", "%d" );
2082 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &v, 0 );
2083 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2084 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2086 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &v, 0 );
2087 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2088 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2090 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &v, 0 );
2091 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2092 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2095 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, old_b, 0, SPIF_UPDATEINIFILE );
2096 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2097 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, old_type, 0, SPIF_UPDATEINIFILE );
2098 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2099 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, old_contrast, 0, SPIF_UPDATEINIFILE );
2100 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2101 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, old_orient, 0, SPIF_UPDATEINIFILE );
2102 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2105 static void test_SPI_SETLOWPOWERACTIVE( void ) /* 85 */
2107 BOOL rc;
2108 BOOL old_b;
2109 const UINT vals[]={TRUE,FALSE};
2110 unsigned int i;
2112 trace("testing SPI_{GET,SET}LOWPOWERACTIVE\n");
2113 SetLastError(0xdeadbeef);
2114 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &old_b, 0 );
2115 if (!test_error_msg(rc,"SPI_{GET,SET}LOWPOWERACTIVE"))
2116 return;
2118 for (i=0;i<ARRAY_SIZE(vals);i++)
2120 UINT v;
2122 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0,
2123 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2124 if (!test_error_msg(rc,"SPI_SETLOWPOWERACTIVE")) return;
2125 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2126 test_change_message( SPI_SETLOWPOWERACTIVE, 1 );
2127 test_reg_key_optional( SPI_SETLOWPOWERACTIVE_REGKEY,
2128 SPI_SETLOWPOWERACTIVE_VALNAME,
2129 vals[i] ? "1" : "0" );
2131 /* SPI_SETLOWPOWERACTIVE is not persistent in win2k3 and above */
2132 v = 0xdeadbeef;
2133 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 );
2134 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2135 ok(v == vals[i] || v == 0, /* win2k3 */
2136 "SPI_GETLOWPOWERACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2139 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2140 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2143 static void test_SPI_SETPOWEROFFACTIVE( void ) /* 86 */
2145 BOOL rc;
2146 BOOL old_b;
2147 const UINT vals[]={TRUE,FALSE};
2148 unsigned int i;
2150 trace("testing SPI_{GET,SET}POWEROFFACTIVE\n");
2151 SetLastError(0xdeadbeef);
2152 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &old_b, 0 );
2153 if (!test_error_msg(rc,"SPI_{GET,SET}POWEROFFACTIVE"))
2154 return;
2156 for (i=0;i<ARRAY_SIZE(vals);i++)
2158 UINT v;
2160 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0,
2161 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2162 if (!test_error_msg(rc,"SPI_SETPOWEROFFACTIVE")) return;
2163 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2164 test_change_message( SPI_SETPOWEROFFACTIVE, 1 );
2165 test_reg_key_optional( SPI_SETPOWEROFFACTIVE_REGKEY,
2166 SPI_SETPOWEROFFACTIVE_VALNAME,
2167 vals[i] ? "1" : "0" );
2169 /* SPI_SETPOWEROFFACTIVE is not persistent in win2k3 and above */
2170 v = 0xdeadbeef;
2171 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 );
2172 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2173 ok(v == vals[i] || v == 0, /* win2k3 */
2174 "SPI_GETPOWEROFFACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2177 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2178 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2181 static void test_SPI_SETSNAPTODEFBUTTON( void ) /* 95 */
2183 BOOL rc;
2184 BOOL old_b;
2185 const UINT vals[]={TRUE,FALSE};
2186 unsigned int i;
2188 trace("testing SPI_{GET,SET}SNAPTODEFBUTTON\n");
2189 SetLastError(0xdeadbeef);
2190 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &old_b, 0 );
2191 if (!test_error_msg(rc,"SPI_GETSNAPTODEFBUTTON"))
2192 return;
2194 for (i=0;i<ARRAY_SIZE(vals);i++)
2196 UINT v;
2198 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, vals[i], 0,
2199 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2200 if (!test_error_msg(rc,"SPI_SETSNAPTODEFBUTTON")) return;
2201 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2202 test_change_message( SPI_SETSNAPTODEFBUTTON, 0 );
2203 test_reg_key_optional( SPI_SETSNAPTODEFBUTTON_REGKEY,
2204 SPI_SETSNAPTODEFBUTTON_VALNAME,
2205 vals[i] ? "1" : "0" );
2207 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &v, 0 );
2208 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2209 eq( v, vals[i], "SPI_GETSNAPTODEFBUTTON", "%d" );
2212 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, old_b, 0, SPIF_UPDATEINIFILE );
2213 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2216 static void test_SPI_SETMOUSEHOVERWIDTH( void ) /* 99 */
2218 BOOL rc;
2219 UINT old_width;
2220 const UINT vals[]={0,32767};
2221 unsigned int i;
2223 trace("testing SPI_{GET,SET}MOUSEHOVERWIDTH\n");
2224 SetLastError(0xdeadbeef);
2225 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &old_width, 0 );
2226 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERWIDTH"))
2227 return;
2229 for (i=0;i<ARRAY_SIZE(vals);i++)
2231 UINT v;
2232 char buf[10];
2234 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, vals[i], 0,
2235 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2236 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERWIDTH")) return;
2237 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2238 test_change_message( SPI_SETMOUSEHOVERWIDTH, 0 );
2239 sprintf( buf, "%d", vals[i] );
2240 test_reg_key( SPI_SETMOUSEHOVERWIDTH_REGKEY,
2241 SPI_SETMOUSEHOVERWIDTH_VALNAME, buf );
2243 SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &v, 0 );
2244 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2245 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERWIDTH", "%d" );
2248 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, old_width, 0,
2249 SPIF_UPDATEINIFILE );
2250 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2253 static void test_SPI_SETMOUSEHOVERHEIGHT( void ) /* 101 */
2255 BOOL rc;
2256 UINT old_height;
2257 const UINT vals[]={0,32767};
2258 unsigned int i;
2260 trace("testing SPI_{GET,SET}MOUSEHOVERHEIGHT\n");
2261 SetLastError(0xdeadbeef);
2262 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &old_height, 0 );
2263 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERHEIGHT"))
2264 return;
2266 for (i=0;i<ARRAY_SIZE(vals);i++)
2268 UINT v;
2269 char buf[10];
2271 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, vals[i], 0,
2272 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2273 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERHEIGHT")) return;
2274 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2275 test_change_message( SPI_SETMOUSEHOVERHEIGHT, 0 );
2276 sprintf( buf, "%d", vals[i] );
2277 test_reg_key( SPI_SETMOUSEHOVERHEIGHT_REGKEY,
2278 SPI_SETMOUSEHOVERHEIGHT_VALNAME, buf );
2280 SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &v, 0 );
2281 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2282 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERHEIGHT", "%d" );
2285 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, old_height, 0,
2286 SPIF_UPDATEINIFILE );
2287 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2290 static void test_SPI_SETMOUSEHOVERTIME( void ) /* 103 */
2292 BOOL rc;
2293 UINT old_time;
2295 /* Windows XP accepts 10 as the minimum hover time. Any value below will be
2296 * defaulted to a value of 10 automatically.
2298 const UINT vals[]={10,32767};
2299 unsigned int i;
2301 trace("testing SPI_{GET,SET}MOUSEHOVERTIME\n");
2302 SetLastError(0xdeadbeef);
2303 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &old_time, 0 );
2304 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERTIME"))
2305 return;
2307 for (i=0;i<ARRAY_SIZE(vals);i++)
2309 UINT v;
2310 char buf[10];
2312 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, vals[i], 0,
2313 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2314 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERTIME")) return;
2315 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2316 test_change_message( SPI_SETMOUSEHOVERTIME, 0 );
2317 sprintf( buf, "%d", vals[i] );
2318 test_reg_key( SPI_SETMOUSEHOVERTIME_REGKEY,
2319 SPI_SETMOUSEHOVERTIME_VALNAME, buf );
2321 SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &v, 0 );
2322 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2323 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERTIME", "%d" );
2326 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, old_time, 0,
2327 SPIF_UPDATEINIFILE );
2328 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2331 static void test_SPI_SETWHEELSCROLLLINES( void ) /* 105 */
2333 BOOL rc;
2334 UINT old_lines;
2335 const UINT vals[]={0,32767};
2336 unsigned int i;
2338 trace("testing SPI_{GET,SET}WHEELSCROLLLINES\n");
2339 SetLastError(0xdeadbeef);
2340 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &old_lines, 0 );
2342 /* SPI_{GET,SET}WHEELSCROLLLINES not supported on Windows 95 */
2343 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLLINES"))
2344 return;
2346 for (i=0;i<ARRAY_SIZE(vals);i++)
2348 UINT v;
2349 char buf[10];
2351 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, vals[i], 0,
2352 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2353 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLLINES")) return;
2354 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2355 test_change_message( SPI_SETWHEELSCROLLLINES, 0 );
2356 sprintf( buf, "%d", vals[i] );
2357 test_reg_key( SPI_SETMOUSESCROLLLINES_REGKEY,
2358 SPI_SETMOUSESCROLLLINES_VALNAME, buf );
2360 SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &v, 0 );
2361 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2362 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLLINES", "%d" );
2365 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, old_lines, 0,
2366 SPIF_UPDATEINIFILE );
2367 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2370 static void test_SPI_SETMENUSHOWDELAY( void ) /* 107 */
2372 BOOL rc;
2373 UINT old_delay;
2374 const UINT vals[]={0,32767};
2375 unsigned int i;
2377 trace("testing SPI_{GET,SET}MENUSHOWDELAY\n");
2378 SetLastError(0xdeadbeef);
2379 rc=SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &old_delay, 0 );
2381 /* SPI_{GET,SET}MENUSHOWDELAY not supported on Windows 95 */
2382 if (!test_error_msg(rc,"SPI_{GET,SET}MENUSHOWDELAY"))
2383 return;
2385 for (i=0;i<ARRAY_SIZE(vals);i++)
2387 UINT v;
2388 char buf[10];
2390 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, vals[i], 0,
2391 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2392 if (!test_error_msg(rc,"SPI_SETMENUSHOWDELAY")) return;
2393 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2394 test_change_message( SPI_SETMENUSHOWDELAY, 0 );
2395 sprintf( buf, "%d", vals[i] );
2396 test_reg_key( SPI_SETMENUSHOWDELAY_REGKEY,
2397 SPI_SETMENUSHOWDELAY_VALNAME, buf );
2399 SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &v, 0 );
2400 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2401 eq( v, vals[i], "SPI_{GET,SET}MENUSHOWDELAY", "%d" );
2404 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, old_delay, 0,
2405 SPIF_UPDATEINIFILE );
2406 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2409 static void test_SPI_SETWHEELSCROLLCHARS( void ) /* 108 */
2411 BOOL rc;
2412 UINT old_chars;
2413 const UINT vals[]={32767,0};
2414 unsigned int i;
2416 trace("testing SPI_{GET,SET}WHEELSCROLLCHARS\n");
2417 SetLastError(0xdeadbeef);
2418 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &old_chars, 0 );
2420 /* SPI_{GET,SET}WHEELSCROLLCHARS not supported on Windows 95 */
2421 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLCHARS"))
2422 return;
2424 for (i=0;i<ARRAY_SIZE(vals);i++)
2426 UINT v;
2427 char buf[10];
2429 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, vals[i], 0,
2430 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2431 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLCHARS")) return;
2432 test_change_message( SPI_SETWHEELSCROLLCHARS, 0 );
2433 sprintf( buf, "%d", vals[i] );
2434 test_reg_key( SPI_SETMOUSESCROLLCHARS_REGKEY,
2435 SPI_SETMOUSESCROLLCHARS_VALNAME, buf );
2437 SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &v, 0 );
2438 ok(rc, "%d: rc=%d err=%d\n", i, rc, GetLastError());
2439 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLCHARS", "%d" );
2442 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, old_chars, 0,
2443 SPIF_UPDATEINIFILE );
2444 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2447 static void test_SPI_SETWALLPAPER( void ) /* 115 */
2449 BOOL rc;
2450 char oldval[260];
2451 char newval[260];
2453 trace("testing SPI_{GET,SET}DESKWALLPAPER\n");
2454 SetLastError(0xdeadbeef);
2455 rc=SystemParametersInfoA(SPI_GETDESKWALLPAPER, 260, oldval, 0);
2456 if (!test_error_msg(rc,"SPI_{GET,SET}DESKWALLPAPER"))
2457 return;
2459 strcpy(newval, "");
2460 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, newval, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
2461 if (!test_error_msg(rc,"SPI_SETDESKWALLPAPER")) return;
2462 ok(rc, "SystemParametersInfoA: rc=%d err=%d\n", rc, GetLastError());
2463 test_change_message(SPI_SETDESKWALLPAPER, 0);
2465 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, oldval, SPIF_UPDATEINIFILE);
2466 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%d\n", rc, GetLastError());
2468 test_reg_key(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, oldval);
2471 static void test_WM_DISPLAYCHANGE(void)
2473 DEVMODEA mode, startmode;
2474 int start_bpp, last_set_bpp = 0;
2475 int test_bpps[] = {8, 16, 24, 32}, i;
2476 LONG change_ret;
2477 DWORD wait_ret;
2479 if (!pChangeDisplaySettingsExA)
2481 win_skip("ChangeDisplaySettingsExA is not available\n");
2482 return;
2485 displaychange_test_active = TRUE;
2487 memset(&startmode, 0, sizeof(startmode));
2488 startmode.dmSize = sizeof(startmode);
2489 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &startmode);
2490 start_bpp = startmode.dmBitsPerPel;
2492 displaychange_sem = CreateSemaphoreW(NULL, 0, 1, NULL);
2494 for(i = 0; i < ARRAY_SIZE(test_bpps); i++) {
2495 last_bpp = -1;
2497 memset(&mode, 0, sizeof(mode));
2498 mode.dmSize = sizeof(mode);
2499 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2500 mode.dmBitsPerPel = test_bpps[i];
2501 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2502 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2504 change_counter = 0; /* This sends a SETTINGSCHANGE message as well in which we aren't interested */
2505 displaychange_ok = TRUE;
2506 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2507 /* Wait quite long for the message, screen setting changes can take some time */
2508 if(change_ret == DISP_CHANGE_SUCCESSFUL) {
2509 wait_ret = WaitForSingleObject(displaychange_sem, 10000);
2510 /* we may not get a notification if nothing changed */
2511 if (wait_ret == WAIT_TIMEOUT && !last_set_bpp && start_bpp == test_bpps[i])
2512 continue;
2513 ok(wait_ret == WAIT_OBJECT_0, "Waiting for the WM_DISPLAYCHANGE message timed out\n");
2515 displaychange_ok = FALSE;
2517 if(change_ret != DISP_CHANGE_SUCCESSFUL) {
2518 skip("Setting depth %d failed(ret = %d)\n", test_bpps[i], change_ret);
2519 ok(last_bpp == -1, "WM_DISPLAYCHANGE was sent with wParam %d despite mode change failure\n", last_bpp);
2520 continue;
2523 todo_wine_if(start_bpp != test_bpps[i]) {
2524 ok(last_bpp == test_bpps[i], "Set bpp %d, but WM_DISPLAYCHANGE reported bpp %d\n", test_bpps[i], last_bpp);
2526 last_set_bpp = test_bpps[i];
2529 if(start_bpp != last_set_bpp && last_set_bpp != 0) {
2530 memset(&mode, 0, sizeof(mode));
2531 mode.dmSize = sizeof(mode);
2532 mode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
2533 mode.dmBitsPerPel = start_bpp;
2534 mode.dmPelsWidth = GetSystemMetrics(SM_CXSCREEN);
2535 mode.dmPelsHeight = GetSystemMetrics(SM_CYSCREEN);
2537 displaychange_ok = TRUE;
2538 change_ret = pChangeDisplaySettingsExA(NULL, &mode, NULL, 0, NULL);
2539 WaitForSingleObject(displaychange_sem, 10000);
2540 displaychange_ok = FALSE;
2541 CloseHandle(displaychange_sem);
2542 displaychange_sem = 0;
2545 displaychange_test_active = FALSE;
2549 * Registry entries for the system parameters.
2550 * Names are created by 'SET' flags names.
2551 * We assume that corresponding 'GET' entries use the same registry keys.
2553 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
2555 test_SPI_SETBEEP(); /* 1 */
2556 test_SPI_SETMOUSE(); /* 4 */
2557 test_SPI_SETBORDER(); /* 6 */
2558 test_SPI_SETKEYBOARDSPEED(); /* 10 */
2559 test_SPI_ICONHORIZONTALSPACING(); /* 13 */
2560 test_SPI_SETSCREENSAVETIMEOUT(); /* 14 */
2561 test_SPI_SETSCREENSAVEACTIVE(); /* 17 */
2562 test_SPI_SETGRIDGRANULARITY(); /* 19 */
2563 test_SPI_SETKEYBOARDDELAY(); /* 23 */
2564 test_SPI_ICONVERTICALSPACING(); /* 24 */
2565 test_SPI_SETICONTITLEWRAP(); /* 26 */
2566 test_SPI_SETMENUDROPALIGNMENT(); /* 28 */
2567 test_SPI_SETDOUBLECLKWIDTH(); /* 29 */
2568 test_SPI_SETDOUBLECLKHEIGHT(); /* 30 */
2569 test_SPI_SETDOUBLECLICKTIME(); /* 32 */
2570 test_SPI_SETMOUSEBUTTONSWAP(); /* 33 */
2571 test_SPI_SETFASTTASKSWITCH(); /* 36 */
2572 test_SPI_SETDRAGFULLWINDOWS(); /* 37 */
2573 /* test_WM_DISPLAYCHANGE seems to be somewhat buggy on
2574 * some versions of Windows (Vista, Win2k8, Win7B) in that
2575 * not all metrics are properly restored. Problems are
2576 * SM_CXMAXTRACK, SM_CYMAXTRACK
2577 * Fortunately setting the Non-Client metrics like in
2578 * test_SPI_SETNONCLIENTMETRICS will correct this. That is why
2579 * we do the DISPLAY change now... */
2580 test_WM_DISPLAYCHANGE();
2581 test_SPI_SETNONCLIENTMETRICS(); /* 42 */
2582 test_SPI_SETMINIMIZEDMETRICS(); /* 44 */
2583 test_SPI_SETICONMETRICS(); /* 46 */
2584 test_SPI_SETWORKAREA(); /* 47 */
2585 test_SPI_SETSHOWSOUNDS(); /* 57 */
2586 test_SPI_SETKEYBOARDPREF(); /* 69 */
2587 test_SPI_SETSCREENREADER(); /* 71 */
2588 test_SPI_SETFONTSMOOTHING(); /* 75 */
2589 test_SPI_SETLOWPOWERACTIVE(); /* 85 */
2590 test_SPI_SETPOWEROFFACTIVE(); /* 86 */
2591 test_SPI_SETSNAPTODEFBUTTON(); /* 95 */
2592 test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */
2593 test_SPI_SETMOUSEHOVERHEIGHT(); /* 101 */
2594 test_SPI_SETMOUSEHOVERTIME(); /* 103 */
2595 test_SPI_SETWHEELSCROLLLINES(); /* 105 */
2596 test_SPI_SETMENUSHOWDELAY(); /* 107 */
2597 test_SPI_SETWHEELSCROLLCHARS(); /* 108 */
2598 test_SPI_SETWALLPAPER(); /* 115 */
2601 SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
2602 return 0;
2605 /* test calculation of GetSystemMetrics values (mostly) from non client metrics,
2606 * icon metrics and minimized metrics.
2609 /* copied from wine's GdiGetCharDimensions, which is not available on most
2610 * windows versions */
2611 static LONG _GdiGetCharDimensions(HDC hdc, LPTEXTMETRICA lptm, LONG *height)
2613 SIZE sz;
2614 static const CHAR alphabet[] = {
2615 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
2616 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
2617 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
2619 if(lptm && !GetTextMetricsA(hdc, lptm)) return 0;
2621 if(!GetTextExtentPointA(hdc, alphabet, 52, &sz)) return 0;
2623 if (height) *height = sz.cy;
2624 return (sz.cx / 26 + 1) / 2;
2627 /* get text metrics and/or "average" char width of the specified logfont
2628 * for the specified dc */
2629 static void get_text_metr_size( HDC hdc, LOGFONTA *plf, TEXTMETRICA * ptm, UINT *psz)
2631 HFONT hfont, hfontsav;
2632 TEXTMETRICA tm;
2633 if( !ptm) ptm = &tm;
2634 hfont = CreateFontIndirectA( plf);
2635 if( !hfont || ( hfontsav = SelectObject( hdc, hfont)) == NULL ) {
2636 ptm->tmHeight = -1;
2637 if( psz) *psz = 10;
2638 if( hfont) DeleteObject( hfont);
2639 return;
2641 GetTextMetricsA( hdc, ptm);
2642 if( psz)
2643 if( !(*psz = _GdiGetCharDimensions( hdc, ptm, NULL)))
2644 *psz = 10;
2645 SelectObject( hdc, hfontsav);
2646 DeleteObject( hfont);
2649 static int gsm_error_ctr;
2651 #define ok_gsm( i, e)\
2653 int exp = (e);\
2654 int act = GetSystemMetrics( (i));\
2655 if( exp != act) gsm_error_ctr++;\
2656 ok( !( exp != act),"GetSystemMetrics(%s): expected %d actual %d\n", #i, exp,act);\
2658 #define ok_gsm_2( i, e1, e2)\
2660 int exp1 = (e1);\
2661 int exp2 = (e2);\
2662 int act = GetSystemMetrics( (i));\
2663 if( exp1 != act && exp2 != act) gsm_error_ctr++;\
2664 ok( !( exp1 != act && exp2 != act), "GetSystemMetrics(%s): expected %d or %d actual %d\n", #i, exp1, exp2, act);\
2666 #define ok_gsm_3( i, e1, e2, e3)\
2668 int exp1 = (e1);\
2669 int exp2 = (e2);\
2670 int exp3 = (e3);\
2671 int act = GetSystemMetrics( (i));\
2672 if( exp1 != act && exp2 != act && exp3 != act) gsm_error_ctr++;\
2673 ok( !( exp1 != act && exp2 != act && exp3 != act),"GetSystemMetrics(%s): expected %d or %d or %d actual %d\n", #i, exp1, exp2, exp3, act);\
2676 static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
2678 return lstrcmpiA(elf->lfFaceName, (const char *)lparam);
2681 static BOOL is_font_enumerated(const char *name)
2683 HDC hdc = CreateCompatibleDC(0);
2684 BOOL ret = FALSE;
2686 if (!EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)name))
2687 ret = TRUE;
2689 DeleteDC(hdc);
2690 return ret;
2693 static int get_cursor_size( int size )
2695 /* only certain sizes are allowed for cursors */
2696 if (size >= 64) return 64;
2697 if (size >= 48) return 48;
2698 return 32;
2701 static void test_GetSystemMetrics( void)
2703 TEXTMETRICA tmMenuFont;
2704 UINT IconSpacing, IconVerticalSpacing;
2705 BOOL rc;
2707 HDC hdc = CreateICA( "Display", 0, 0, 0);
2708 UINT avcwCaption;
2709 INT CaptionWidthfromreg, smicon, broken_val;
2710 MINIMIZEDMETRICS minim;
2711 NONCLIENTMETRICSA ncm;
2712 SIZE screen;
2714 assert(sizeof(ncm) == 344);
2716 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2717 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2718 ok(rc, "SystemParametersInfoA failed\n");
2720 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) - 1;
2721 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2722 ok(!rc, "SystemParametersInfoA should fail\n");
2724 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) + 1;
2725 SetLastError(0xdeadbeef);
2726 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2727 ok(!rc, "SystemParametersInfoA should fail\n");
2729 ncm.cbSize = sizeof(ncm); /* Vista added padding */
2730 SetLastError(0xdeadbeef);
2731 ncm.iPaddedBorderWidth = 0xcccc;
2732 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2733 ok(rc || broken(!rc) /* before Vista */, "SystemParametersInfoA failed\n");
2734 if (rc) ok( ncm.iPaddedBorderWidth == 0, "wrong iPaddedBorderWidth %u\n", ncm.iPaddedBorderWidth );
2736 minim.cbSize = sizeof( minim);
2737 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2738 SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0);
2739 rc = SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2740 if( !rc) {
2741 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
2742 return;
2745 ok(is_font_enumerated(ncm.lfCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfCaptionFont.lfFaceName);
2746 ok(is_font_enumerated(ncm.lfSmCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfSmCaptionFont.lfFaceName);
2747 ok(is_font_enumerated(ncm.lfMenuFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMenuFont.lfFaceName);
2748 ok(is_font_enumerated(ncm.lfStatusFont.lfFaceName), "font %s should be enumerated\n", ncm.lfStatusFont.lfFaceName);
2749 ok(is_font_enumerated(ncm.lfMessageFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMessageFont.lfFaceName);
2751 /* CaptionWidth from the registry may have different value of iCaptionWidth
2752 * from the non client metrics (observed on WinXP) */
2753 CaptionWidthfromreg = metricfromreg(
2754 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
2755 get_text_metr_size( hdc, &ncm.lfMenuFont, &tmMenuFont, NULL);
2756 get_text_metr_size( hdc, &ncm.lfCaptionFont, NULL, &avcwCaption);
2757 /* FIXME: use icon metric */
2758 if( !SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &IconVerticalSpacing, 0))
2759 IconVerticalSpacing = 0;
2760 if( !SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &IconSpacing, 0 ))
2761 IconSpacing = 0;
2762 /* reset error counters */
2763 gsm_error_ctr = 0;
2765 /* the tests: */
2767 /* SM_CXSCREEN, cannot test these two */
2768 /* SM_CYSCREEN */
2769 ok_gsm( SM_CXVSCROLL, ncm.iScrollWidth);
2770 ok_gsm( SM_CYHSCROLL, ncm.iScrollWidth);
2771 ok_gsm( SM_CYCAPTION, ncm.iCaptionHeight+1);
2772 ok_gsm( SM_CXBORDER, 1);
2773 ok_gsm( SM_CYBORDER, 1);
2774 ok_gsm( SM_CXDLGFRAME, 3);
2775 ok_gsm( SM_CYDLGFRAME, 3);
2776 ok_gsm( SM_CYVTHUMB, ncm.iScrollHeight);
2777 ok_gsm( SM_CXHTHUMB, ncm.iScrollHeight);
2778 /* These don't depend on the Shell Icon Size registry value */
2779 ok_gsm( SM_CXICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2780 ok_gsm( SM_CYICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2781 ok_gsm( SM_CXCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2782 ok_gsm( SM_CYCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2783 ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1);
2784 ok_gsm( SM_CXFULLSCREEN,
2785 GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME));
2786 ok_gsm( SM_CYFULLSCREEN,
2787 GetSystemMetrics( SM_CYMAXIMIZED) - GetSystemMetrics( SM_CYMIN));
2788 /* SM_CYKANJIWINDOW */
2789 /* SM_MOUSEPRESENT */
2790 ok_gsm( SM_CYVSCROLL, ncm.iScrollHeight);
2791 ok_gsm( SM_CXHSCROLL, ncm.iScrollHeight);
2792 /* SM_DEBUG */
2793 /* SM_SWAPBUTTON */
2794 /* SM_RESERVED1 */
2795 /* SM_RESERVED2 */
2796 /* SM_RESERVED3 */
2797 /* SM_RESERVED4 */
2798 ok_gsm( SM_CXMIN, 3 * max( CaptionWidthfromreg >= 0 ? CaptionWidthfromreg : ncm.iCaptionWidth, 8) +
2799 GetSystemMetrics( SM_CYSIZE) + 4 + 4 * avcwCaption + 2 * GetSystemMetrics( SM_CXFRAME));
2800 ok_gsm( SM_CYMIN, GetSystemMetrics( SM_CYCAPTION) +
2801 2 * GetSystemMetrics( SM_CYFRAME));
2802 ok_gsm_2( SM_CXSIZE,
2803 ncm.iCaptionWidth, /* classic/standard windows style */
2804 GetSystemMetrics( SM_CYCAPTION) - 1 /* WinXP style */
2806 ok_gsm( SM_CYSIZE, ncm.iCaptionHeight);
2807 ok_gsm( SM_CXFRAME, ncm.iBorderWidth + 3);
2808 ok_gsm( SM_CYFRAME, ncm.iBorderWidth + 3);
2809 ok_gsm( SM_CXMINTRACK, GetSystemMetrics( SM_CXMIN));
2810 ok_gsm( SM_CYMINTRACK, GetSystemMetrics( SM_CYMIN));
2811 /* SM_CXDOUBLECLK */
2812 /* SM_CYDOUBLECLK */
2813 if( IconSpacing) ok_gsm( SM_CXICONSPACING, IconSpacing);
2814 if( IconVerticalSpacing) ok_gsm( SM_CYICONSPACING, IconVerticalSpacing);
2815 /* SM_MENUDROPALIGNMENT */
2816 /* SM_PENWINDOWS */
2817 /* SM_DBCSENABLED */
2818 /* SM_CMOUSEBUTTONS */
2819 /* SM_SECURE */
2820 ok_gsm( SM_CXEDGE, 2);
2821 ok_gsm( SM_CYEDGE, 2);
2822 /* sign-extension for iHorzGap/iVertGap is broken on Win9x */
2823 ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + (short)minim.iHorzGap );
2824 ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + (short)minim.iVertGap );
2826 smicon = MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI );
2827 if (!pIsProcessDPIAware || pIsProcessDPIAware())
2828 smicon = max( min( smicon, CaptionWidthfromreg - 2), 4 ) & ~1;
2829 todo_wine_if( real_dpi == dpi && smicon != (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI) & ~1) )
2831 broken_val = (min( ncm.iCaptionHeight, CaptionWidthfromreg ) - 2) & ~1;
2832 broken_val = min( broken_val, 20 );
2834 if (smicon == 4)
2836 ok_gsm_2( SM_CXSMICON, smicon, 6 );
2837 ok_gsm_2( SM_CYSMICON, smicon, 6 );
2839 else if (smicon < broken_val)
2841 ok_gsm_2( SM_CXSMICON, smicon, broken_val );
2842 ok_gsm_2( SM_CYSMICON, smicon, broken_val );
2844 else
2846 ok_gsm( SM_CXSMICON, smicon );
2847 ok_gsm( SM_CYSMICON, smicon );
2851 ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1);
2852 ok_gsm_3( SM_CXSMSIZE,
2853 ncm.iSmCaptionWidth, /* classic/standard windows style */
2854 GetSystemMetrics( SM_CYSMCAPTION) - 1, /* WinXP style */
2855 smcxsmsize /* winXP seems to cache this value: setnonclientmetric
2856 does not change it */
2858 ok_gsm( SM_CYSMSIZE, GetSystemMetrics( SM_CYSMCAPTION) - 1);
2859 ok_gsm( SM_CXMENUSIZE, ncm.iMenuWidth);
2860 ok_gsm( SM_CYMENUSIZE, ncm.iMenuHeight);
2861 /* SM_ARRANGE */
2862 ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6);
2863 ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5);
2864 screen.cx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
2865 screen.cy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
2866 if (!screen.cx || !screen.cy) /* not supported on NT4 */
2868 screen.cx = GetSystemMetrics( SM_CXSCREEN );
2869 screen.cy = GetSystemMetrics( SM_CYSCREEN );
2871 ok_gsm_3( SM_CXMAXTRACK, screen.cx + 4 + 2 * GetSystemMetrics(SM_CXFRAME),
2872 screen.cx - 4 + 2 * GetSystemMetrics(SM_CXFRAME), /* Vista */
2873 screen.cx + 2 * GetSystemMetrics(SM_CXFRAME)); /* Win8 */
2874 ok_gsm_3( SM_CYMAXTRACK, screen.cy + 4 + 2 * GetSystemMetrics(SM_CYFRAME),
2875 screen.cy - 4 + 2 * GetSystemMetrics(SM_CYFRAME), /* Vista */
2876 screen.cy + 2 * GetSystemMetrics(SM_CYFRAME)); /* Win8 */
2877 /* the next two cannot really be tested as they depend on (application)
2878 * toolbars */
2879 /* SM_CXMAXIMIZED */
2880 /* SM_CYMAXIMIZED */
2881 /* SM_NETWORK */
2882 /* */
2883 /* */
2884 /* */
2885 /* SM_CLEANBOOT */
2886 /* SM_CXDRAG */
2887 /* SM_CYDRAG */
2888 /* SM_SHOWSOUNDS */
2889 ok_gsm( SM_CXMENUCHECK,
2890 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2891 ok_gsm( SM_CYMENUCHECK,
2892 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2893 /* SM_SLOWMACHINE */
2894 /* SM_MIDEASTENABLED */
2895 /* SM_MOUSEWHEELPRESENT */
2896 /* SM_XVIRTUALSCREEN */
2897 /* SM_YVIRTUALSCREEN */
2898 /* SM_CXVIRTUALSCREEN */
2899 /* SM_CYVIRTUALSCREEN */
2900 /* SM_CMONITORS */
2901 /* SM_SAMEDISPLAYFORMAT */
2902 /* SM_IMMENABLED */
2903 /* SM_CXFOCUSBORDER */
2904 /* SM_CYFOCUSBORDER */
2905 /* SM_TABLETPC */
2906 /* SM_MEDIACENTER */
2907 /* SM_CMETRICS */
2908 /* end of tests */
2909 if( gsm_error_ctr ) { /* if any errors where found */
2910 trace( "BorderWidth %d CaptionWidth %d CaptionHeight %d IconSpacing %d IconVerticalSpacing %d\n",
2911 ncm.iBorderWidth, ncm.iCaptionWidth, ncm.iCaptionHeight, IconSpacing, IconVerticalSpacing);
2912 trace( "MenuHeight %d MenuWidth %d ScrollHeight %d ScrollWidth %d SmCaptionHeight %d SmCaptionWidth %d\n",
2913 ncm.iMenuHeight, ncm.iMenuWidth, ncm.iScrollHeight, ncm.iScrollWidth, ncm.iSmCaptionHeight, ncm.iSmCaptionWidth);
2914 trace( "Captionfontchar width %d MenuFont %d,%d CaptionWidth from registry: %d screen %d,%d\n",
2915 avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidthfromreg, screen.cx, screen.cy);
2918 DeleteDC(hdc);
2921 static void compare_font( const LOGFONTW *lf1, const LOGFONTW *lf2, int dpi, int custom_dpi, int line )
2923 ok_(__FILE__,line)( lf1->lfHeight == MulDiv( lf2->lfHeight, dpi, custom_dpi ),
2924 "wrong lfHeight %d vs %d\n", lf1->lfHeight, lf2->lfHeight );
2925 ok_(__FILE__,line)( abs( lf1->lfWidth - MulDiv( lf2->lfWidth, dpi, custom_dpi )) <= 1,
2926 "wrong lfWidth %d vs %d\n", lf1->lfWidth, lf2->lfWidth );
2927 ok_(__FILE__,line)( !memcmp( &lf1->lfEscapement, &lf2->lfEscapement,
2928 offsetof( LOGFONTW, lfFaceName ) - offsetof( LOGFONTW, lfEscapement )),
2929 "font differs\n" );
2930 ok_(__FILE__,line)( !lstrcmpW( lf1->lfFaceName, lf2->lfFaceName ), "wrong face name %s vs %s\n",
2931 wine_dbgstr_w( lf1->lfFaceName ), wine_dbgstr_w( lf2->lfFaceName ));
2934 static void test_metrics_for_dpi( int custom_dpi )
2936 int i, val;
2937 NONCLIENTMETRICSW ncm1, ncm2;
2938 ICONMETRICSW im1, im2;
2939 LOGFONTW lf1, lf2;
2940 BOOL ret;
2942 if (!pSystemParametersInfoForDpi)
2944 win_skip( "custom dpi metrics not supported\n" );
2945 return;
2948 ncm1.cbSize = sizeof(ncm1);
2949 ret = SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof(ncm1), &ncm1, FALSE );
2950 ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
2951 ncm2.cbSize = sizeof(ncm2);
2952 ret = pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof(ncm2), &ncm2, FALSE, custom_dpi );
2953 ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
2955 for (i = 0; i < 92; i++)
2957 int ret1 = GetSystemMetrics( i );
2958 int ret2 = pGetSystemMetricsForDpi( i, custom_dpi );
2959 switch (i)
2961 case SM_CXVSCROLL:
2962 case SM_CYHSCROLL:
2963 case SM_CYVTHUMB:
2964 case SM_CXHTHUMB:
2965 case SM_CXICON:
2966 case SM_CYICON:
2967 case SM_CYVSCROLL:
2968 case SM_CXHSCROLL:
2969 case SM_CYSIZE:
2970 case SM_CXICONSPACING:
2971 case SM_CYICONSPACING:
2972 case SM_CXSMSIZE:
2973 case SM_CYSMSIZE:
2974 case SM_CYMENUSIZE:
2975 ok( ret1 == MulDiv( ret2, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2976 break;
2977 case SM_CXSIZE:
2978 ok( ret1 == ncm1.iCaptionWidth && ret2 == ncm2.iCaptionWidth,
2979 "%u: wrong value %u vs %u caption %u vs %u\n",
2980 i, ret1, ret2, ncm1.iCaptionWidth, ncm2.iCaptionWidth );
2981 break;
2982 case SM_CXCURSOR:
2983 case SM_CYCURSOR:
2984 val = MulDiv( 32, custom_dpi, USER_DEFAULT_SCREEN_DPI );
2985 if (val < 48) val = 32;
2986 else if (val < 64) val = 48;
2987 else val = 64;
2988 ok( val == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2989 break;
2990 case SM_CYCAPTION:
2991 case SM_CYSMCAPTION:
2992 case SM_CYMENU:
2993 ok( ret1 - 1 == MulDiv( ret2 - 1, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2994 break;
2995 case SM_CXMENUSIZE:
2996 ok( ret1 / 8 == MulDiv( ret2, dpi, custom_dpi ) / 8, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
2997 break;
2998 case SM_CXFRAME:
2999 case SM_CYFRAME:
3000 ok( ret1 == ncm1.iBorderWidth + 3 && ret2 == ncm2.iBorderWidth + 3,
3001 "%u: wrong value %u vs %u borders %u+%u vs %u+%u\n", i, ret1, ret2,
3002 ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
3003 break;
3004 case SM_CXSMICON:
3005 case SM_CYSMICON:
3006 ok( ret1 == (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI ) & ~1) &&
3007 ret2 == (MulDiv( 16, custom_dpi, USER_DEFAULT_SCREEN_DPI ) & ~1),
3008 "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3009 break;
3010 case SM_CXMENUCHECK:
3011 case SM_CYMENUCHECK:
3012 ok( ret1 == ((get_tmheightW( &ncm1.lfMenuFont, 1 ) - 1) | 1) &&
3013 ret2 == ((get_tmheightW( &ncm2.lfMenuFont, 1 ) - 1) | 1),
3014 "%u: wrong value %u vs %u font %u vs %u\n", i, ret1, ret2,
3015 get_tmheightW( &ncm1.lfMenuFont, 1 ), get_tmheightW( &ncm2.lfMenuFont, 1 ));
3016 break;
3017 default:
3018 ok( ret1 == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3019 break;
3022 im1.cbSize = sizeof(im1);
3023 ret = SystemParametersInfoW( SPI_GETICONMETRICS, sizeof(im1), &im1, FALSE );
3024 ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
3025 im2.cbSize = sizeof(im2);
3026 ret = pSystemParametersInfoForDpi( SPI_GETICONMETRICS, sizeof(im2), &im2, FALSE, custom_dpi );
3027 ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
3028 ok( im1.iHorzSpacing == MulDiv( im2.iHorzSpacing, dpi, custom_dpi ), "wrong iHorzSpacing %u vs %u\n",
3029 im1.iHorzSpacing, im2.iHorzSpacing );
3030 ok( im1.iVertSpacing == MulDiv( im2.iVertSpacing, dpi, custom_dpi ), "wrong iVertSpacing %u vs %u\n",
3031 im1.iVertSpacing, im2.iVertSpacing );
3032 ok( im1.iTitleWrap == im2.iTitleWrap, "wrong iTitleWrap %u vs %u\n",
3033 im1.iTitleWrap, im2.iTitleWrap );
3034 compare_font( &im1.lfFont, &im2.lfFont, dpi, custom_dpi, __LINE__ );
3036 ret = SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf1), &lf1, FALSE );
3037 ok( ret, "SystemParametersInfoW failed err %u\n", GetLastError() );
3038 ret = pSystemParametersInfoForDpi( SPI_GETICONTITLELOGFONT, sizeof(lf2), &lf2, FALSE, custom_dpi );
3039 ok( ret, "SystemParametersInfoForDpi failed err %u\n", GetLastError() );
3040 compare_font( &lf1, &lf2, dpi, custom_dpi, __LINE__ );
3042 /* on high-dpi iPaddedBorderWidth is used in addition to iBorderWidth */
3043 ok( ncm1.iBorderWidth + ncm1.iPaddedBorderWidth == MulDiv( ncm2.iBorderWidth + ncm2.iPaddedBorderWidth, dpi, custom_dpi ),
3044 "wrong iBorderWidth %u+%u vs %u+%u\n",
3045 ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
3046 ok( ncm1.iScrollWidth == MulDiv( ncm2.iScrollWidth, dpi, custom_dpi ),
3047 "wrong iScrollWidth %u vs %u\n", ncm1.iScrollWidth, ncm2.iScrollWidth );
3048 ok( ncm1.iScrollHeight == MulDiv( ncm2.iScrollHeight, dpi, custom_dpi ),
3049 "wrong iScrollHeight %u vs %u\n", ncm1.iScrollHeight, ncm2.iScrollHeight );
3050 ok( ((ncm1.iCaptionWidth + 1) & ~1) == ((MulDiv( ncm2.iCaptionWidth, dpi, custom_dpi ) + 1) & ~1),
3051 "wrong iCaptionWidth %u vs %u\n", ncm1.iCaptionWidth, ncm2.iCaptionWidth );
3052 ok( ncm1.iCaptionHeight == MulDiv( ncm2.iCaptionHeight, dpi, custom_dpi ),
3053 "wrong iCaptionHeight %u vs %u\n", ncm1.iCaptionHeight, ncm2.iCaptionHeight );
3054 compare_font( &ncm1.lfCaptionFont, &ncm2.lfCaptionFont, dpi, custom_dpi, __LINE__ );
3055 ok( ncm1.iSmCaptionHeight == MulDiv( ncm2.iSmCaptionHeight, dpi, custom_dpi ),
3056 "wrong iSmCaptionHeight %u vs %u\n", ncm1.iSmCaptionHeight, ncm2.iSmCaptionHeight );
3057 compare_font( &ncm1.lfSmCaptionFont, &ncm2.lfSmCaptionFont, dpi, custom_dpi, __LINE__ );
3058 ok( ncm1.iMenuHeight == MulDiv( ncm2.iMenuHeight, dpi, custom_dpi ),
3059 "wrong iMenuHeight %u vs %u\n", ncm1.iMenuHeight, ncm2.iMenuHeight );
3060 /* iSmCaptionWidth and iMenuWidth apparently need to be multiples of 8 */
3061 ok( ncm1.iSmCaptionWidth / 8 == MulDiv( ncm2.iSmCaptionWidth, dpi, custom_dpi ) / 8,
3062 "wrong iSmCaptionWidth %u vs %u\n", ncm1.iSmCaptionWidth, ncm2.iSmCaptionWidth );
3063 ok( ncm1.iMenuWidth / 8 == MulDiv( ncm2.iMenuWidth, dpi, custom_dpi ) / 8,
3064 "wrong iMenuWidth %u vs %u\n", ncm1.iMenuWidth, ncm2.iMenuWidth );
3065 compare_font( &ncm1.lfMenuFont, &ncm2.lfMenuFont, dpi, custom_dpi, __LINE__ );
3066 compare_font( &ncm1.lfStatusFont, &ncm2.lfStatusFont, dpi, custom_dpi, __LINE__ );
3067 compare_font( &ncm1.lfMessageFont, &ncm2.lfMessageFont, dpi, custom_dpi, __LINE__ );
3069 for (i = 1; i < 120; i++)
3071 if (i == SPI_GETICONTITLELOGFONT || i == SPI_GETNONCLIENTMETRICS || i == SPI_GETICONMETRICS)
3072 continue;
3073 SetLastError( 0xdeadbeef );
3074 ret = pSystemParametersInfoForDpi( i, 0, &val, 0, custom_dpi );
3075 ok( !ret, "%u: SystemParametersInfoForDpi succeeded\n", i );
3076 ok( GetLastError() == ERROR_INVALID_PARAMETER, "%u: wrong error %u\n", i, GetLastError() );
3080 static void test_EnumDisplaySettings(void)
3082 DEVMODEA devmode;
3083 DWORD val;
3084 HDC hdc;
3085 DWORD num;
3087 memset(&devmode, 0, sizeof(devmode));
3088 EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &devmode);
3090 hdc = GetDC(0);
3091 val = GetDeviceCaps(hdc, BITSPIXEL);
3092 ok(devmode.dmBitsPerPel == val,
3093 "GetDeviceCaps(BITSPIXEL) returned %d, EnumDisplaySettings returned %d\n",
3094 val, devmode.dmBitsPerPel);
3096 val = GetDeviceCaps(hdc, NUMCOLORS);
3097 if(devmode.dmBitsPerPel <= 8) {
3098 ok(val == 256, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
3099 } else {
3100 ok(val == -1, "Screen bpp is %d, NUMCOLORS returned %d\n", devmode.dmBitsPerPel, val);
3103 ReleaseDC(0, hdc);
3105 num = 1;
3106 while (1) {
3107 SetLastError (0xdeadbeef);
3108 if (!EnumDisplaySettingsA(NULL, num, &devmode)) {
3109 DWORD le = GetLastError();
3110 ok(le == ERROR_NO_MORE_FILES ||
3111 le == ERROR_MOD_NOT_FOUND /* Win8 */ ||
3112 le == 0xdeadbeef, /* XP, 2003 */
3113 "Expected ERROR_NO_MORE_FILES, ERROR_MOD_NOT_FOUND or 0xdeadbeef, got %d for %d\n", le, num);
3114 break;
3116 num++;
3120 static void test_GetSysColorBrush(void)
3122 HBRUSH hbr;
3124 SetLastError(0xdeadbeef);
3125 hbr = GetSysColorBrush(-1);
3126 ok(hbr == NULL, "Expected NULL brush\n");
3127 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
3128 /* greater than max index */
3129 hbr = GetSysColorBrush(COLOR_MENUBAR);
3130 if (hbr)
3132 SetLastError(0xdeadbeef);
3133 hbr = GetSysColorBrush(COLOR_MENUBAR + 1);
3134 ok(hbr == NULL, "Expected NULL brush\n");
3135 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %x\n", GetLastError());
3137 else
3138 win_skip("COLOR_MENUBAR unsupported\n");
3141 static void test_dpi_stock_objects( HDC hdc )
3143 DPI_AWARENESS_CONTEXT context;
3144 HGDIOBJ obj[STOCK_LAST + 1], obj2[STOCK_LAST + 1];
3145 LOGFONTW lf, lf2;
3146 UINT i, dpi;
3148 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3149 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3150 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3151 ok( !pIsProcessDPIAware(), "not aware\n" );
3152 for (i = 0; i <= STOCK_LAST; i++) obj[i] = GetStockObject( i );
3154 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3155 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3156 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3157 ok( pIsProcessDPIAware(), "not aware\n" );
3158 for (i = 0; i <= STOCK_LAST; i++) obj2[i] = GetStockObject( i );
3160 for (i = 0; i <= STOCK_LAST; i++)
3162 switch (i)
3164 case OEM_FIXED_FONT:
3165 case SYSTEM_FIXED_FONT:
3166 ok( obj[i] != obj2[i], "%u: same object\n", i );
3167 break;
3168 case SYSTEM_FONT:
3169 case DEFAULT_GUI_FONT:
3170 ok( obj[i] != obj2[i], "%u: same object\n", i );
3171 GetObjectW( obj[i], sizeof(lf), &lf );
3172 GetObjectW( obj2[i], sizeof(lf2), &lf2 );
3173 ok( lf.lfHeight == MulDiv( lf2.lfHeight, USER_DEFAULT_SCREEN_DPI, real_dpi ),
3174 "%u: wrong height %d / %d\n", i, lf.lfHeight, lf2.lfHeight );
3175 break;
3176 default:
3177 ok( obj[i] == obj2[i], "%u: different object\n", i );
3178 break;
3182 pSetThreadDpiAwarenessContext( context );
3185 static void scale_rect_dpi( RECT *rect, UINT src_dpi, UINT target_dpi )
3187 rect->left = MulDiv( rect->left, target_dpi, src_dpi );
3188 rect->top = MulDiv( rect->top, target_dpi, src_dpi );
3189 rect->right = MulDiv( rect->right, target_dpi, src_dpi );
3190 rect->bottom = MulDiv( rect->bottom, target_dpi, src_dpi );
3193 static void test_dpi_mapping(void)
3195 HWND hwnd;
3196 HDC hdc;
3197 UINT win_dpi;
3198 POINT point;
3199 BOOL ret, todo;
3200 RECT rect, orig, client, desktop, expect;
3201 ULONG_PTR i, j;
3202 HMONITOR monitor;
3203 MONITORINFO mon_info;
3204 DPI_AWARENESS_CONTEXT context;
3206 if (!pLogicalToPhysicalPointForPerMonitorDPI)
3208 win_skip( "LogicalToPhysicalPointForPerMonitorDPI not supported\n" );
3209 return;
3211 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3212 GetWindowRect( GetDesktopWindow(), &desktop );
3213 for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
3215 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3216 /* test desktop rect */
3217 GetWindowRect( GetDesktopWindow(), &rect );
3218 expect = desktop;
3219 if (i == DPI_AWARENESS_UNAWARE) scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3220 ok( EqualRect( &expect, &rect ), "%lu: wrong desktop rect %s expected %s\n",
3221 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3222 SetRect( &rect, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ));
3223 ok( EqualRect( &expect, &rect ), "%lu: wrong desktop rect %s expected %s\n",
3224 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3225 SetRect( &rect, 0, 0, GetSystemMetrics( SM_CXVIRTUALSCREEN ), GetSystemMetrics( SM_CYVIRTUALSCREEN ));
3226 ok( EqualRect( &expect, &rect ), "%lu: wrong virt desktop rect %s expected %s\n",
3227 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3228 SetRect( &rect, 0, 0, 1, 1 );
3229 monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
3230 ok( monitor != 0, "failed to get monitor\n" );
3231 mon_info.cbSize = sizeof(mon_info);
3232 ok( GetMonitorInfoW( monitor, &mon_info ), "GetMonitorInfoExW failed\n" );
3233 ok( EqualRect( &expect, &mon_info.rcMonitor ), "%lu: wrong monitor rect %s expected %s\n",
3234 i, wine_dbgstr_rect(&mon_info.rcMonitor), wine_dbgstr_rect(&expect) );
3235 hdc = CreateDCA( "display", NULL, NULL, NULL );
3236 SetRect( &rect, 0, 0, GetDeviceCaps( hdc, HORZRES ), GetDeviceCaps( hdc, VERTRES ));
3237 ok( EqualRect( &expect, &rect ), "%lu: wrong caps desktop rect %s expected %s\n",
3238 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3239 SetRect( &rect, 0, 0, GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ));
3240 ok( EqualRect( &desktop, &rect ), "%lu: wrong caps virt desktop rect %s expected %s\n",
3241 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&desktop) );
3242 DeleteDC( hdc );
3243 /* test message window rect */
3244 hwnd = CreateWindowA( "SysParamsTestClass", "test", WS_CHILD,
3245 10, 10, 20, 20, HWND_MESSAGE, 0, GetModuleHandleA(0), NULL );
3246 GetWindowRect( GetAncestor( hwnd, GA_PARENT ), &rect );
3247 SetRect( &expect, 0, 0, 100, 100 );
3248 if (i == DPI_AWARENESS_UNAWARE) scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3249 ok( EqualRect( &expect, &rect ), "%lu: wrong message rect %s expected %s\n",
3250 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3251 DestroyWindow( hwnd );
3253 for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
3255 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3256 hwnd = CreateWindowA( "SysParamsTestClass", "test", WS_OVERLAPPEDWINDOW,
3257 193, 177, 295, 303, 0, 0, GetModuleHandleA(0), NULL );
3258 ok( hwnd != 0, "creating window failed err %u\n", GetLastError());
3259 GetWindowRect( hwnd, &orig );
3260 GetClientRect( hwnd, &client );
3261 for (j = DPI_AWARENESS_UNAWARE; j <= DPI_AWARENESS_PER_MONITOR_AWARE; j++)
3263 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3264 GetWindowRect( hwnd, &rect );
3265 expect = orig;
3266 todo = (real_dpi != USER_DEFAULT_SCREEN_DPI);
3267 if (i == DPI_AWARENESS_UNAWARE && j != DPI_AWARENESS_UNAWARE)
3268 scale_rect_dpi( &expect, USER_DEFAULT_SCREEN_DPI, real_dpi );
3269 else if (i != DPI_AWARENESS_UNAWARE && j == DPI_AWARENESS_UNAWARE)
3270 scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3271 else
3272 todo = FALSE;
3273 todo_wine_if (todo)
3274 ok( EqualRect( &expect, &rect ), "%lu/%lu: wrong window rect %s expected %s\n",
3275 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3276 GetClientRect( hwnd, &rect );
3277 expect = client;
3278 MapWindowPoints( hwnd, 0, (POINT *)&expect, 2 );
3279 if (i == DPI_AWARENESS_UNAWARE && j != DPI_AWARENESS_UNAWARE)
3280 scale_rect_dpi( &expect, USER_DEFAULT_SCREEN_DPI, real_dpi );
3281 else if (i != DPI_AWARENESS_UNAWARE && j == DPI_AWARENESS_UNAWARE)
3282 scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3283 MapWindowPoints( 0, hwnd, (POINT *)&expect, 2 );
3284 OffsetRect( &expect, -expect.left, -expect.top );
3285 todo_wine_if (todo)
3286 ok( EqualRect( &expect, &rect ), "%lu/%lu: wrong client rect %s expected %s\n",
3287 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3288 win_dpi = pGetDpiForWindow( hwnd );
3289 if (i == DPI_AWARENESS_UNAWARE)
3290 ok( win_dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", win_dpi );
3291 else if (i == DPI_AWARENESS_SYSTEM_AWARE)
3292 ok( win_dpi == real_dpi, "wrong dpi %u / %u\n", win_dpi, real_dpi );
3293 point.x = 373;
3294 point.y = 377;
3295 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3296 ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3297 ok( point.x == MulDiv( 373, real_dpi, win_dpi ) &&
3298 point.y == MulDiv( 377, real_dpi, win_dpi ),
3299 "%lu/%lu: wrong pos %d,%d dpi %u\n", i, j, point.x, point.y, win_dpi );
3300 point.x = 405;
3301 point.y = 423;
3302 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3303 ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3304 ok( point.x == MulDiv( 405, win_dpi, real_dpi ) &&
3305 point.y == MulDiv( 423, win_dpi, real_dpi ),
3306 "%lu/%lu: wrong pos %d,%d dpi %u\n", i, j, point.x, point.y, win_dpi );
3307 /* point outside the window fails, but note that Windows (wrongly) checks against the
3308 * window rect transformed relative to the thread's awareness */
3309 GetWindowRect( hwnd, &rect );
3310 point.x = rect.left - 1;
3311 point.y = rect.top;
3312 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3313 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3314 point.x++;
3315 point.y--;
3316 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3317 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3318 point.y++;
3319 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3320 ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3321 point.x = rect.right;
3322 point.y = rect.bottom + 1;
3323 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3324 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3325 point.x++;
3326 point.y--;
3327 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3328 ok( !ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3329 point.x--;
3330 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3331 ok( ret, "%lu/%lu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3332 /* get physical window rect */
3333 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3334 GetWindowRect( hwnd, &rect );
3335 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3336 point.x = rect.left - 1;
3337 point.y = rect.top;
3338 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3339 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3340 point.x++;
3341 point.y--;
3342 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3343 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3344 point.y++;
3345 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3346 ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3347 point.x = rect.right;
3348 point.y = rect.bottom + 1;
3349 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3350 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3351 point.x++;
3352 point.y--;
3353 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3354 ok( !ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3355 point.x--;
3356 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3357 ok( ret, "%lu/%lu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3359 DestroyWindow( hwnd );
3361 pSetThreadDpiAwarenessContext( context );
3364 static void test_dpi_aware(void)
3366 BOOL ret;
3368 if (!pIsProcessDPIAware)
3370 win_skip("IsProcessDPIAware not available\n");
3371 return;
3374 ret = pSetProcessDPIAware();
3375 ok(ret, "got %d\n", ret);
3377 ret = pIsProcessDPIAware();
3378 ok(ret, "got %d\n", ret);
3380 dpi = real_dpi;
3381 test_GetSystemMetrics();
3382 test_metrics_for_dpi( 96 );
3383 test_metrics_for_dpi( 192 );
3386 static void test_dpi_context(void)
3388 DPI_AWARENESS awareness;
3389 DPI_AWARENESS_CONTEXT context;
3390 ULONG_PTR i;
3391 BOOL ret;
3392 UINT dpi;
3393 HDC hdc = GetDC( 0 );
3395 context = pGetThreadDpiAwarenessContext();
3396 todo_wine
3397 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3398 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3399 todo_wine
3400 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3401 todo_wine
3402 ok( !pIsProcessDPIAware(), "already aware\n" );
3403 dpi = pGetDpiForSystem();
3404 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
3405 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3406 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3407 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
3408 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3409 SetLastError( 0xdeadbeef );
3410 ret = pSetProcessDpiAwarenessContext( NULL );
3411 ok( !ret, "got %d\n", ret );
3412 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3413 SetLastError( 0xdeadbeef );
3414 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3415 ok( !ret, "got %d\n", ret );
3416 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3417 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3418 ok( ret, "got %d\n", ret );
3419 ok( pIsProcessDPIAware(), "not aware\n" );
3420 real_dpi = pGetDpiForSystem();
3421 SetLastError( 0xdeadbeef );
3422 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3423 ok( !ret, "got %d\n", ret );
3424 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3425 SetLastError( 0xdeadbeef );
3426 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3427 ok( !ret, "got %d\n", ret );
3428 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3430 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_INVALID );
3431 ok( !ret, "got %d\n", ret );
3432 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3433 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_UNAWARE );
3434 ok( !ret, "got %d\n", ret );
3435 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError() );
3436 ret = pGetProcessDpiAwarenessInternal( 0, &awareness );
3437 ok( ret, "got %d\n", ret );
3438 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3439 ret = pGetProcessDpiAwarenessInternal( GetCurrentProcess(), &awareness );
3440 ok( ret, "got %d\n", ret );
3441 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
3442 ret = pGetProcessDpiAwarenessInternal( (HANDLE)0xdeadbeef, &awareness );
3443 ok( ret, "got %d\n", ret );
3444 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong value %d\n", awareness );
3446 ret = pIsProcessDPIAware();
3447 ok(ret, "got %d\n", ret);
3448 context = pGetThreadDpiAwarenessContext();
3449 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3450 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3451 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3452 SetLastError( 0xdeadbeef );
3453 context = pSetThreadDpiAwarenessContext( 0 );
3454 ok( !context, "got %p\n", context );
3455 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3456 SetLastError( 0xdeadbeef );
3457 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-5 );
3458 ok( !context, "got %p\n", context );
3459 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %u\n", GetLastError() );
3460 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3461 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3462 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3463 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
3464 dpi = pGetDpiForSystem();
3465 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3466 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3467 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3468 ok( !pIsProcessDPIAware(), "still aware\n" );
3469 context = pGetThreadDpiAwarenessContext();
3470 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3471 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3472 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3473 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3474 ok( context == (DPI_AWARENESS_CONTEXT)0x10, "wrong context %p\n", context );
3475 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3476 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
3477 dpi = pGetDpiForSystem();
3478 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
3479 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3480 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3481 context = pGetThreadDpiAwarenessContext();
3482 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3483 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3484 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3485 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3486 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3487 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3488 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3489 dpi = pGetDpiForSystem();
3490 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
3491 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3492 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3493 ok( pIsProcessDPIAware(), "not aware\n" );
3494 context = pGetThreadDpiAwarenessContext();
3495 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3496 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000010 );
3497 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3498 context = pGetThreadDpiAwarenessContext();
3499 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3500 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000011 );
3501 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3502 context = pGetThreadDpiAwarenessContext();
3503 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3504 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
3505 ok( context == (DPI_AWARENESS_CONTEXT)0x80000011, "wrong context %p\n", context );
3506 context = pSetThreadDpiAwarenessContext( context );
3507 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
3508 context = pGetThreadDpiAwarenessContext();
3509 ok( context == (DPI_AWARENESS_CONTEXT)0x11, "wrong context %p\n", context );
3510 for (i = 0; i < 0x100; i++)
3512 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i );
3513 switch (i)
3515 case 0x10:
3516 case 0x11:
3517 case 0x12:
3518 ok( awareness == (i & ~0x10), "%lx: wrong value %u\n", i, awareness );
3519 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i ), "%lx: not valid\n", i );
3520 break;
3521 default:
3522 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", i, awareness );
3523 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i ), "%lx: valid\n", i );
3524 break;
3526 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) );
3527 switch (i)
3529 case 0x10:
3530 case 0x11:
3531 case 0x12:
3532 ok( awareness == (i & ~0x10), "%lx: wrong value %u\n", i | 0x80000000, awareness );
3533 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) ),
3534 "%lx: not valid\n", i | 0x80000000 );
3535 break;
3536 default:
3537 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", i | 0x80000000, awareness );
3538 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x80000000) ),
3539 "%lx: valid\n", i | 0x80000000 );
3540 break;
3542 awareness = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3543 switch (~i)
3545 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_UNAWARE:
3546 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_SYSTEM_AWARE:
3547 case (ULONG_PTR)DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE:
3548 ok( awareness == i, "%lx: wrong value %u\n", ~i, awareness );
3549 ok( pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i ), "%lx: not valid\n", ~i );
3550 break;
3551 default:
3552 ok( awareness == DPI_AWARENESS_INVALID, "%lx: wrong value %u\n", ~i, awareness );
3553 ok( !pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i ), "%lx: valid\n", ~i );
3554 break;
3557 if (real_dpi != USER_DEFAULT_SCREEN_DPI) test_dpi_stock_objects( hdc );
3558 ReleaseDC( 0, hdc );
3561 static LRESULT CALLBACK dpi_winproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
3563 DPI_AWARENESS_CONTEXT ctx = pGetWindowDpiAwarenessContext( hwnd );
3564 DPI_AWARENESS_CONTEXT ctx2 = pGetThreadDpiAwarenessContext();
3565 ok( pGetAwarenessFromDpiAwarenessContext( ctx ) == pGetAwarenessFromDpiAwarenessContext( ctx2 ),
3566 "msg %04x wrong awareness %p / %p\n", msg, ctx, ctx2 );
3567 return DefWindowProcA( hwnd, msg, wp, lp );
3570 static void test_dpi_window(void)
3572 DPI_AWARENESS_CONTEXT context, orig;
3573 DPI_AWARENESS awareness;
3574 ULONG_PTR i, j;
3575 UINT dpi;
3576 HWND hwnd, child, ret;
3577 MSG msg = { 0, WM_USER + 1, 0, 0 };
3579 if (!pGetWindowDpiAwarenessContext)
3581 win_skip( "GetWindowDpiAwarenessContext not supported\n" );
3582 return;
3584 orig = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3585 for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
3587 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3588 hwnd = CreateWindowA( "DpiTestClass", "Test",
3589 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3590 ok( hwnd != 0, "failed to create window\n" );
3591 context = pGetWindowDpiAwarenessContext( hwnd );
3592 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3593 ok( awareness == i, "%lu: wrong awareness %u\n", i, awareness );
3594 dpi = pGetDpiForWindow( hwnd );
3595 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
3596 "%lu: got %u / %u\n", i, dpi, real_dpi );
3597 if (pGetDpiForMonitorInternal)
3599 BOOL res;
3600 SetLastError( 0xdeadbeef );
3601 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 0, &dpi, NULL );
3602 ok( !res, "succeeded\n" );
3603 ok( GetLastError() == ERROR_INVALID_ADDRESS, "wrong error %u\n", GetLastError() );
3604 SetLastError( 0xdeadbeef );
3605 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 3, &dpi, &dpi );
3606 ok( !res, "succeeded\n" );
3607 ok( GetLastError() == ERROR_BAD_ARGUMENTS, "wrong error %u\n", GetLastError() );
3608 SetLastError( 0xdeadbeef );
3609 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 3, &dpi, NULL );
3610 ok( !res, "succeeded\n" );
3611 ok( GetLastError() == ERROR_BAD_ARGUMENTS, "wrong error %u\n", GetLastError() );
3612 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 0, &dpi, &dpi );
3613 ok( res, "failed err %u\n", GetLastError() );
3614 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
3615 "%lu: got %u / %u\n", i, dpi, real_dpi );
3617 msg.hwnd = hwnd;
3618 for (j = DPI_AWARENESS_UNAWARE; j <= DPI_AWARENESS_PER_MONITOR_AWARE; j++)
3620 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3621 SendMessageA( hwnd, WM_USER, 0, 0 );
3622 DispatchMessageA( &msg );
3623 CallWindowProcA( dpi_winproc, hwnd, WM_USER + 2, 0, 0 );
3624 child = CreateWindowA( "DpiTestClass", "Test",
3625 WS_CHILD, 0, 0, 100, 100, hwnd, 0, GetModuleHandleA(0), NULL );
3626 context = pGetWindowDpiAwarenessContext( child );
3627 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3628 ok( awareness == i, "%lu/%lu: wrong awareness %u\n", i, j, awareness );
3629 dpi = pGetDpiForWindow( child );
3630 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
3631 "%lu/%lu: got %u / %u\n", i, j, dpi, real_dpi );
3632 ret = SetParent( child, NULL );
3633 ok( ret != 0, "SetParent failed err %u\n", GetLastError() );
3634 context = pGetWindowDpiAwarenessContext( child );
3635 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3636 ok( awareness == i, "%lu/%lu: wrong awareness %u\n", i, j, awareness );
3637 dpi = pGetDpiForWindow( child );
3638 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
3639 "%lu/%lu: got %u / %u\n", i, j, dpi, real_dpi );
3640 DestroyWindow( child );
3641 child = CreateWindowA( "DpiTestClass", "Test",
3642 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
3643 context = pGetWindowDpiAwarenessContext( child );
3644 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3645 ok( awareness == j, "%lu/%lu: wrong awareness %u\n", i, j, awareness );
3646 dpi = pGetDpiForWindow( child );
3647 ok( dpi == (j == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
3648 "%lu/%lu: got %u / %u\n", i, j, dpi, real_dpi );
3649 ret = SetParent( child, hwnd );
3650 ok( ret != 0, "SetParent failed err %u\n", GetLastError() );
3651 context = pGetWindowDpiAwarenessContext( child );
3652 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3653 ok( awareness == i, "%lu/%lu: wrong awareness %u\n", i, j, awareness );
3654 dpi = pGetDpiForWindow( child );
3655 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
3656 "%lu/%lu: got %u / %u\n", i, j, dpi, real_dpi );
3657 DestroyWindow( child );
3659 DestroyWindow( hwnd );
3662 SetLastError( 0xdeadbeef );
3663 context = pGetWindowDpiAwarenessContext( (HWND)0xdeadbeef );
3664 ok( !context, "got %p\n", context );
3665 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %u\n", GetLastError() );
3666 SetLastError( 0xdeadbeef );
3667 dpi = pGetDpiForWindow( (HWND)0xdeadbeef );
3668 ok( !dpi, "got %u\n", dpi );
3669 ok( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_WINDOW_HANDLE,
3670 "wrong error %u\n", GetLastError() );
3672 SetLastError( 0xdeadbeef );
3673 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3674 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3675 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3676 dpi = pGetDpiForWindow( GetDesktopWindow() );
3677 ok( dpi == real_dpi, "got %u / %u\n", dpi, real_dpi );
3679 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3680 SetLastError( 0xdeadbeef );
3681 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
3682 awareness = pGetAwarenessFromDpiAwarenessContext( context );
3683 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
3684 dpi = pGetDpiForWindow( GetDesktopWindow() );
3685 ok( dpi == real_dpi, "got %u / %u\n", dpi, real_dpi );
3687 pSetThreadDpiAwarenessContext( orig );
3690 static void test_GetAutoRotationState(void)
3692 AR_STATE state;
3693 BOOL ret;
3695 if (!pGetAutoRotationState)
3697 win_skip("GetAutoRotationState not supported\n");
3698 return;
3701 SetLastError(0xdeadbeef);
3702 ret = pGetAutoRotationState(NULL);
3703 ok(!ret, "Expected GetAutoRotationState to fail\n");
3704 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
3706 state = 0;
3707 ret = pGetAutoRotationState(&state);
3708 ok(ret, "Expected GetAutoRotationState to succeed, error %d\n", GetLastError());
3711 START_TEST(sysparams)
3713 int argc;
3714 char** argv;
3715 WNDCLASSA wc;
3716 MSG msg;
3717 HDC hdc;
3718 HANDLE hThread;
3719 DWORD dwThreadId;
3720 HANDLE hInstance, hdll;
3722 hdll = GetModuleHandleA("user32.dll");
3723 pChangeDisplaySettingsExA = (void*)GetProcAddress(hdll, "ChangeDisplaySettingsExA");
3724 pIsProcessDPIAware = (void*)GetProcAddress(hdll, "IsProcessDPIAware");
3725 pSetProcessDPIAware = (void*)GetProcAddress(hdll, "SetProcessDPIAware");
3726 pGetDpiForSystem = (void*)GetProcAddress(hdll, "GetDpiForSystem");
3727 pGetDpiForWindow = (void*)GetProcAddress(hdll, "GetDpiForWindow");
3728 pGetDpiForMonitorInternal = (void*)GetProcAddress(hdll, "GetDpiForMonitorInternal");
3729 pSetProcessDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessContext");
3730 pGetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "GetProcessDpiAwarenessInternal");
3731 pSetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessInternal");
3732 pGetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetThreadDpiAwarenessContext");
3733 pSetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetThreadDpiAwarenessContext");
3734 pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetWindowDpiAwarenessContext");
3735 pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetAwarenessFromDpiAwarenessContext");
3736 pIsValidDpiAwarenessContext = (void*)GetProcAddress(hdll, "IsValidDpiAwarenessContext");
3737 pGetSystemMetricsForDpi = (void*)GetProcAddress(hdll, "GetSystemMetricsForDpi");
3738 pSystemParametersInfoForDpi = (void*)GetProcAddress(hdll, "SystemParametersInfoForDpi");
3739 pLogicalToPhysicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "LogicalToPhysicalPointForPerMonitorDPI");
3740 pPhysicalToLogicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "PhysicalToLogicalPointForPerMonitorDPI");
3741 pGetAutoRotationState = (void*)GetProcAddress(hdll, "GetAutoRotationState");
3743 hInstance = GetModuleHandleA( NULL );
3744 hdc = GetDC(0);
3745 dpi = GetDeviceCaps( hdc, LOGPIXELSY);
3746 real_dpi = get_real_dpi();
3747 trace("dpi %d real_dpi %d\n", dpi, real_dpi);
3748 ReleaseDC( 0, hdc);
3750 /* This test requires interactivity, if we don't have it, give up */
3751 if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) &&
3752 GetLastError()==ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) return;
3754 argc = winetest_get_mainargs(&argv);
3755 strict=(argc >= 3 && strcmp(argv[2],"strict")==0);
3756 trace("strict=%d\n",strict);
3758 trace("testing GetSystemMetrics with your current desktop settings\n");
3759 test_GetSystemMetrics( );
3760 test_metrics_for_dpi( 192 );
3761 test_EnumDisplaySettings( );
3762 test_GetSysColorBrush( );
3763 test_GetAutoRotationState( );
3765 change_counter = 0;
3766 change_last_param = 0;
3768 wc.lpszClassName = "SysParamsTestClass";
3769 wc.lpfnWndProc = SysParamsTestWndProc;
3770 wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
3771 wc.hInstance = hInstance;
3772 wc.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
3773 wc.hCursor = LoadCursorA( 0, (LPCSTR)IDC_ARROW );
3774 wc.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
3775 wc.lpszMenuName = 0;
3776 wc.cbClsExtra = 0;
3777 wc.cbWndExtra = 0;
3778 RegisterClassA( &wc );
3779 wc.lpszClassName = "DpiTestClass";
3780 wc.lpfnWndProc = dpi_winproc;
3781 RegisterClassA( &wc );
3783 ghTestWnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
3784 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, hInstance, NULL );
3786 hThread = CreateThread( NULL, 0, SysParamsThreadFunc, 0, 0, &dwThreadId );
3787 assert( hThread );
3788 CloseHandle( hThread );
3790 while( GetMessageA( &msg, 0, 0, 0 )) {
3791 TranslateMessage( &msg );
3792 DispatchMessageA( &msg );
3795 if (pSetThreadDpiAwarenessContext)
3797 test_dpi_context();
3798 test_dpi_mapping();
3799 test_dpi_window();
3801 else win_skip( "SetThreadDpiAwarenessContext not supported\n" );
3803 test_dpi_aware();