include/mscvpdb.h: Use flexible array members for the rest of structures.
[wine.git] / dlls / user32 / tests / sysparams.c
blob930d6ac6c5bd21d35cc84b223f8a708af154d62a
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 #include <assert.h>
21 #include <stdlib.h>
22 #include <stdarg.h>
23 #include <stdio.h>
25 #include "wine/test.h"
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winreg.h"
30 #include "winuser.h"
31 #include "winnls.h"
33 static BOOL (WINAPI *pIsProcessDPIAware)(void);
34 static BOOL (WINAPI *pSetProcessDPIAware)(void);
35 static BOOL (WINAPI *pSetProcessDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
36 static BOOL (WINAPI *pGetProcessDpiAwarenessInternal)(HANDLE,DPI_AWARENESS*);
37 static BOOL (WINAPI *pSetProcessDpiAwarenessInternal)(DPI_AWARENESS);
38 static UINT (WINAPI *pGetDpiForSystem)(void);
39 static UINT (WINAPI *pGetDpiForWindow)(HWND);
40 static BOOL (WINAPI *pGetDpiForMonitorInternal)(HMONITOR,UINT,UINT*,UINT*);
41 static DPI_AWARENESS_CONTEXT (WINAPI *pGetThreadDpiAwarenessContext)(void);
42 static DPI_AWARENESS_CONTEXT (WINAPI *pSetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
43 static DPI_AWARENESS_CONTEXT (WINAPI *pGetWindowDpiAwarenessContext)(HWND);
44 static DPI_AWARENESS (WINAPI *pGetAwarenessFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
45 static BOOL (WINAPI *pIsValidDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
46 static INT (WINAPI *pGetSystemMetricsForDpi)(INT,UINT);
47 static BOOL (WINAPI *pSystemParametersInfoForDpi)(UINT,UINT,void*,UINT,UINT);
48 static BOOL (WINAPI *pAdjustWindowRectExForDpi)(LPRECT,DWORD,BOOL,DWORD,UINT);
49 static BOOL (WINAPI *pLogicalToPhysicalPointForPerMonitorDPI)(HWND,POINT*);
50 static BOOL (WINAPI *pPhysicalToLogicalPointForPerMonitorDPI)(HWND,POINT*);
51 static LONG (WINAPI *pGetAutoRotationState)(PAR_STATE);
52 static BOOL (WINAPI *pAreDpiAwarenessContextsEqual)(DPI_AWARENESS_CONTEXT,DPI_AWARENESS_CONTEXT);
53 static LONG (WINAPI *pGetDpiFromDpiAwarenessContext)(DPI_AWARENESS_CONTEXT);
55 static BOOL strict;
56 static int dpi, real_dpi;
58 #define eq(received, expected, label, type) \
59 ok((received) == (expected), "%s: got " type " instead of " type "\n", (label),(received),(expected))
62 #define SPI_SETBEEP_REGKEY "Control Panel\\Sound"
63 #define SPI_SETBEEP_VALNAME "Beep"
64 #define SPI_SETMOUSE_REGKEY "Control Panel\\Mouse"
65 #define SPI_SETMOUSE_VALNAME1 "MouseThreshold1"
66 #define SPI_SETMOUSE_VALNAME2 "MouseThreshold2"
67 #define SPI_SETMOUSE_VALNAME3 "MouseSpeed"
68 #define SPI_SETBORDER_REGKEY "Control Panel\\Desktop\\WindowMetrics"
69 #define SPI_SETBORDER_REGKEY2 "Control Panel\\Desktop"
70 #define SPI_SETBORDER_VALNAME "BorderWidth"
71 #define SPI_METRIC_REGKEY "Control Panel\\Desktop\\WindowMetrics"
72 #define SPI_SCROLLWIDTH_VALNAME "ScrollWidth"
73 #define SPI_SCROLLHEIGHT_VALNAME "ScrollHeight"
74 #define SPI_CAPTIONWIDTH_VALNAME "CaptionWidth"
75 #define SPI_CAPTIONHEIGHT_VALNAME "CaptionHeight"
76 #define SPI_CAPTIONFONT_VALNAME "CaptionFont"
77 #define SPI_SMCAPTIONWIDTH_VALNAME "SmCaptionWidth"
78 #define SPI_SMCAPTIONHEIGHT_VALNAME "SmCaptionHeight"
79 #define SPI_SMCAPTIONFONT_VALNAME "SmCaptionFont"
80 #define SPI_MENUWIDTH_VALNAME "MenuWidth"
81 #define SPI_MENUHEIGHT_VALNAME "MenuHeight"
82 #define SPI_MENUFONT_VALNAME "MenuFont"
83 #define SPI_STATUSFONT_VALNAME "StatusFont"
84 #define SPI_MESSAGEFONT_VALNAME "MessageFont"
86 #define SPI_SETKEYBOARDSPEED_REGKEY "Control Panel\\Keyboard"
87 #define SPI_SETKEYBOARDSPEED_VALNAME "KeyboardSpeed"
88 #define SPI_ICONHORIZONTALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
89 #define SPI_ICONHORIZONTALSPACING_REGKEY2 "Control Panel\\Desktop"
90 #define SPI_ICONHORIZONTALSPACING_VALNAME "IconSpacing"
91 #define SPI_ICONVERTICALSPACING_REGKEY "Control Panel\\Desktop\\WindowMetrics"
92 #define SPI_ICONVERTICALSPACING_REGKEY2 "Control Panel\\Desktop"
93 #define SPI_ICONVERTICALSPACING_VALNAME "IconVerticalSpacing"
94 #define SPI_MINIMIZEDMETRICS_REGKEY "Control Panel\\Desktop\\WindowMetrics"
95 #define SPI_MINWIDTH_VALNAME "MinWidth"
96 #define SPI_MINHORZGAP_VALNAME "MinHorzGap"
97 #define SPI_MINVERTGAP_VALNAME "MinVertGap"
98 #define SPI_MINARRANGE_VALNAME "MinArrange"
99 #define SPI_SETSCREENSAVETIMEOUT_REGKEY "Control Panel\\Desktop"
100 #define SPI_SETSCREENSAVETIMEOUT_VALNAME "ScreenSaveTimeOut"
101 #define SPI_SETSCREENSAVEACTIVE_REGKEY "Control Panel\\Desktop"
102 #define SPI_SETSCREENSAVEACTIVE_VALNAME "ScreenSaveActive"
103 #define SPI_SETGRIDGRANULARITY_REGKEY "Control Panel\\Desktop"
104 #define SPI_SETGRIDGRANULARITY_VALNAME "GridGranularity"
105 #define SPI_SETKEYBOARDDELAY_REGKEY "Control Panel\\Keyboard"
106 #define SPI_SETKEYBOARDDELAY_VALNAME "KeyboardDelay"
107 #define SPI_SETICONTITLEWRAP_REGKEY1 "Control Panel\\Desktop\\WindowMetrics"
108 #define SPI_SETICONTITLEWRAP_REGKEY2 "Control Panel\\Desktop"
109 #define SPI_SETICONTITLEWRAP_VALNAME "IconTitleWrap"
110 #define SPI_SETMENUDROPALIGNMENT_REGKEY1 "Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows"
111 #define SPI_SETMENUDROPALIGNMENT_REGKEY2 "Control Panel\\Desktop"
112 #define SPI_SETMENUDROPALIGNMENT_VALNAME "MenuDropAlignment"
113 #define SPI_SETDOUBLECLKWIDTH_REGKEY1 "Control Panel\\Mouse"
114 #define SPI_SETDOUBLECLKWIDTH_REGKEY2 "Control Panel\\Desktop"
115 #define SPI_SETDOUBLECLKWIDTH_VALNAME "DoubleClickWidth"
116 #define SPI_SETDOUBLECLKHEIGHT_REGKEY1 "Control Panel\\Mouse"
117 #define SPI_SETDOUBLECLKHEIGHT_REGKEY2 "Control Panel\\Desktop"
118 #define SPI_SETDOUBLECLKHEIGHT_VALNAME "DoubleClickHeight"
119 #define SPI_SETDOUBLECLICKTIME_REGKEY "Control Panel\\Mouse"
120 #define SPI_SETDOUBLECLICKTIME_VALNAME "DoubleClickSpeed"
121 #define SPI_SETMOUSEBUTTONSWAP_REGKEY "Control Panel\\Mouse"
122 #define SPI_SETMOUSEBUTTONSWAP_VALNAME "SwapMouseButtons"
123 #define SPI_SETWORKAREA_REGKEY "Control Panel\\Desktop"
124 #define SPI_SETWORKAREA_VALNAME "WINE_WorkArea"
125 #define SPI_SETSHOWSOUNDS_REGKEY "Control Panel\\Accessibility\\ShowSounds"
126 #define SPI_SETSHOWSOUNDS_VALNAME "On"
127 #define SPI_SETKEYBOARDPREF_REGKEY "Control Panel\\Accessibility\\Keyboard Preference"
128 #define SPI_SETKEYBOARDPREF_VALNAME "On"
129 #define SPI_SETKEYBOARDPREF_REGKEY_LEGACY "Control Panel\\Accessibility"
130 #define SPI_SETKEYBOARDPREF_VALNAME_LEGACY "Keyboard Preference"
131 #define SPI_SETSCREENREADER_REGKEY "Control Panel\\Accessibility\\Blind Access"
132 #define SPI_SETSCREENREADER_VALNAME "On"
133 #define SPI_SETSCREENREADER_REGKEY_LEGACY "Control Panel\\Accessibility"
134 #define SPI_SETSCREENREADER_VALNAME_LEGACY "Blind Access"
135 #define SPI_SETFONTSMOOTHING_REGKEY "Control Panel\\Desktop"
136 #define SPI_SETFONTSMOOTHING_VALNAME "FontSmoothing"
137 #define SPI_SETFONTSMOOTHINGTYPE_VALNAME "FontSmoothingType"
138 #define SPI_SETFONTSMOOTHINGCONTRAST_VALNAME "FontSmoothingGamma"
139 #define SPI_SETFONTSMOOTHINGORIENTATION_VALNAME "FontSmoothingOrientation"
140 #define SPI_SETLOWPOWERACTIVE_REGKEY "Control Panel\\Desktop"
141 #define SPI_SETLOWPOWERACTIVE_VALNAME "LowPowerActive"
142 #define SPI_SETPOWEROFFACTIVE_REGKEY "Control Panel\\Desktop"
143 #define SPI_SETPOWEROFFACTIVE_VALNAME "PowerOffActive"
144 #define SPI_SETDRAGFULLWINDOWS_REGKEY "Control Panel\\Desktop"
145 #define SPI_SETDRAGFULLWINDOWS_VALNAME "DragFullWindows"
146 #define SPI_SETSNAPTODEFBUTTON_REGKEY "Control Panel\\Mouse"
147 #define SPI_SETSNAPTODEFBUTTON_VALNAME "SnapToDefaultButton"
148 #define SPI_SETMOUSEHOVERWIDTH_REGKEY "Control Panel\\Mouse"
149 #define SPI_SETMOUSEHOVERWIDTH_VALNAME "MouseHoverWidth"
150 #define SPI_SETMOUSEHOVERHEIGHT_REGKEY "Control Panel\\Mouse"
151 #define SPI_SETMOUSEHOVERHEIGHT_VALNAME "MouseHoverHeight"
152 #define SPI_SETMOUSEHOVERTIME_REGKEY "Control Panel\\Mouse"
153 #define SPI_SETMOUSEHOVERTIME_VALNAME "MouseHoverTime"
154 #define SPI_SETMOUSESCROLLCHARS_REGKEY "Control Panel\\Desktop"
155 #define SPI_SETMOUSESCROLLCHARS_VALNAME "WheelScrollChars"
156 #define SPI_SETMOUSESCROLLLINES_REGKEY "Control Panel\\Desktop"
157 #define SPI_SETMOUSESCROLLLINES_VALNAME "WheelScrollLines"
158 #define SPI_SETMENUSHOWDELAY_REGKEY "Control Panel\\Desktop"
159 #define SPI_SETMENUSHOWDELAY_VALNAME "MenuShowDelay"
160 #define SPI_SETDESKWALLPAPER_REGKEY "Control Panel\\Desktop"
161 #define SPI_SETDESKWALLPAPER_VALNAME "Wallpaper"
163 /* volatile registry branch under CURRENT_USER_REGKEY for temporary values storage */
164 #define WINE_CURRENT_USER_REGKEY "Wine"
166 static HWND ghTestWnd;
168 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam );
169 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
170 LPARAM lParam );
171 static int change_counter;
172 static int change_last_param;
173 static int last_bpp;
174 static BOOL displaychange_ok = FALSE, displaychange_test_active = FALSE;
175 static HANDLE displaychange_sem = 0;
177 #define run_in_process( a, b ) run_in_process_( __FILE__, __LINE__, a, b )
178 static void run_in_process_( const char *file, int line, char **argv, const char *args )
180 STARTUPINFOA startup = {.cb = sizeof(STARTUPINFOA)};
181 PROCESS_INFORMATION info = {0};
182 char cmdline[MAX_PATH * 2];
183 DWORD ret;
185 sprintf( cmdline, "%s %s %s", argv[0], argv[1], args );
186 ret = CreateProcessA( NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info );
187 ok_(file, line)( ret, "CreateProcessA failed, error %lu\n", GetLastError() );
188 if (!ret) return;
190 wait_child_process( info.hProcess );
191 CloseHandle( info.hThread );
192 CloseHandle( info.hProcess );
195 static BOOL get_reg_dword(HKEY base, const char *key_name, const char *value_name, DWORD *value)
197 HKEY key;
198 DWORD type, data, size = sizeof(data);
199 BOOL ret = FALSE;
201 if (RegOpenKeyA(base, key_name, &key) == ERROR_SUCCESS)
203 if (RegQueryValueExA(key, value_name, NULL, &type, (void *)&data, &size) == ERROR_SUCCESS &&
204 type == REG_DWORD)
206 *value = data;
207 ret = TRUE;
209 RegCloseKey(key);
211 return ret;
214 static DWORD get_real_dpi(void)
216 DPI_AWARENESS_CONTEXT ctx;
217 DWORD dpi;
219 if (pSetThreadDpiAwarenessContext)
221 ctx = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
222 todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", ctx );
223 dpi = pGetDpiForSystem();
224 ok( dpi, "GetDpiForSystem failed\n" );
225 /* restore process-wide DPI awareness context */
226 ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006010 );
227 ok( ctx == (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | (dpi << 8)), "got %p\n", ctx );
228 return dpi;
230 if (get_reg_dword(HKEY_CURRENT_USER, "Control Panel\\Desktop", "LogPixels", &dpi))
231 return dpi;
232 if (get_reg_dword(HKEY_CURRENT_CONFIG, "Software\\Fonts", "LogPixels", &dpi))
233 return dpi;
234 return USER_DEFAULT_SCREEN_DPI;
237 static LRESULT CALLBACK SysParamsTestWndProc( HWND hWnd, UINT msg, WPARAM wParam,
238 LPARAM lParam )
240 switch (msg) {
242 case WM_DISPLAYCHANGE:
243 ok(displaychange_ok, "Unexpected WM_DISPLAYCHANGE message\n");
244 last_bpp = wParam;
245 displaychange_ok = FALSE;
246 ReleaseSemaphore(displaychange_sem, 1, 0);
247 break;
249 case WM_SETTINGCHANGE:
250 if (wParam == SPI_SETHANDEDNESS) break; /* ignore */
251 if (!change_counter++) change_last_param = 0;
252 if (displaychange_test_active) break;
253 if (!change_last_param) change_last_param = wParam;
254 else if (change_last_param != wParam)
256 switch (wParam)
258 /* ignore these messages when caused by other actions */
259 case SPI_ICONVERTICALSPACING:
260 case SPI_SETWORKAREA:
261 break;
262 default:
263 ok( 0, "too many changes counter=%d last change=%Iu\n", change_counter, wParam );
264 break;
267 break;
269 case WM_DESTROY:
270 PostQuitMessage( 0 );
271 break;
273 /* drop through */
274 default:
275 return( DefWindowProcA( hWnd, msg, wParam, lParam ) );
278 return 0;
282 Performs testing for system parameters messages
283 params:
284 - system parameter id
285 - supposed value of the registry key
287 static void test_change_message( int action, int optional )
289 SendMessageA( ghTestWnd, WM_NULL, 0, 0 );
290 if (change_counter==0 && optional==1)
291 return;
292 ok( change_counter >= 1, "Missed a message: change_counter=%d\n", change_counter );
293 change_counter = 0;
294 ok( action == change_last_param, "Wrong action got %d expected %d\n", change_last_param, action );
295 change_last_param = 0;
298 static void flush_change_messages(void)
300 change_counter = 0;
301 SendMessageA( ghTestWnd, WM_NULL, 0, 0 );
302 change_counter = 0;
305 static BOOL test_error_msg ( int rc, const char *name )
307 DWORD last_error = GetLastError();
309 if (rc==0)
311 if (last_error==0xdeadbeef || last_error==ERROR_INVALID_SPI_VALUE || last_error==ERROR_INVALID_PARAMETER)
313 skip("%s not supported on this platform\n", name);
315 else if (last_error==ERROR_ACCESS_DENIED)
317 skip("%s does not have privileges to run\n", name);
319 else
321 trace("%s failed for reason: %ld. Indicating test failure and skipping remainder of test\n",name,last_error);
322 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,last_error);
324 return FALSE;
326 else
328 ok(rc!=0,"SystemParametersInfoA: rc=%d err=%ld\n",rc,last_error);
329 return TRUE;
334 * Tests the HKEY_CURRENT_USER subkey value.
335 * The value should contain string value.
337 static void _test_reg_key( LPCSTR subKey1, LPCSTR subKey2, LPCSTR valName1, LPCSTR valName2,
338 const void *exp_value, DWORD exp_type, BOOL optional )
340 CHAR value[MAX_PATH];
341 DWORD valueLen;
342 DWORD type;
343 HKEY hKey;
344 LONG rc;
345 int found=0;
347 *value='\0';
348 valueLen=sizeof(value);
349 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
350 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
351 RegCloseKey( hKey );
352 if (rc==ERROR_SUCCESS)
354 ok( type == exp_type, "wrong type %lu/%lu\n", type, exp_type );
355 switch (exp_type)
357 case REG_DWORD:
358 ok( *(DWORD *)value == *(DWORD *)exp_value,
359 "Wrong value in registry: %s %s %08lx/%08lx\n",
360 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
361 break;
362 case REG_SZ:
363 ok( !strcmp( exp_value, value ),
364 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
365 subKey1, valName1, value, (const char *)exp_value );
366 break;
368 found++;
370 else if (strict)
372 ok(0,"Missing registry entry: subKey=%s, valName=%s\n",
373 subKey1, valName1);
375 if (valName2)
377 *value='\0';
378 valueLen=sizeof(value);
379 RegOpenKeyA( HKEY_CURRENT_USER, subKey1, &hKey );
380 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
381 RegCloseKey( hKey );
382 if (rc==ERROR_SUCCESS)
384 ok( type == exp_type, "wrong type %lu/%lu\n", type, exp_type );
385 switch (exp_type)
387 case REG_DWORD:
388 ok( *(DWORD *)value == *(DWORD *)exp_value,
389 "Wrong value in registry: %s %s %08lx/%08lx\n",
390 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
391 break;
392 case REG_SZ:
393 ok( !strcmp( exp_value, value ),
394 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
395 subKey1, valName1, value, (const char *)exp_value );
396 break;
398 found++;
400 else if (strict)
402 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
403 subKey1, valName2 );
406 if (subKey2 && !strict)
408 *value='\0';
409 valueLen=sizeof(value);
410 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
411 rc=RegQueryValueExA( hKey, valName1, NULL, &type, (LPBYTE)value, &valueLen );
412 RegCloseKey( hKey );
413 if (rc==ERROR_SUCCESS)
415 ok( type == exp_type, "wrong type %lu/%lu\n", type, exp_type );
416 switch (exp_type)
418 case REG_DWORD:
419 ok( *(DWORD *)value == *(DWORD *)exp_value,
420 "Wrong value in registry: %s %s %08lx/%08lx\n",
421 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
422 break;
423 case REG_SZ:
424 ok( !strcmp( exp_value, value ),
425 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
426 subKey1, valName1, value, (const char *)exp_value );
427 break;
429 found++;
431 else if (strict)
433 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
434 subKey2, valName1 );
436 if (valName2)
438 *value='\0';
439 valueLen=sizeof(value);
440 RegOpenKeyA( HKEY_CURRENT_USER, subKey2, &hKey );
441 rc=RegQueryValueExA( hKey, valName2, NULL, &type, (LPBYTE)value, &valueLen );
442 RegCloseKey( hKey );
443 if (rc==ERROR_SUCCESS)
445 ok( type == exp_type, "wrong type %lu/%lu\n", type, exp_type );
446 switch (exp_type)
448 case REG_DWORD:
449 ok( *(DWORD *)value == *(DWORD *)exp_value,
450 "Wrong value in registry: %s %s %08lx/%08lx\n",
451 subKey1, valName1, *(DWORD *)value, *(DWORD *)exp_value );
452 break;
453 case REG_SZ:
454 ok( !strcmp( exp_value, value ),
455 "Wrong value in registry: %s %s '%s' instead of '%s'\n",
456 subKey1, valName1, value, (const char *)exp_value );
457 break;
459 found++;
461 else if (strict)
463 ok( 0,"Missing registry entry: subKey=%s, valName=%s\n",
464 subKey2, valName2 );
468 ok(found || optional,
469 "Missing registry values: %s or %s in keys: %s or %s\n",
470 valName1, (valName2?valName2:"<n/a>"), subKey1, (subKey2?subKey2:"<n/a>") );
473 #define test_reg_key( subKey, valName, testValue ) \
474 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, FALSE )
475 #define test_reg_key_optional( subKey, valName, testValue ) \
476 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_SZ, TRUE )
477 #define test_reg_key_ex( subKey1, subKey2, valName, testValue ) \
478 _test_reg_key( subKey1, subKey2, valName, NULL, testValue, REG_SZ, FALSE )
479 #define test_reg_key_ex2( subKey1, subKey2, valName1, valName2, testValue ) \
480 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, FALSE )
481 #define test_reg_key_ex2_optional( subKey1, subKey2, valName1, valName2, testValue ) \
482 _test_reg_key( subKey1, subKey2, valName1, valName2, testValue, REG_SZ, TRUE )
483 #define test_reg_key_dword( subKey, valName, testValue ) \
484 _test_reg_key( subKey, NULL, valName, NULL, testValue, REG_DWORD, FALSE )
486 /* get a metric from the registry. If the value is negative
487 * it is assumed to be in twips and converted to pixels */
488 static UINT metricfromreg( const char *keyname, const char *valname, int dpi)
490 HKEY hkey;
491 char buf[64];
492 DWORD ret;
493 DWORD size, type;
494 int value;
496 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
497 size = sizeof(buf);
498 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)buf, &size );
499 RegCloseKey( hkey );
500 if( ret != ERROR_SUCCESS) return -1;
501 value = atoi( buf);
502 if( value < 0)
503 value = ( -value * dpi + 720) / 1440;
504 return value;
507 typedef struct
509 INT16 lfHeight;
510 INT16 lfWidth;
511 INT16 lfEscapement;
512 INT16 lfOrientation;
513 INT16 lfWeight;
514 BYTE lfItalic;
515 BYTE lfUnderline;
516 BYTE lfStrikeOut;
517 BYTE lfCharSet;
518 BYTE lfOutPrecision;
519 BYTE lfClipPrecision;
520 BYTE lfQuality;
521 BYTE lfPitchAndFamily;
522 CHAR lfFaceName[LF_FACESIZE];
523 } LOGFONT16, *LPLOGFONT16;
525 /* get logfont from the registry */
526 static int lffromreg( const char *keyname, const char *valname, LOGFONTA *plf)
528 HKEY hkey;
529 LOGFONTW lfw;
530 DWORD ret, size, type;
532 RegOpenKeyA( HKEY_CURRENT_USER, keyname, &hkey );
533 size = sizeof( lfw);
534 ret=RegQueryValueExA( hkey, valname, NULL, &type, (LPBYTE)&lfw, &size );
535 RegCloseKey( hkey );
536 ok( ret == ERROR_SUCCESS, "Key \"%s\" value \"%s\" not found\n", keyname, valname);
537 if( ret != ERROR_SUCCESS)
538 return FALSE;
539 if( size <= sizeof( LOGFONT16)) {
540 LOGFONT16 *plf16 = (LOGFONT16*) &lfw;
541 plf->lfHeight = plf16->lfHeight;
542 plf->lfWidth = plf16->lfWidth;
543 plf->lfEscapement = plf16->lfEscapement;
544 plf->lfOrientation = plf16->lfOrientation;
545 plf->lfWeight = plf16->lfWeight;
546 plf->lfItalic = plf16->lfItalic;
547 plf->lfUnderline = plf16->lfUnderline;
548 plf->lfStrikeOut = plf16->lfStrikeOut;
549 plf->lfCharSet = plf16->lfCharSet;
550 plf->lfOutPrecision = plf16->lfOutPrecision;
551 plf->lfClipPrecision = plf16->lfClipPrecision;
552 plf->lfQuality = plf16->lfQuality;
553 plf->lfPitchAndFamily = plf16->lfPitchAndFamily;
554 memcpy( plf->lfFaceName, plf16->lfFaceName, LF_FACESIZE );
555 } else if( size <= sizeof( LOGFONTA)) {
556 plf = (LOGFONTA*) &lfw;
557 } else {
558 plf->lfHeight = lfw.lfHeight;
559 plf->lfWidth = lfw.lfWidth;
560 plf->lfEscapement = lfw.lfEscapement;
561 plf->lfOrientation = lfw.lfOrientation;
562 plf->lfWeight = lfw.lfWeight;
563 plf->lfItalic = lfw.lfItalic;
564 plf->lfUnderline = lfw.lfUnderline;
565 plf->lfStrikeOut = lfw.lfStrikeOut;
566 plf->lfCharSet = lfw.lfCharSet;
567 plf->lfOutPrecision = lfw.lfOutPrecision;
568 plf->lfClipPrecision = lfw.lfClipPrecision;
569 plf->lfQuality = lfw.lfQuality;
570 plf->lfPitchAndFamily = lfw.lfPitchAndFamily;
571 WideCharToMultiByte( CP_ACP, 0, lfw.lfFaceName, -1, plf->lfFaceName,
572 LF_FACESIZE, NULL, NULL);
575 return TRUE;
578 static void test_SPI_SETBEEP( void ) /* 2 */
580 BOOL rc;
581 BOOL old_b;
582 BOOL b;
583 BOOL curr_val;
585 trace("testing SPI_{GET,SET}BEEP\n");
586 SetLastError(0xdeadbeef);
587 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &old_b, 0 );
588 if (!test_error_msg(rc,"SPI_{GET,SET}BEEP"))
589 return;
591 curr_val = TRUE;
592 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
593 if (!test_error_msg(rc,"SPI_SETBEEP")) return;
594 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
595 test_change_message( SPI_SETBEEP, 0 );
596 test_reg_key( SPI_SETBEEP_REGKEY,
597 SPI_SETBEEP_VALNAME,
598 curr_val ? "Yes" : "No" );
599 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
600 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
601 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
602 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
603 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
605 ok(rc, "SystemParametersInfoW: rc=%d err=%ld\n", rc, GetLastError());
606 eq( b, curr_val, "SystemParametersInfoW", "%d" );
609 /* is a message sent for the second change? */
610 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
611 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
612 test_change_message( SPI_SETBEEP, 0 );
614 curr_val = FALSE;
615 rc=SystemParametersInfoW( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
616 if (rc == FALSE && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
617 rc=SystemParametersInfoA( SPI_SETBEEP, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
618 ok(rc, "SystemParametersInfo: rc=%d err=%ld\n", rc, GetLastError());
619 test_change_message( SPI_SETBEEP, 0 );
620 test_reg_key( SPI_SETBEEP_REGKEY,
621 SPI_SETBEEP_VALNAME,
622 curr_val ? "Yes" : "No" );
623 rc=SystemParametersInfoA( SPI_GETBEEP, 0, &b, 0 );
624 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
625 eq( b, curr_val, "SPI_{GET,SET}BEEP", "%d" );
626 rc=SystemParametersInfoW( SPI_GETBEEP, 0, &b, 0 );
627 if (rc || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
629 ok(rc, "SystemParametersInfoW: rc=%d err=%ld\n", rc, GetLastError());
630 eq( b, curr_val, "SystemParametersInfoW", "%d" );
632 ok( MessageBeep( MB_OK ), "Return value of MessageBeep when sound is disabled\n" );
634 rc=SystemParametersInfoA( SPI_SETBEEP, old_b, 0, SPIF_UPDATEINIFILE );
635 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
638 static const char *setmouse_valuenames[3] = {
639 SPI_SETMOUSE_VALNAME1,
640 SPI_SETMOUSE_VALNAME2,
641 SPI_SETMOUSE_VALNAME3
645 * Runs check for one setting of spi_setmouse.
647 static BOOL run_spi_setmouse_test( int curr_val[], POINT *req_change, POINT *proj_change, int nchange )
649 BOOL rc;
650 INT mi[3];
651 static int aw_turn = 0;
653 char buf[20];
654 int i;
656 aw_turn++;
657 rc = FALSE;
658 SetLastError(0xdeadbeef);
659 if (aw_turn % 2) /* call unicode on odd (non even) calls */
660 rc=SystemParametersInfoW( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
661 else
662 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, curr_val, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
663 if (!test_error_msg(rc,"SPI_SETMOUSE")) return FALSE;
665 ok(rc, "SystemParametersInfo: rc=%d err=%ld\n", rc, GetLastError());
666 test_change_message( SPI_SETMOUSE, 0 );
667 for (i = 0; i < 3; i++)
669 sprintf( buf, "%d", curr_val[i] );
670 test_reg_key( SPI_SETMOUSE_REGKEY, setmouse_valuenames[i], buf );
673 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, mi, 0 );
674 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
675 ok(mi[0] == curr_val[0], "expected X threshold %d, got %d\n", curr_val[0], mi[0]);
676 ok(mi[1] == curr_val[1], "expected Y threshold %d, got %d\n", curr_val[1], mi[1]);
677 ok(mi[2] == curr_val[2] || broken(mi[2] == 1) /* Win10 1709+ */,
678 "expected acceleration %d, got %d\n", curr_val[2], mi[2]);
680 rc=SystemParametersInfoW( SPI_GETMOUSE, 0, mi, 0 );
681 ok(rc, "SystemParametersInfoW: rc=%d err=%ld\n", rc, GetLastError());
682 ok(mi[0] == curr_val[0], "expected X threshold %d, got %d\n", curr_val[0], mi[0]);
683 ok(mi[1] == curr_val[1], "expected Y threshold %d, got %d\n", curr_val[1], mi[1]);
684 ok(mi[2] == curr_val[2] || broken(mi[2] == 1) /* Win10 1709+ */,
685 "expected acceleration %d, got %d\n", curr_val[2], mi[2]);
687 if (0)
689 /* FIXME: this always fails for me - AJ */
690 for (i = 0; i < nchange; i++)
692 POINT mv;
693 mouse_event( MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, 0, 0, 0, 0 );
694 mouse_event( MOUSEEVENTF_MOVE, req_change[i].x, req_change[i].y, 0, 0 );
695 GetCursorPos( &mv );
696 ok( proj_change[i].x == mv.x, "Projected dx and real dx comparison. May fail under high load.\n" );
697 ok( proj_change[i].y == mv.y, "Projected dy equals real dy. May fail under high load.\n" );
700 return TRUE;
703 static void test_SPI_SETMOUSE( void ) /* 4 */
705 BOOL rc;
706 INT old_mi[3];
708 /* win nt default values - 6, 10, 1 */
709 INT curr_val[3] = {6, 10, 1};
711 /* requested and projected mouse movements */
712 POINT req_change[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
713 POINT proj_change1[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
714 POINT proj_change2[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {44, 20}, {400, 400} };
715 POINT proj_change3[] = { {6, 6}, {14, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
716 POINT proj_change4[] = { {6, 6}, { 7, 6}, { 8, 6}, {10, 10}, {11, 10}, {100, 100} };
717 POINT proj_change5[] = { {6, 6}, { 7, 6}, {16, 6}, {20, 20}, {22, 20}, {200, 200} };
718 POINT proj_change6[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
719 POINT proj_change7[] = { {6, 6}, {14, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
720 POINT proj_change8[] = { {6, 6}, {28, 6}, {32, 6}, {40, 40}, {44, 40}, {400, 400} };
722 int nchange = ARRAY_SIZE(req_change);
724 trace("testing SPI_{GET,SET}MOUSE\n");
725 SetLastError(0xdeadbeef);
726 rc=SystemParametersInfoA( SPI_GETMOUSE, 0, old_mi, 0 );
727 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSE"))
728 return;
730 if (!run_spi_setmouse_test( curr_val, req_change, proj_change1, nchange )) return;
732 /* acceleration change */
733 curr_val[2] = 2;
734 run_spi_setmouse_test( curr_val, req_change, proj_change2, nchange );
736 /* acceleration change */
737 curr_val[2] = 3;
738 run_spi_setmouse_test( curr_val, req_change, proj_change3, nchange );
740 /* acceleration change */
741 curr_val[2] = 0;
742 run_spi_setmouse_test( curr_val, req_change, proj_change4, nchange );
744 /* threshold change */
745 curr_val[2] = 1;
746 curr_val[0] = 7;
747 run_spi_setmouse_test( curr_val, req_change, proj_change5, nchange );
749 /* threshold change */
750 curr_val[2] = 2;
751 curr_val[0] = 6;
752 curr_val[1] = 6;
753 run_spi_setmouse_test( curr_val, req_change, proj_change6, nchange );
755 /* threshold change */
756 curr_val[1] = 7;
757 run_spi_setmouse_test( curr_val, req_change, proj_change7, nchange );
759 /* threshold change */
760 curr_val[1] = 5;
761 run_spi_setmouse_test( curr_val, req_change, proj_change8, nchange );
763 rc=SystemParametersInfoA( SPI_SETMOUSE, 0, old_mi, SPIF_UPDATEINIFILE );
764 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
767 static BOOL test_setborder(UINT curr_val, int usesetborder, int dpi)
769 BOOL rc;
770 UINT border, regval;
771 INT frame;
772 NONCLIENTMETRICSA ncm;
774 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
775 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
776 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
777 if( usesetborder) {
778 rc=SystemParametersInfoA( SPI_SETBORDER, curr_val, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
779 if (!test_error_msg(rc,"SPI_SETBORDER")) return FALSE;
780 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
781 test_change_message( SPI_SETBORDER, 1 );
782 } else { /* set non client metrics */
783 ncm.iBorderWidth = curr_val;
784 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &ncm, SPIF_UPDATEINIFILE|
785 SPIF_SENDCHANGE);
786 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return FALSE;
787 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
788 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
790 if( curr_val) { /* skip if 0, some windows versions return 0 others 1 */
791 regval = metricfromreg( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_VALNAME, dpi);
792 if( regval != curr_val)
793 regval = metricfromreg( SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, dpi);
794 ok( regval==curr_val, "wrong value in registry %d, expected %d\n", regval, curr_val);
796 /* minimum border width is 1 */
797 if (curr_val == 0) curr_val = 1;
798 /* should be the same as the non client metrics */
799 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
800 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
801 eq( (UINT)ncm.iBorderWidth, curr_val, "NonClientMetric.iBorderWidth", "%d");
802 /* and from SPI_GETBORDER */
803 rc=SystemParametersInfoA( SPI_GETBORDER, 0, &border, 0 );
804 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
805 eq( border, curr_val, "SPI_{GET,SET}BORDER", "%d");
806 /* test some SystemMetrics */
807 frame = curr_val + GetSystemMetrics( SM_CXDLGFRAME );
808 eq( frame, GetSystemMetrics( SM_CXFRAME ), "SM_CXFRAME", "%d" );
809 eq( frame, GetSystemMetrics( SM_CYFRAME ), "SM_CYFRAME", "%d" );
810 eq( frame, GetSystemMetrics( SM_CXSIZEFRAME ), "SM_CXSIZEFRAME", "%d" );
811 eq( frame, GetSystemMetrics( SM_CYSIZEFRAME ), "SM_CYSIZEFRAME", "%d" );
812 return TRUE;
815 static void test_SPI_SETBORDER( void ) /* 6 */
817 BOOL rc;
818 UINT old_border;
819 NONCLIENTMETRICSA ncmsave;
820 INT CaptionWidth,
821 PaddedBorderWidth;
823 ncmsave.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
824 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncmsave, 0);
825 if( !rc) {
826 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
827 return;
829 /* CaptionWidth from the registry may have different value of iCaptionWidth
830 * from the non client metrics (observed on WinXP).
831 * Fix this so we can safely restore settings with the nonclientmetrics */
832 CaptionWidth = metricfromreg(
833 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
834 ncmsave.iCaptionWidth = CaptionWidth;
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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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=%ld\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 trace("testing SPI_{GET,SET}ICONTITLEWRAP\n");
1136 SetLastError(0xdeadbeef);
1137 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &old_b, 0 );
1138 if (!test_error_msg(rc,"SPI_{GET,SET}ICONTITLEWRAP"))
1139 return;
1141 for (i=0;i<ARRAY_SIZE(vals);i++)
1143 UINT v;
1144 UINT regval;
1146 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, vals[i], 0,
1147 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1148 if (!test_error_msg(rc,"SPI_SETICONTITLEWRAP")) return;
1149 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1150 test_change_message( SPI_SETICONTITLEWRAP, 1 );
1151 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2,
1152 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1153 if( regval != vals[i])
1154 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1,
1155 SPI_SETICONTITLEWRAP_VALNAME, dpi);
1156 ok( regval == vals[i], "wrong value in registry %d, expected %d\n", regval, vals[i] );
1158 rc=SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &v, 0 );
1159 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1160 eq( v, vals[i], "SPI_{GET,SET}ICONTITLEWRAP", "%d" );
1161 /* and test with what SPI_GETICONMETRICS returns */
1162 im.cbSize = sizeof(ICONMETRICSA);
1163 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im, FALSE );
1164 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1165 eq( im.iTitleWrap, (BOOL)vals[i], "SPI_GETICONMETRICS", "%d" );
1168 rc=SystemParametersInfoA( SPI_SETICONTITLEWRAP, old_b, 0, SPIF_UPDATEINIFILE );
1169 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1172 static void test_SPI_SETMENUDROPALIGNMENT( void ) /* 28 */
1174 BOOL rc;
1175 BOOL old_b;
1176 const UINT vals[]={TRUE,FALSE};
1177 unsigned int i;
1179 trace("testing SPI_{GET,SET}MENUDROPALIGNMENT\n");
1180 SetLastError(0xdeadbeef);
1181 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &old_b, 0 );
1182 if (!test_error_msg(rc,"SPI_{GET,SET}MENUDROPALIGNMENT"))
1183 return;
1185 for (i=0;i<ARRAY_SIZE(vals);i++)
1187 UINT v;
1189 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, vals[i], 0,
1190 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1191 if (!test_error_msg(rc,"SPI_SETMENUDROPALIGNMENT")) return;
1192 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1193 test_change_message( SPI_SETMENUDROPALIGNMENT, 0 );
1194 test_reg_key_ex( SPI_SETMENUDROPALIGNMENT_REGKEY1,
1195 SPI_SETMENUDROPALIGNMENT_REGKEY2,
1196 SPI_SETMENUDROPALIGNMENT_VALNAME,
1197 vals[i] ? "1" : "0" );
1199 rc=SystemParametersInfoA( SPI_GETMENUDROPALIGNMENT, 0, &v, 0 );
1200 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1201 eq( v, vals[i], "SPI_{GET,SET}MENUDROPALIGNMENT", "%d" );
1202 eq( GetSystemMetrics( SM_MENUDROPALIGNMENT ), (int)vals[i],
1203 "SM_MENUDROPALIGNMENT", "%d" );
1206 rc=SystemParametersInfoA( SPI_SETMENUDROPALIGNMENT, old_b, 0,
1207 SPIF_UPDATEINIFILE );
1208 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1209 flush_change_messages();
1212 static void test_SPI_SETDOUBLECLKWIDTH( void ) /* 29 */
1214 BOOL rc;
1215 INT old_width;
1216 const UINT vals[]={0,10000};
1217 unsigned int i;
1219 trace("testing SPI_{GET,SET}DOUBLECLKWIDTH\n");
1220 old_width = GetSystemMetrics( SM_CXDOUBLECLK );
1222 for (i=0;i<ARRAY_SIZE(vals);i++)
1224 char buf[10];
1226 SetLastError(0xdeadbeef);
1227 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, vals[i], 0,
1228 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1229 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKWIDTH"))
1230 return;
1232 test_change_message( SPI_SETDOUBLECLKWIDTH, 0 );
1233 sprintf( buf, "%d", vals[i] );
1234 test_reg_key_ex( SPI_SETDOUBLECLKWIDTH_REGKEY1,
1235 SPI_SETDOUBLECLKWIDTH_REGKEY2,
1236 SPI_SETDOUBLECLKWIDTH_VALNAME, buf );
1237 eq( GetSystemMetrics( SM_CXDOUBLECLK ), (int)vals[i],
1238 "SM_CXDOUBLECLK", "%d" );
1241 rc=SystemParametersInfoA( SPI_SETDOUBLECLKWIDTH, old_width, 0,
1242 SPIF_UPDATEINIFILE );
1243 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1246 static void test_SPI_SETDOUBLECLKHEIGHT( void ) /* 30 */
1248 BOOL rc;
1249 INT old_height;
1250 const UINT vals[]={0,10000};
1251 unsigned int i;
1253 trace("testing SPI_{GET,SET}DOUBLECLKHEIGHT\n");
1254 old_height = GetSystemMetrics( SM_CYDOUBLECLK );
1256 for (i=0;i<ARRAY_SIZE(vals);i++)
1258 char buf[10];
1260 SetLastError(0xdeadbeef);
1261 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, vals[i], 0,
1262 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1263 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLKHEIGHT"))
1264 return;
1266 test_change_message( SPI_SETDOUBLECLKHEIGHT, 0 );
1267 sprintf( buf, "%d", vals[i] );
1268 test_reg_key_ex( SPI_SETDOUBLECLKHEIGHT_REGKEY1,
1269 SPI_SETDOUBLECLKHEIGHT_REGKEY2,
1270 SPI_SETDOUBLECLKHEIGHT_VALNAME, buf );
1271 eq( GetSystemMetrics( SM_CYDOUBLECLK ), (int)vals[i],
1272 "SM_CYDOUBLECLK", "%d" );
1275 rc=SystemParametersInfoA( SPI_SETDOUBLECLKHEIGHT, old_height, 0,
1276 SPIF_UPDATEINIFILE );
1277 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1278 flush_change_messages();
1281 static void test_SPI_SETDOUBLECLICKTIME( void ) /* 32 */
1283 BOOL rc;
1284 UINT curr_val;
1285 UINT saved_val;
1286 UINT old_time;
1287 char buf[10];
1289 trace("testing SPI_{GET,SET}DOUBLECLICKTIME\n");
1290 old_time = GetDoubleClickTime();
1292 curr_val = 0;
1293 SetLastError(0xdeadbeef);
1294 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1295 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1296 if (!test_error_msg(rc,"SPI_{GET,SET}DOUBLECLICKTIME"))
1297 return;
1299 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1300 sprintf( buf, "%d", curr_val );
1301 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1302 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1303 curr_val = 500; /* used value for 0 */
1304 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1306 curr_val = 1000;
1307 rc=SystemParametersInfoA( SPI_SETDOUBLECLICKTIME, curr_val, 0,
1308 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1309 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1310 test_change_message( SPI_SETDOUBLECLICKTIME, 0 );
1311 sprintf( buf, "%d", curr_val );
1312 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1313 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1314 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1316 saved_val = curr_val;
1318 curr_val = 0;
1319 SetDoubleClickTime( curr_val );
1320 sprintf( buf, "%d", saved_val );
1321 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1322 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1323 curr_val = 500; /* used value for 0 */
1324 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1326 curr_val = 1000;
1327 SetDoubleClickTime( curr_val );
1328 sprintf( buf, "%d", saved_val );
1329 test_reg_key( SPI_SETDOUBLECLICKTIME_REGKEY,
1330 SPI_SETDOUBLECLICKTIME_VALNAME, buf );
1331 eq( GetDoubleClickTime(), curr_val, "GetDoubleClickTime", "%d" );
1333 rc=SystemParametersInfoA(SPI_SETDOUBLECLICKTIME, old_time, 0, SPIF_UPDATEINIFILE);
1334 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1335 flush_change_messages();
1338 static void test_SPI_SETMOUSEBUTTONSWAP( void ) /* 33 */
1340 BOOL rc;
1341 BOOL vals[2];
1342 unsigned int i;
1344 trace("testing SPI_{GET,SET}MOUSEBUTTONSWAP\n");
1345 vals[1] = GetSystemMetrics( SM_SWAPBUTTON );
1346 vals[0] = !vals[1];
1348 for (i=0;i<ARRAY_SIZE(vals);i++)
1350 SetLastError(0xdeadbeef);
1351 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[i], 0,
1352 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1353 if (!test_error_msg(rc,"SPI_SETMOUSEBUTTONSWAP")) break;
1355 test_change_message( SPI_SETMOUSEBUTTONSWAP, 0 );
1356 test_reg_key( SPI_SETMOUSEBUTTONSWAP_REGKEY,
1357 SPI_SETMOUSEBUTTONSWAP_VALNAME,
1358 vals[i] ? "1" : "0" );
1359 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i],
1360 "SM_SWAPBUTTON", "%d" );
1361 rc=SwapMouseButton((BOOL)vals[i^1]);
1362 eq( GetSystemMetrics( SM_SWAPBUTTON ), (int)vals[i^1],
1363 "SwapMouseButton", "%d" );
1364 ok( rc==(BOOL)vals[i], "SwapMouseButton does not return previous state (really %d)\n", rc );
1365 test_change_message( SPI_SETMOUSEBUTTONSWAP, 1 );
1368 rc=SystemParametersInfoA( SPI_SETMOUSEBUTTONSWAP, vals[1], 0,
1369 SPIF_UPDATEINIFILE );
1370 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1371 flush_change_messages();
1374 static void test_SPI_SETFASTTASKSWITCH( void ) /* 36 */
1376 BOOL rc;
1377 BOOL v;
1379 trace("testing SPI_GETFASTTASKSWITCH\n");
1380 SetLastError(0xdeadbeef);
1381 rc=SystemParametersInfoA( SPI_GETFASTTASKSWITCH, 0, &v, 0 );
1382 if (!test_error_msg(rc,"SPI_{GET,SET}FASTTASKSWITCH"))
1383 return;
1385 /* there is not a single Windows platform on which SPI_GETFASTTASKSWITCH
1386 * works. That sure simplifies testing!
1390 static void test_SPI_SETDRAGFULLWINDOWS( void ) /* 37 */
1392 BOOL rc;
1393 BOOL old_b;
1394 const UINT vals[]={TRUE,FALSE};
1395 unsigned int i;
1397 trace("testing SPI_{GET,SET}DRAGFULLWINDOWS\n");
1398 SetLastError(0xdeadbeef);
1399 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &old_b, 0 );
1401 /* SPI_{GET,SET}DRAGFULLWINDOWS is not implemented on Win95 */
1402 if (!test_error_msg(rc,"SPI_{GET,SET}DRAGFULLWINDOWS"))
1403 return;
1405 for (i=0;i<ARRAY_SIZE(vals);i++)
1407 UINT v;
1409 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, vals[i], 0,
1410 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1411 if (!test_error_msg(rc,"SPI_SETDRAGFULLWINDOWS")) return;
1412 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1413 test_change_message( SPI_SETDRAGFULLWINDOWS, 0 );
1414 test_reg_key( SPI_SETDRAGFULLWINDOWS_REGKEY,
1415 SPI_SETDRAGFULLWINDOWS_VALNAME,
1416 vals[i] ? "1" : "0" );
1418 rc=SystemParametersInfoA( SPI_GETDRAGFULLWINDOWS, 0, &v, 0 );
1419 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1420 eq( v, vals[i], "SPI_{GET,SET}DRAGFULLWINDOWS", "%d" );
1423 rc=SystemParametersInfoA( SPI_SETDRAGFULLWINDOWS, old_b, 0, SPIF_UPDATEINIFILE );
1424 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1425 flush_change_messages();
1428 #define test_reg_metric( KEY, VAL, val) do { \
1429 INT regval;\
1430 regval = metricfromreg( KEY, VAL, dpi);\
1431 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1432 } while(0)
1434 #define test_reg_metric2( KEY1, KEY2, VAL, val) do { \
1435 INT regval;\
1436 regval = metricfromreg( KEY1, VAL, dpi);\
1437 if( regval != val) regval = metricfromreg( KEY2, VAL, dpi);\
1438 ok( regval==val, "wrong value \"%s\" in registry %d, expected %d\n", VAL, regval, val);\
1439 } while(0)
1441 #define test_reg_font( KEY, VAL, LF) do { \
1442 LOGFONTA lfreg;\
1443 lffromreg( KEY, VAL, &lfreg);\
1444 ok( (lfreg.lfHeight < 0 ? (LF).lfHeight == MulDiv( lfreg.lfHeight, dpi, real_dpi ) : \
1445 MulDiv( -(LF).lfHeight , 72, dpi) == lfreg.lfHeight )&&\
1446 (LF).lfWidth == lfreg.lfWidth &&\
1447 (LF).lfWeight == lfreg.lfWeight &&\
1448 !strcmp( (LF).lfFaceName, lfreg.lfFaceName)\
1449 , "wrong value \"%s\" in registry %ld, %ld\n", VAL, (LF).lfHeight, lfreg.lfHeight);\
1450 } while(0)
1452 #define TEST_NONCLIENTMETRICS_REG( ncm) do { \
1453 /*FIXME: test_reg_metric2( SPI_SETBORDER_REGKEY2, SPI_SETBORDER_REGKEY, SPI_SETBORDER_VALNAME, (ncm).iBorderWidth);*/\
1454 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLWIDTH_VALNAME, (ncm).iScrollWidth);\
1455 test_reg_metric( SPI_METRIC_REGKEY, SPI_SCROLLHEIGHT_VALNAME, (ncm).iScrollHeight);\
1456 /*FIXME: test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, (ncm).iCaptionWidth);*/\
1457 test_reg_metric( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, (ncm).iCaptionHeight);\
1458 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONWIDTH_VALNAME, (ncm).iSmCaptionWidth);\
1459 test_reg_metric( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, (ncm).iSmCaptionHeight);\
1460 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUWIDTH_VALNAME, (ncm).iMenuWidth);\
1461 test_reg_metric( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, (ncm).iMenuHeight);\
1462 test_reg_font( SPI_METRIC_REGKEY, SPI_MENUFONT_VALNAME, (ncm).lfMenuFont);\
1463 test_reg_font( SPI_METRIC_REGKEY, SPI_CAPTIONFONT_VALNAME, (ncm).lfCaptionFont);\
1464 test_reg_font( SPI_METRIC_REGKEY, SPI_SMCAPTIONFONT_VALNAME, (ncm).lfSmCaptionFont);\
1465 test_reg_font( SPI_METRIC_REGKEY, SPI_STATUSFONT_VALNAME, (ncm).lfStatusFont);\
1466 test_reg_font( SPI_METRIC_REGKEY, SPI_MESSAGEFONT_VALNAME, (ncm).lfMessageFont); } while(0)
1468 /* get text metric height value for the specified logfont */
1469 static int get_tmheight( LOGFONTA *plf, int flag)
1471 TEXTMETRICA tm;
1472 HDC hdc = GetDC(0);
1473 HFONT hfont = CreateFontIndirectA( plf);
1474 hfont = SelectObject( hdc, hfont);
1475 GetTextMetricsA( hdc, &tm);
1476 hfont = SelectObject( hdc, hfont);
1477 ReleaseDC( 0, hdc );
1478 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1481 static int get_tmheightW( LOGFONTW *plf, int flag)
1483 TEXTMETRICW tm;
1484 HDC hdc = GetDC(0);
1485 HFONT hfont = CreateFontIndirectW( plf);
1486 hfont = SelectObject( hdc, hfont);
1487 GetTextMetricsW( hdc, &tm);
1488 hfont = SelectObject( hdc, hfont);
1489 ReleaseDC( 0, hdc );
1490 return tm.tmHeight + (flag ? tm.tmExternalLeading : 0);
1493 static void test_GetSystemMetrics( void);
1494 static UINT smcxsmsize = 999999999;
1496 static void test_SPI_SETNONCLIENTMETRICS( void ) /* 44 */
1498 BOOL rc;
1499 INT expect;
1500 NONCLIENTMETRICSA Ncmorig;
1501 NONCLIENTMETRICSA Ncmnew;
1502 NONCLIENTMETRICSA Ncmcur;
1503 NONCLIENTMETRICSA Ncmstart;
1505 Ncmorig.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1506 Ncmnew.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1507 Ncmcur.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1508 Ncmstart.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
1510 trace("testing SPI_{GET,SET}NONCLIENTMETRICS\n");
1511 change_counter = 0;
1512 SetLastError(0xdeadbeef);
1513 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmorig, FALSE );
1514 if (!test_error_msg(rc,"SPI_{GET,SET}NONCLIENTMETRICS"))
1515 return;
1516 Ncmstart = Ncmorig;
1517 smcxsmsize = Ncmstart.iSmCaptionWidth;
1518 /* SPI_GETNONCLIENTMETRICS returns some "cooked" values. For instance if
1519 the caption font height is higher than the CaptionHeight field,
1520 the latter is adjusted accordingly. To be able to restore these setting
1521 accurately we restore the raw values. */
1522 Ncmorig.iCaptionWidth = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONWIDTH_VALNAME, real_dpi);
1523 Ncmorig.iCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_CAPTIONHEIGHT_VALNAME, dpi);
1524 Ncmorig.iSmCaptionHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_SMCAPTIONHEIGHT_VALNAME, dpi);
1525 Ncmorig.iMenuHeight = metricfromreg( SPI_METRIC_REGKEY, SPI_MENUHEIGHT_VALNAME, dpi);
1526 /* test registry entries */
1527 TEST_NONCLIENTMETRICS_REG( Ncmorig);
1529 /* make small changes */
1530 Ncmnew = Ncmstart;
1531 Ncmnew.iBorderWidth += 1;
1532 Ncmnew.iScrollWidth += 1;
1533 Ncmnew.iScrollHeight -= 1;
1534 Ncmnew.iCaptionWidth -= 2;
1535 Ncmnew.iCaptionHeight += 2;
1536 Ncmnew.lfCaptionFont.lfHeight +=1;
1537 Ncmnew.lfCaptionFont.lfWidth +=2;
1538 Ncmnew.lfCaptionFont.lfWeight +=1;
1539 Ncmnew.iSmCaptionWidth += 1;
1540 Ncmnew.iSmCaptionHeight += 2;
1541 Ncmnew.lfSmCaptionFont.lfHeight +=3;
1542 Ncmnew.lfSmCaptionFont.lfWidth -=1;
1543 Ncmnew.lfSmCaptionFont.lfWeight +=3;
1544 Ncmnew.iMenuWidth += 1;
1545 Ncmnew.iMenuHeight += 2;
1546 Ncmnew.lfMenuFont.lfHeight +=1;
1547 Ncmnew.lfMenuFont.lfWidth +=1;
1548 Ncmnew.lfMenuFont.lfWeight +=2;
1549 Ncmnew.lfStatusFont.lfHeight -=1;
1550 Ncmnew.lfStatusFont.lfWidth -=1;
1551 Ncmnew.lfStatusFont.lfWeight +=3;
1552 Ncmnew.lfMessageFont.lfHeight -=2;
1553 Ncmnew.lfMessageFont.lfWidth -=1;
1554 Ncmnew.lfMessageFont.lfWeight +=4;
1556 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1557 SPIF_SENDCHANGE);
1558 if (!test_error_msg(rc,"SPI_SETNONCLIENTMETRICS")) return;
1559 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1560 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1561 /* get them back */
1562 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1563 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1564 /* test registry entries */
1565 TEST_NONCLIENTMETRICS_REG( Ncmcur );
1566 /* test the system metrics with these settings */
1567 test_GetSystemMetrics();
1568 /* now for something invalid: increase the {menu|caption|smcaption} fonts
1569 by a large amount will increase the {menu|caption|smcaption} height*/
1570 Ncmnew = Ncmstart;
1571 Ncmnew.lfMenuFont.lfHeight -= 8;
1572 Ncmnew.lfCaptionFont.lfHeight =-4;
1573 Ncmnew.lfSmCaptionFont.lfHeight -=10;
1574 /* also show that a few values are lo limited */
1575 Ncmnew.iCaptionWidth = 0;
1576 Ncmnew.iCaptionHeight = 0;
1577 Ncmnew.iScrollHeight = 0;
1578 Ncmnew.iScrollWidth = 0;
1580 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, 0, &Ncmnew, SPIF_UPDATEINIFILE|
1581 SPIF_SENDCHANGE);
1582 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1583 test_change_message( SPI_SETNONCLIENTMETRICS, 1 );
1584 /* raw values are in registry */
1585 TEST_NONCLIENTMETRICS_REG( Ncmnew );
1586 /* get them back */
1587 rc=SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA), &Ncmcur, FALSE );
1588 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1589 /* cooked values are returned */
1590 expect = max( Ncmnew.iMenuHeight, 2 + get_tmheight( &Ncmnew.lfMenuFont, 1));
1591 ok( Ncmcur.iMenuHeight == expect,
1592 "MenuHeight: %d expected %d\n", Ncmcur.iMenuHeight, expect);
1593 expect = max( Ncmnew.iCaptionHeight, 2 + get_tmheight(&Ncmnew.lfCaptionFont, 0));
1594 ok( Ncmcur.iCaptionHeight == expect,
1595 "CaptionHeight: %d expected %d\n", Ncmcur.iCaptionHeight, expect);
1596 expect = max( Ncmnew.iSmCaptionHeight, 2 + get_tmheight( &Ncmnew.lfSmCaptionFont, 0));
1597 ok( Ncmcur.iSmCaptionHeight == expect,
1598 "SmCaptionHeight: %d expected %d\n", Ncmcur.iSmCaptionHeight, expect);
1600 /* iCaptionWidth depends on a version, could be 8, 12 (Vista, Win7), 13 */
1601 ok( (Ncmcur.iCaptionWidth >= 8 && Ncmcur.iCaptionWidth <= 13) ||
1602 Ncmcur.iCaptionWidth == Ncmstart.iCaptionWidth, /* with windows XP theme, the value never changes */
1603 "CaptionWidth: %d expected from [8, 13] or %d\n", Ncmcur.iCaptionWidth, Ncmstart.iCaptionWidth);
1604 ok( Ncmcur.iScrollWidth == 8,
1605 "ScrollWidth: %d expected 8\n", Ncmcur.iScrollWidth);
1606 ok( Ncmcur.iScrollHeight == 8,
1607 "ScrollHeight: %d expected 8\n", Ncmcur.iScrollHeight);
1608 /* test the system metrics with these settings */
1609 test_GetSystemMetrics();
1610 /* restore */
1611 rc=SystemParametersInfoA( SPI_SETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSA),
1612 &Ncmorig, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
1613 test_change_message( SPI_SETNONCLIENTMETRICS, 0 );
1614 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1615 flush_change_messages();
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=%ld\n", rc, GetLastError());
1661 /* read them back */
1662 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1663 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\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=%ld\n", rc, GetLastError());
1699 /* read back */
1700 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1701 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\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=%ld\n", rc, GetLastError());
1737 flush_change_messages();
1738 /* check that */
1739 rc=SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, sizeof(MINIMIZEDMETRICS), &lpMm_new, FALSE );
1740 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1741 eq( lpMm_new.iWidth, lpMm_orig.iWidth, "iWidth", "%d" );
1742 eq( lpMm_new.iHorzGap, lpMm_orig.iHorzGap, "iHorzGap", "%d" );
1743 eq( lpMm_new.iVertGap, lpMm_orig.iVertGap, "iVertGap", "%d" );
1744 eq( lpMm_new.iArrange, lpMm_orig.iArrange, "iArrange", "%d" );
1747 static void test_SPI_SETICONMETRICS( void ) /* 46 */
1749 BOOL rc, wrap;
1750 INT spacing;
1751 ICONMETRICSA im_orig;
1752 ICONMETRICSA im_new;
1753 ICONMETRICSA im_cur;
1754 INT regval;
1756 im_orig.cbSize = sizeof(ICONMETRICSA);
1757 im_new.cbSize = sizeof(ICONMETRICSA);
1758 im_cur.cbSize = sizeof(ICONMETRICSA);
1760 trace("testing SPI_{GET,SET}ICONMETRICS\n");
1761 SetLastError(0xdeadbeef);
1762 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_orig, FALSE );
1763 if (!test_error_msg(rc,"SPI_{GET,SET}ICONMETRICS"))
1764 return;
1765 /* check some registry values */
1766 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1767 ok( regval==im_orig.iHorzSpacing,
1768 "wrong value in registry %d, expected %d\n", regval, im_orig.iHorzSpacing);
1769 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1770 ok( regval==im_orig.iVertSpacing,
1771 "wrong value in registry %d, expected %d\n", regval, im_orig.iVertSpacing);
1772 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1773 if( regval != im_orig.iTitleWrap)
1774 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1775 ok( regval==im_orig.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_orig.iTitleWrap);
1777 /* change everything without creating something invalid ( Win9x would ignore
1778 * an invalid font for instance) */
1779 im_cur = im_orig;
1780 im_cur.iHorzSpacing += 10;
1781 im_cur.iVertSpacing += 6;
1782 im_cur.iTitleWrap = !im_cur.iTitleWrap;
1783 im_cur.lfFont.lfHeight += 1;
1784 im_cur.lfFont.lfWidth += 2;
1785 im_cur.lfFont.lfEscapement = 1;
1786 im_cur.lfFont.lfWeight = im_cur.lfFont.lfWeight > 100 ? 1 : 314;
1787 im_cur.lfFont.lfItalic = !im_cur.lfFont.lfItalic;
1788 im_cur.lfFont.lfStrikeOut = !im_cur.lfFont.lfStrikeOut;
1789 im_cur.lfFont.lfUnderline = !im_cur.lfFont.lfUnderline;
1790 im_cur.lfFont.lfCharSet = im_cur.lfFont.lfCharSet ? 0 : 1;
1791 im_cur.lfFont.lfOutPrecision = im_cur.lfFont.lfOutPrecision == OUT_DEFAULT_PRECIS ?
1792 OUT_TT_PRECIS : OUT_DEFAULT_PRECIS;
1793 im_cur.lfFont.lfClipPrecision ^= CLIP_LH_ANGLES;
1794 im_cur.lfFont.lfPitchAndFamily = im_cur.lfFont.lfPitchAndFamily ? 0 : 1;
1795 im_cur.lfFont.lfQuality = im_cur.lfFont.lfQuality == DEFAULT_QUALITY ?
1796 DRAFT_QUALITY : DEFAULT_QUALITY;
1797 if( strcmp( im_cur.lfFont.lfFaceName, "MS Serif"))
1798 strcpy( im_cur.lfFont.lfFaceName, "MS Serif");
1799 else
1800 strcpy( im_cur.lfFont.lfFaceName, "MS Sans Serif");
1802 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_cur, SPIF_UPDATEINIFILE );
1803 if (!test_error_msg(rc,"SPI_SETICONMETRICS")) return;
1804 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1806 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1807 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1808 /* test GET <-> SETICONMETRICS */
1809 eq( im_new.iHorzSpacing, im_cur.iHorzSpacing, "iHorzSpacing", "%d" );
1810 eq( im_new.iVertSpacing, im_cur.iVertSpacing, "iVertSpacing", "%d" );
1811 eq( im_new.iTitleWrap, im_cur.iTitleWrap, "iTitleWrap", "%d" );
1812 eq( im_new.lfFont.lfHeight, im_cur.lfFont.lfHeight, "lfHeight", "%ld" );
1813 eq( im_new.lfFont.lfWidth, im_cur.lfFont.lfWidth, "lfWidth", "%ld" );
1814 eq( im_new.lfFont.lfEscapement, im_cur.lfFont.lfEscapement, "lfEscapement", "%ld" );
1815 eq( im_new.lfFont.lfWeight, im_cur.lfFont.lfWeight, "lfWeight", "%ld" );
1816 eq( im_new.lfFont.lfItalic, im_cur.lfFont.lfItalic, "lfItalic", "%d" );
1817 eq( im_new.lfFont.lfStrikeOut, im_cur.lfFont.lfStrikeOut, "lfStrikeOut", "%d" );
1818 eq( im_new.lfFont.lfUnderline, im_cur.lfFont.lfUnderline, "lfUnderline", "%d" );
1819 eq( im_new.lfFont.lfCharSet, im_cur.lfFont.lfCharSet, "lfCharSet", "%d" );
1820 eq( im_new.lfFont.lfOutPrecision, im_cur.lfFont.lfOutPrecision, "lfOutPrecision", "%d" );
1821 eq( im_new.lfFont.lfClipPrecision, im_cur.lfFont.lfClipPrecision, "lfClipPrecision", "%d" );
1822 eq( im_new.lfFont.lfPitchAndFamily, im_cur.lfFont.lfPitchAndFamily, "lfPitchAndFamily", "%d" );
1823 eq( im_new.lfFont.lfQuality, im_cur.lfFont.lfQuality, "lfQuality", "%d" );
1824 ok( !strcmp( im_new.lfFont.lfFaceName, im_cur.lfFont.lfFaceName),
1825 "wrong facename \"%s\", should be \"%s\"\n", im_new.lfFont.lfFaceName,
1826 im_cur.lfFont.lfFaceName);
1827 /* test some system metrics */
1828 eq( GetSystemMetrics( SM_CXICONSPACING ),
1829 im_new.iHorzSpacing, "iHorzSpacing", "%d" );
1830 eq( GetSystemMetrics( SM_CYICONSPACING ),
1831 im_new.iVertSpacing, "iVertSpacing", "%d" );
1832 /* check some registry values */
1833 regval = metricfromreg( SPI_ICONHORIZONTALSPACING_REGKEY, SPI_ICONHORIZONTALSPACING_VALNAME, dpi);
1834 ok( regval==im_cur.iHorzSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iHorzSpacing);
1835 regval = metricfromreg( SPI_ICONVERTICALSPACING_REGKEY, SPI_ICONVERTICALSPACING_VALNAME, dpi);
1836 ok( regval==im_cur.iVertSpacing, "wrong value in registry %d, expected %d\n", regval, im_cur.iVertSpacing);
1837 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY2, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1838 if( regval != im_cur.iTitleWrap)
1839 regval = metricfromreg( SPI_SETICONTITLEWRAP_REGKEY1, SPI_SETICONTITLEWRAP_VALNAME, dpi);
1840 ok( regval==im_cur.iTitleWrap, "wrong value in registry %d, expected %d\n", regval, im_cur.iTitleWrap);
1841 /* test some values from other SPI_GETxxx calls */
1842 rc = SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &spacing, 0 );
1843 ok( rc && spacing == im_cur.iHorzSpacing,
1844 "SystemParametersInfoA( SPI_ICONHORIZONTALSPACING...) failed or returns wrong value %d instead of %d\n",
1845 spacing, im_cur.iHorzSpacing);
1846 rc = SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &spacing, 0 );
1847 ok( rc && spacing == im_cur.iVertSpacing,
1848 "SystemParametersInfoA( SPI_ICONVERTICALSPACING...) failed or returns wrong value %d instead of %d\n",
1849 spacing, im_cur.iVertSpacing);
1850 rc = SystemParametersInfoA( SPI_GETICONTITLEWRAP, 0, &wrap, 0 );
1851 ok( rc && wrap == im_cur.iTitleWrap,
1852 "SystemParametersInfoA( SPI_GETICONTITLEWRAP...) failed or returns wrong value %d instead of %d\n",
1853 wrap, im_cur.iTitleWrap);
1854 /* restore old values */
1855 rc=SystemParametersInfoA( SPI_SETICONMETRICS, sizeof(ICONMETRICSA), &im_orig,SPIF_UPDATEINIFILE );
1856 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1857 flush_change_messages();
1859 rc=SystemParametersInfoA( SPI_GETICONMETRICS, sizeof(ICONMETRICSA), &im_new, FALSE );
1860 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1862 eq( im_new.iHorzSpacing, im_orig.iHorzSpacing, "iHorzSpacing", "%d" );
1863 eq( im_new.iVertSpacing, im_orig.iVertSpacing, "iVertSpacing", "%d" );
1864 eq( im_new.iTitleWrap, im_orig.iTitleWrap, "iTitleWrap", "%d" );
1867 static void test_SPI_SETWORKAREA( void ) /* 47 */
1869 BOOL rc;
1870 RECT old_area;
1871 RECT area;
1872 RECT curr_val;
1874 trace("testing SPI_{GET,SET}WORKAREA\n");
1875 SetLastError(0xdeadbeef);
1876 rc=SystemParametersInfoA(SPI_GETWORKAREA, 0, &old_area, 0);
1877 if (!test_error_msg(rc,"SPI_{GET,SET}WORKAREA"))
1878 return;
1880 /* Modify the work area only minimally as this causes the icons that
1881 * fall outside it to be moved around thus requiring the user to
1882 * reposition them manually one by one.
1883 * Changing the work area by just one pixel should make this occurrence
1884 * reasonably unlikely.
1886 SetRect(&curr_val, old_area.left, old_area.top, old_area.right - 1, old_area.bottom - 1);
1887 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &curr_val,
1888 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1889 if (!test_error_msg(rc,"SPI_SETWORKAREA")) return;
1890 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1891 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1892 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1893 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1894 test_change_message( SPI_SETWORKAREA, 0);
1895 eq( area.left, curr_val.left, "left", "%ld" );
1896 eq( area.top, curr_val.top, "top", "%ld" );
1897 /* size may be rounded */
1898 ok( area.right >= curr_val.right - 16 && area.right < curr_val.right + 16,
1899 "right: got %ld instead of %ld\n", area.right, curr_val.right );
1900 ok( area.bottom >= curr_val.bottom - 16 && area.bottom < curr_val.bottom + 16,
1901 "bottom: got %ld instead of %ld\n", area.bottom, curr_val.bottom );
1902 curr_val = area;
1903 rc=SystemParametersInfoA( SPI_SETWORKAREA, 0, &old_area,
1904 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1905 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1906 rc=SystemParametersInfoA( SPI_GETWORKAREA, 0, &area, 0 );
1907 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
1908 if( !EqualRect( &area, &curr_val)) /* no message if rect has not changed */
1909 test_change_message( SPI_SETWORKAREA, 0 );
1910 eq( area.left, old_area.left, "left", "%ld" );
1911 eq( area.top, old_area.top, "top", "%ld" );
1912 /* size may be rounded */
1913 ok( area.right >= old_area.right - 16 && area.right < old_area.right + 16,
1914 "right: got %ld instead of %ld\n", area.right, old_area.right );
1915 ok( area.bottom >= old_area.bottom - 16 && area.bottom < old_area.bottom + 16,
1916 "bottom: got %ld instead of %ld\n", area.bottom, old_area.bottom );
1917 flush_change_messages();
1920 static void test_SPI_SETSHOWSOUNDS( void ) /* 57 */
1922 BOOL rc;
1923 BOOL old_b;
1924 const UINT vals[]={TRUE,FALSE};
1925 unsigned int i;
1927 trace("testing SPI_{GET,SET}SHOWSOUNDS\n");
1928 SetLastError(0xdeadbeef);
1929 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &old_b, 0 );
1930 if (!test_error_msg(rc,"SPI_{GET,SET}SHOWSOUNDS"))
1931 return;
1933 for (i=0;i<ARRAY_SIZE(vals);i++)
1935 UINT v;
1937 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, vals[i], 0,
1938 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1939 if (!test_error_msg(rc,"SPI_SETSHOWSOUNDS")) return;
1940 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1941 test_change_message( SPI_SETSHOWSOUNDS, 1 );
1942 test_reg_key( SPI_SETSHOWSOUNDS_REGKEY,
1943 SPI_SETSHOWSOUNDS_VALNAME,
1944 vals[i] ? "1" : "0" );
1946 rc=SystemParametersInfoA( SPI_GETSHOWSOUNDS, 0, &v, 0 );
1947 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1948 eq( v, vals[i], "SPI_GETSHOWSOUNDS", "%d" );
1949 eq( GetSystemMetrics( SM_SHOWSOUNDS ), (int)vals[i],
1950 "SM_SHOWSOUNDS", "%d" );
1953 rc=SystemParametersInfoA( SPI_SETSHOWSOUNDS, old_b, 0, SPIF_UPDATEINIFILE );
1954 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1955 flush_change_messages();
1958 static void test_SPI_SETKEYBOARDPREF( void ) /* 69 */
1960 BOOL rc;
1961 BOOL vals[2];
1962 unsigned int i;
1964 trace("testing SPI_{GET,SET}KEYBOARDPREF\n");
1965 SetLastError(0xdeadbeef);
1966 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &vals[1], 0 );
1967 if (!test_error_msg(rc,"SPI_{GET,SET}KEYBOARDPREF"))
1968 return;
1969 vals[0] = !vals[1];
1971 for (i=0;i<ARRAY_SIZE(vals);i++)
1973 BOOL v;
1975 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[i], 0,
1976 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
1977 if (!test_error_msg(rc,"SPI_SETKEYBOARDPREF")) break;
1978 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1979 test_change_message( SPI_SETKEYBOARDPREF, 1 );
1980 test_reg_key_ex2( SPI_SETKEYBOARDPREF_REGKEY, SPI_SETKEYBOARDPREF_REGKEY_LEGACY,
1981 SPI_SETKEYBOARDPREF_VALNAME, SPI_SETKEYBOARDPREF_VALNAME_LEGACY,
1982 vals[i] ? "1" : "0" );
1984 rc=SystemParametersInfoA( SPI_GETKEYBOARDPREF, 0, &v, 0 );
1985 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
1986 eq( v, (BOOL)vals[i], "SPI_GETKEYBOARDPREF", "%d" );
1989 rc=SystemParametersInfoA( SPI_SETKEYBOARDPREF, vals[1], 0, SPIF_UPDATEINIFILE );
1990 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
1991 flush_change_messages();
1994 static void test_SPI_SETSCREENREADER( void ) /* 71 */
1996 BOOL rc;
1997 BOOL old_b;
1998 const UINT vals[]={TRUE,FALSE};
1999 unsigned int i;
2001 trace("testing SPI_{GET,SET}SCREENREADER\n");
2002 SetLastError(0xdeadbeef);
2003 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &old_b, 0 );
2004 if (!test_error_msg(rc,"SPI_{GET,SET}SCREENREADER"))
2005 return;
2007 for (i=0;i<ARRAY_SIZE(vals);i++)
2009 BOOL v;
2011 rc=SystemParametersInfoA( SPI_SETSCREENREADER, vals[i], 0,
2012 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2013 if (!test_error_msg(rc,"SPI_SETSCREENREADER")) return;
2014 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2015 test_change_message( SPI_SETSCREENREADER, 1 );
2016 test_reg_key_ex2_optional( SPI_SETSCREENREADER_REGKEY, SPI_SETSCREENREADER_REGKEY_LEGACY,
2017 SPI_SETSCREENREADER_VALNAME, SPI_SETSCREENREADER_VALNAME_LEGACY,
2018 vals[i] ? "1" : "0" );
2020 rc=SystemParametersInfoA( SPI_GETSCREENREADER, 0, &v, 0 );
2021 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2022 eq( v, (BOOL)vals[i], "SPI_GETSCREENREADER", "%d" );
2025 rc=SystemParametersInfoA( SPI_SETSCREENREADER, old_b, 0, SPIF_UPDATEINIFILE );
2026 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2027 flush_change_messages();
2030 static void test_SPI_SETFONTSMOOTHING( void ) /* 75 */
2032 BOOL rc;
2033 BOOL old_b;
2034 DWORD old_type, old_contrast, old_orient;
2035 const UINT vals[]={0xffffffff,0,1,2};
2036 unsigned int i;
2038 trace("testing SPI_{GET,SET}FONTSMOOTHING\n");
2039 SetLastError(0xdeadbeef);
2040 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &old_b, 0 );
2041 if (!test_error_msg(rc,"SPI_{GET,SET}FONTSMOOTHING"))
2042 return;
2043 SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &old_type, 0 );
2044 SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &old_contrast, 0 );
2045 SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &old_orient, 0 );
2047 for (i=0;i<ARRAY_SIZE(vals);i++)
2049 UINT v;
2051 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, vals[i], 0,
2052 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2053 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHING")) return;
2054 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2055 test_change_message( SPI_SETFONTSMOOTHING, 0 );
2056 test_reg_key( SPI_SETFONTSMOOTHING_REGKEY,
2057 SPI_SETFONTSMOOTHING_VALNAME,
2058 vals[i] ? "2" : "0" );
2060 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, 0, UlongToPtr(vals[i]),
2061 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2062 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGTYPE")) return;
2063 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2064 test_change_message( SPI_SETFONTSMOOTHINGTYPE, 0 );
2065 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2066 SPI_SETFONTSMOOTHINGTYPE_VALNAME, &vals[i] );
2068 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, 0, UlongToPtr(vals[i]),
2069 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2070 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGCONTRAST")) return;
2071 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2072 test_change_message( SPI_SETFONTSMOOTHINGCONTRAST, 0 );
2073 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2074 SPI_SETFONTSMOOTHINGCONTRAST_VALNAME, &vals[i] );
2076 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, 0, UlongToPtr(vals[i]),
2077 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2078 if (!test_error_msg(rc,"SPI_SETFONTSMOOTHINGORIENTATION")) return;
2079 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2080 test_change_message( SPI_SETFONTSMOOTHINGORIENTATION, 0 );
2081 test_reg_key_dword( SPI_SETFONTSMOOTHING_REGKEY,
2082 SPI_SETFONTSMOOTHINGORIENTATION_VALNAME, &vals[i] );
2084 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHING, 0, &v, 0 );
2085 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2086 eq( v, vals[i] ? 1 : 0, "SPI_GETFONTSMOOTHING", "%d" );
2088 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGTYPE, 0, &v, 0 );
2089 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2090 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2092 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGCONTRAST, 0, &v, 0 );
2093 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2094 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2096 rc=SystemParametersInfoA( SPI_GETFONTSMOOTHINGORIENTATION, 0, &v, 0 );
2097 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2098 ok( v == vals[i], "wrong value %x/%x\n", v, vals[i] );
2101 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHING, old_b, 0, SPIF_UPDATEINIFILE );
2102 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2103 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGTYPE, old_type, 0, SPIF_UPDATEINIFILE );
2104 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2105 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGCONTRAST, old_contrast, 0, SPIF_UPDATEINIFILE );
2106 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2107 rc=SystemParametersInfoA( SPI_SETFONTSMOOTHINGORIENTATION, old_orient, 0, SPIF_UPDATEINIFILE );
2108 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2109 flush_change_messages();
2112 static void test_SPI_SETLOWPOWERACTIVE( void ) /* 85 */
2114 BOOL rc;
2115 BOOL old_b;
2116 const UINT vals[]={TRUE,FALSE};
2117 unsigned int i;
2119 trace("testing SPI_{GET,SET}LOWPOWERACTIVE\n");
2120 SetLastError(0xdeadbeef);
2121 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &old_b, 0 );
2122 if (!test_error_msg(rc,"SPI_{GET,SET}LOWPOWERACTIVE"))
2123 return;
2125 for (i=0;i<ARRAY_SIZE(vals);i++)
2127 UINT v;
2129 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, vals[i], 0,
2130 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2131 if (!test_error_msg(rc,"SPI_SETLOWPOWERACTIVE")) return;
2132 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2133 test_change_message( SPI_SETLOWPOWERACTIVE, 1 );
2134 test_reg_key_optional( SPI_SETLOWPOWERACTIVE_REGKEY,
2135 SPI_SETLOWPOWERACTIVE_VALNAME,
2136 vals[i] ? "1" : "0" );
2138 /* SPI_SETLOWPOWERACTIVE is not persistent in win2k3 and above */
2139 v = 0xdeadbeef;
2140 rc=SystemParametersInfoA( SPI_GETLOWPOWERACTIVE, 0, &v, 0 );
2141 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2142 ok(v == vals[i] || v == 0, /* win2k3 */
2143 "SPI_GETLOWPOWERACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2146 rc=SystemParametersInfoA( SPI_SETLOWPOWERACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2147 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2148 flush_change_messages();
2151 static void test_SPI_SETPOWEROFFACTIVE( void ) /* 86 */
2153 BOOL rc;
2154 BOOL old_b;
2155 const UINT vals[]={TRUE,FALSE};
2156 unsigned int i;
2158 trace("testing SPI_{GET,SET}POWEROFFACTIVE\n");
2159 SetLastError(0xdeadbeef);
2160 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &old_b, 0 );
2161 if (!test_error_msg(rc,"SPI_{GET,SET}POWEROFFACTIVE"))
2162 return;
2164 for (i=0;i<ARRAY_SIZE(vals);i++)
2166 UINT v;
2168 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, vals[i], 0,
2169 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2170 if (!test_error_msg(rc,"SPI_SETPOWEROFFACTIVE")) return;
2171 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2172 test_change_message( SPI_SETPOWEROFFACTIVE, 1 );
2173 test_reg_key_optional( SPI_SETPOWEROFFACTIVE_REGKEY,
2174 SPI_SETPOWEROFFACTIVE_VALNAME,
2175 vals[i] ? "1" : "0" );
2177 /* SPI_SETPOWEROFFACTIVE is not persistent in win2k3 and above */
2178 v = 0xdeadbeef;
2179 rc=SystemParametersInfoA( SPI_GETPOWEROFFACTIVE, 0, &v, 0 );
2180 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2181 ok(v == vals[i] || v == 0, /* win2k3 */
2182 "SPI_GETPOWEROFFACTIVE: got %d instead of 0 or %d\n", v, vals[i]);
2185 rc=SystemParametersInfoA( SPI_SETPOWEROFFACTIVE, old_b, 0, SPIF_UPDATEINIFILE );
2186 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2187 flush_change_messages();
2190 static void test_SPI_SETSNAPTODEFBUTTON( void ) /* 95 */
2192 BOOL rc;
2193 BOOL old_b;
2194 const UINT vals[]={TRUE,FALSE};
2195 unsigned int i;
2197 trace("testing SPI_{GET,SET}SNAPTODEFBUTTON\n");
2198 SetLastError(0xdeadbeef);
2199 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &old_b, 0 );
2200 if (!test_error_msg(rc,"SPI_GETSNAPTODEFBUTTON"))
2201 return;
2203 for (i=0;i<ARRAY_SIZE(vals);i++)
2205 UINT v;
2207 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, vals[i], 0,
2208 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2209 if (!test_error_msg(rc,"SPI_SETSNAPTODEFBUTTON")) return;
2210 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2211 test_change_message( SPI_SETSNAPTODEFBUTTON, 0 );
2212 test_reg_key_optional( SPI_SETSNAPTODEFBUTTON_REGKEY,
2213 SPI_SETSNAPTODEFBUTTON_VALNAME,
2214 vals[i] ? "1" : "0" );
2216 rc=SystemParametersInfoA( SPI_GETSNAPTODEFBUTTON, 0, &v, 0 );
2217 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2218 eq( v, vals[i], "SPI_GETSNAPTODEFBUTTON", "%d" );
2221 rc=SystemParametersInfoA( SPI_SETSNAPTODEFBUTTON, old_b, 0, SPIF_UPDATEINIFILE );
2222 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2223 flush_change_messages();
2226 static void test_SPI_SETMOUSEHOVERWIDTH( void ) /* 99 */
2228 BOOL rc;
2229 UINT old_width;
2230 const UINT vals[]={0,32767};
2231 unsigned int i;
2233 trace("testing SPI_{GET,SET}MOUSEHOVERWIDTH\n");
2234 SetLastError(0xdeadbeef);
2235 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &old_width, 0 );
2236 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERWIDTH"))
2237 return;
2239 for (i=0;i<ARRAY_SIZE(vals);i++)
2241 UINT v;
2242 char buf[10];
2244 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, vals[i], 0,
2245 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2246 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERWIDTH")) return;
2247 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2248 test_change_message( SPI_SETMOUSEHOVERWIDTH, 0 );
2249 sprintf( buf, "%d", vals[i] );
2250 test_reg_key( SPI_SETMOUSEHOVERWIDTH_REGKEY,
2251 SPI_SETMOUSEHOVERWIDTH_VALNAME, buf );
2253 SystemParametersInfoA( SPI_GETMOUSEHOVERWIDTH, 0, &v, 0 );
2254 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2255 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERWIDTH", "%d" );
2258 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERWIDTH, old_width, 0,
2259 SPIF_UPDATEINIFILE );
2260 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2261 flush_change_messages();
2264 static void test_SPI_SETMOUSEHOVERHEIGHT( void ) /* 101 */
2266 BOOL rc;
2267 UINT old_height;
2268 const UINT vals[]={0,32767};
2269 unsigned int i;
2271 trace("testing SPI_{GET,SET}MOUSEHOVERHEIGHT\n");
2272 SetLastError(0xdeadbeef);
2273 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &old_height, 0 );
2274 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERHEIGHT"))
2275 return;
2277 for (i=0;i<ARRAY_SIZE(vals);i++)
2279 UINT v;
2280 char buf[10];
2282 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, vals[i], 0,
2283 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2284 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERHEIGHT")) return;
2285 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2286 test_change_message( SPI_SETMOUSEHOVERHEIGHT, 0 );
2287 sprintf( buf, "%d", vals[i] );
2288 test_reg_key( SPI_SETMOUSEHOVERHEIGHT_REGKEY,
2289 SPI_SETMOUSEHOVERHEIGHT_VALNAME, buf );
2291 SystemParametersInfoA( SPI_GETMOUSEHOVERHEIGHT, 0, &v, 0 );
2292 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2293 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERHEIGHT", "%d" );
2296 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERHEIGHT, old_height, 0,
2297 SPIF_UPDATEINIFILE );
2298 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2299 flush_change_messages();
2302 static void test_SPI_SETMOUSEHOVERTIME( void ) /* 103 */
2304 BOOL rc;
2305 UINT old_time;
2307 /* Windows XP accepts 10 as the minimum hover time. Any value below will be
2308 * defaulted to a value of 10 automatically.
2310 const UINT vals[]={10,32767};
2311 unsigned int i;
2313 trace("testing SPI_{GET,SET}MOUSEHOVERTIME\n");
2314 SetLastError(0xdeadbeef);
2315 rc=SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &old_time, 0 );
2316 if (!test_error_msg(rc,"SPI_{GET,SET}MOUSEHOVERTIME"))
2317 return;
2319 for (i=0;i<ARRAY_SIZE(vals);i++)
2321 UINT v;
2322 char buf[10];
2324 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, vals[i], 0,
2325 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2326 if (!test_error_msg(rc,"SPI_SETMOUSEHOVERTIME")) return;
2327 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2328 test_change_message( SPI_SETMOUSEHOVERTIME, 0 );
2329 sprintf( buf, "%d", vals[i] );
2330 test_reg_key( SPI_SETMOUSEHOVERTIME_REGKEY,
2331 SPI_SETMOUSEHOVERTIME_VALNAME, buf );
2333 SystemParametersInfoA( SPI_GETMOUSEHOVERTIME, 0, &v, 0 );
2334 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2335 eq( v, vals[i], "SPI_{GET,SET}MOUSEHOVERTIME", "%d" );
2338 rc=SystemParametersInfoA( SPI_SETMOUSEHOVERTIME, old_time, 0,
2339 SPIF_UPDATEINIFILE );
2340 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2341 flush_change_messages();
2344 static void test_SPI_SETWHEELSCROLLLINES( void ) /* 105 */
2346 BOOL rc;
2347 UINT old_lines;
2348 const UINT vals[]={0,32767};
2349 unsigned int i;
2351 trace("testing SPI_{GET,SET}WHEELSCROLLLINES\n");
2352 SetLastError(0xdeadbeef);
2353 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &old_lines, 0 );
2355 /* SPI_{GET,SET}WHEELSCROLLLINES not supported on Windows 95 */
2356 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLLINES"))
2357 return;
2359 for (i=0;i<ARRAY_SIZE(vals);i++)
2361 UINT v;
2362 char buf[10];
2364 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, vals[i], 0,
2365 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2366 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLLINES")) return;
2367 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2368 test_change_message( SPI_SETWHEELSCROLLLINES, 0 );
2369 sprintf( buf, "%d", vals[i] );
2370 test_reg_key( SPI_SETMOUSESCROLLLINES_REGKEY,
2371 SPI_SETMOUSESCROLLLINES_VALNAME, buf );
2373 SystemParametersInfoA( SPI_GETWHEELSCROLLLINES, 0, &v, 0 );
2374 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2375 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLLINES", "%d" );
2378 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLLINES, old_lines, 0,
2379 SPIF_UPDATEINIFILE );
2380 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2381 flush_change_messages();
2384 static void test_SPI_SETMENUSHOWDELAY( void ) /* 107 */
2386 BOOL rc;
2387 UINT old_delay;
2388 const UINT vals[]={0,32767};
2389 unsigned int i;
2391 trace("testing SPI_{GET,SET}MENUSHOWDELAY\n");
2392 SetLastError(0xdeadbeef);
2393 rc=SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &old_delay, 0 );
2395 /* SPI_{GET,SET}MENUSHOWDELAY not supported on Windows 95 */
2396 if (!test_error_msg(rc,"SPI_{GET,SET}MENUSHOWDELAY"))
2397 return;
2399 for (i=0;i<ARRAY_SIZE(vals);i++)
2401 UINT v;
2402 char buf[10];
2404 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, vals[i], 0,
2405 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2406 if (!test_error_msg(rc,"SPI_SETMENUSHOWDELAY")) return;
2407 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2408 test_change_message( SPI_SETMENUSHOWDELAY, 0 );
2409 sprintf( buf, "%d", vals[i] );
2410 test_reg_key( SPI_SETMENUSHOWDELAY_REGKEY,
2411 SPI_SETMENUSHOWDELAY_VALNAME, buf );
2413 SystemParametersInfoA( SPI_GETMENUSHOWDELAY, 0, &v, 0 );
2414 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2415 eq( v, vals[i], "SPI_{GET,SET}MENUSHOWDELAY", "%d" );
2418 rc=SystemParametersInfoA( SPI_SETMENUSHOWDELAY, old_delay, 0,
2419 SPIF_UPDATEINIFILE );
2420 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2421 flush_change_messages();
2424 static void test_SPI_SETWHEELSCROLLCHARS( void ) /* 108 */
2426 BOOL rc;
2427 UINT old_chars;
2428 const UINT vals[]={32767,0};
2429 unsigned int i;
2431 trace("testing SPI_{GET,SET}WHEELSCROLLCHARS\n");
2432 SetLastError(0xdeadbeef);
2433 rc=SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &old_chars, 0 );
2435 /* SPI_{GET,SET}WHEELSCROLLCHARS not supported on Windows 95 */
2436 if (!test_error_msg(rc,"SPI_{GET,SET}WHEELSCROLLCHARS"))
2437 return;
2439 for (i=0;i<ARRAY_SIZE(vals);i++)
2441 UINT v;
2442 char buf[10];
2444 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, vals[i], 0,
2445 SPIF_UPDATEINIFILE | SPIF_SENDCHANGE );
2446 if (!test_error_msg(rc,"SPI_SETWHEELSCROLLCHARS")) return;
2447 test_change_message( SPI_SETWHEELSCROLLCHARS, 0 );
2448 sprintf( buf, "%d", vals[i] );
2449 test_reg_key( SPI_SETMOUSESCROLLCHARS_REGKEY,
2450 SPI_SETMOUSESCROLLCHARS_VALNAME, buf );
2452 SystemParametersInfoA( SPI_GETWHEELSCROLLCHARS, 0, &v, 0 );
2453 ok(rc, "%d: rc=%d err=%ld\n", i, rc, GetLastError());
2454 eq( v, vals[i], "SPI_{GET,SET}WHEELSCROLLCHARS", "%d" );
2457 rc=SystemParametersInfoA( SPI_SETWHEELSCROLLCHARS, old_chars, 0,
2458 SPIF_UPDATEINIFILE );
2459 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2460 flush_change_messages();
2463 static void test_SPI_SETWALLPAPER( void ) /* 115 */
2465 BOOL rc;
2466 char oldval[260];
2467 char newval[260];
2469 trace("testing SPI_{GET,SET}DESKWALLPAPER\n");
2470 SetLastError(0xdeadbeef);
2471 rc=SystemParametersInfoA(SPI_GETDESKWALLPAPER, 260, oldval, 0);
2472 if (!test_error_msg(rc,"SPI_{GET,SET}DESKWALLPAPER"))
2473 return;
2475 strcpy(newval, "");
2476 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, newval, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE);
2477 if (!test_error_msg(rc,"SPI_SETDESKWALLPAPER")) return;
2478 ok(rc, "SystemParametersInfoA: rc=%d err=%ld\n", rc, GetLastError());
2479 test_change_message(SPI_SETDESKWALLPAPER, 0);
2481 rc=SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, oldval, SPIF_UPDATEINIFILE);
2482 ok(rc, "***warning*** failed to restore the original value: rc=%d err=%ld\n", rc, GetLastError());
2484 test_reg_key(SPI_SETDESKWALLPAPER_REGKEY, SPI_SETDESKWALLPAPER_VALNAME, oldval);
2485 flush_change_messages();
2488 static void test_WM_DISPLAYCHANGE(void)
2490 UINT test_bpps[] = {8, 16, 24}, default_bpp, i;
2491 DEVMODEW settings;
2492 DWORD res;
2493 BOOL ret;
2495 displaychange_test_active = TRUE;
2496 displaychange_sem = CreateSemaphoreW( NULL, 0, 1, NULL );
2498 memset( &settings, 0, sizeof(DEVMODEW) );
2499 settings.dmSize = sizeof(DEVMODEW);
2500 ret = EnumDisplaySettingsW( NULL, ENUM_CURRENT_SETTINGS, &settings );
2501 ok( ret, "EnumDisplaySettingsW failed, error %#lx\n", GetLastError() );
2503 ok( settings.dmFields & DM_BITSPERPEL, "got dmFields %#lx\n", settings.dmFields );
2504 ok( settings.dmBitsPerPel == 32, "got dmBitsPerPel %lu\n", settings.dmBitsPerPel );
2505 default_bpp = settings.dmBitsPerPel;
2507 /* setting default mode most of the time doesn't send WM_DISPLAYCHANGE,
2508 * it only does the first time ChangeDisplaySettingsExW is called */
2510 last_bpp = -1;
2511 change_counter = 0;
2512 displaychange_ok = TRUE;
2513 res = ChangeDisplaySettingsExW( NULL, &settings, NULL, 0, NULL );
2514 ok( !res, "ChangeDisplaySettingsExW returned %ld\n", res );
2515 res = WaitForSingleObject( displaychange_sem, 1000 );
2516 todo_wine
2517 ok( res == WAIT_TIMEOUT || broken( !res ), "WaitForSingleObject returned %#lx\n", res );
2518 todo_wine
2519 ok( last_bpp == -1 || broken( last_bpp == default_bpp ), "got WM_DISPLAYCHANGE bpp %d\n", last_bpp );
2520 displaychange_ok = FALSE;
2522 for (i = 0; i < ARRAY_SIZE(test_bpps); i++)
2524 UINT bpp = test_bpps[i];
2526 winetest_push_context( "bpp %u", bpp );
2528 settings.dmBitsPerPel = bpp;
2529 settings.dmFields |= DM_BITSPERPEL;
2531 last_bpp = -1;
2532 change_counter = 0;
2533 displaychange_ok = TRUE;
2534 res = ChangeDisplaySettingsExW( NULL, &settings, NULL, 0, NULL );
2535 if (!res)
2537 /* Wait quite long for the message, screen setting changes can take some time */
2538 res = WaitForSingleObject( displaychange_sem, 10000 );
2539 ok( !res, "WaitForSingleObject returned %#lx\n", res );
2540 ok( last_bpp == bpp, "got WM_DISPLAYCHANGE bpp %d\n", last_bpp );
2542 else
2544 todo_wine
2545 win_skip( "ChangeDisplaySettingsExW returned %ld\n", res );
2546 ok( res == DISP_CHANGE_BADMODE || broken( res == DISP_CHANGE_FAILED && bpp == 8 ),
2547 "ChangeDisplaySettingsExW returned %ld\n", res );
2548 ok( last_bpp == -1, "got WM_DISPLAYCHANGE bpp %d\n", last_bpp );
2550 displaychange_ok = FALSE;
2552 winetest_pop_context();
2555 /* restoring default mode most of the time doesn't send WM_DISPLAYCHANGE */
2557 settings.dmBitsPerPel = default_bpp;
2558 settings.dmFields |= DM_BITSPERPEL;
2560 last_bpp = -1;
2561 change_counter = 0;
2562 displaychange_ok = TRUE;
2563 res = ChangeDisplaySettingsExW( NULL, &settings, NULL, 0, NULL );
2564 ok( !res, "ChangeDisplaySettingsExW returned %ld\n", res );
2565 res = WaitForSingleObject( displaychange_sem, 1000 );
2566 todo_wine
2567 ok( res == WAIT_TIMEOUT || broken( !res ), "WaitForSingleObject returned %#lx\n", res );
2568 todo_wine
2569 ok( last_bpp == -1 || broken( last_bpp == default_bpp ), "got WM_DISPLAYCHANGE bpp %d\n", last_bpp );
2570 displaychange_ok = FALSE;
2572 CloseHandle( displaychange_sem );
2573 displaychange_sem = 0;
2574 displaychange_test_active = FALSE;
2578 * Registry entries for the system parameters.
2579 * Names are created by 'SET' flags names.
2580 * We assume that corresponding 'GET' entries use the same registry keys.
2582 static DWORD WINAPI SysParamsThreadFunc( LPVOID lpParam )
2584 test_SPI_SETBEEP(); /* 1 */
2585 test_SPI_SETMOUSE(); /* 4 */
2586 test_SPI_SETBORDER(); /* 6 */
2587 test_SPI_SETKEYBOARDSPEED(); /* 10 */
2588 test_SPI_ICONHORIZONTALSPACING(); /* 13 */
2589 test_SPI_SETSCREENSAVETIMEOUT(); /* 14 */
2590 test_SPI_SETSCREENSAVEACTIVE(); /* 17 */
2591 test_SPI_SETGRIDGRANULARITY(); /* 19 */
2592 test_SPI_SETKEYBOARDDELAY(); /* 23 */
2593 test_SPI_ICONVERTICALSPACING(); /* 24 */
2594 test_SPI_SETICONTITLEWRAP(); /* 26 */
2595 test_SPI_SETMENUDROPALIGNMENT(); /* 28 */
2596 test_SPI_SETDOUBLECLKWIDTH(); /* 29 */
2597 test_SPI_SETDOUBLECLKHEIGHT(); /* 30 */
2598 test_SPI_SETDOUBLECLICKTIME(); /* 32 */
2599 test_SPI_SETMOUSEBUTTONSWAP(); /* 33 */
2600 test_SPI_SETFASTTASKSWITCH(); /* 36 */
2601 test_SPI_SETDRAGFULLWINDOWS(); /* 37 */
2602 /* test_WM_DISPLAYCHANGE seems to be somewhat buggy on
2603 * some versions of Windows (Vista, Win2k8, Win7B) in that
2604 * not all metrics are properly restored. Problems are
2605 * SM_CXMAXTRACK, SM_CYMAXTRACK
2606 * Fortunately setting the Non-Client metrics like in
2607 * test_SPI_SETNONCLIENTMETRICS will correct this. That is why
2608 * we do the DISPLAY change now... */
2609 test_WM_DISPLAYCHANGE();
2610 test_SPI_SETNONCLIENTMETRICS(); /* 42 */
2611 test_SPI_SETMINIMIZEDMETRICS(); /* 44 */
2612 test_SPI_SETICONMETRICS(); /* 46 */
2613 test_SPI_SETWORKAREA(); /* 47 */
2614 test_SPI_SETSHOWSOUNDS(); /* 57 */
2615 test_SPI_SETKEYBOARDPREF(); /* 69 */
2616 test_SPI_SETSCREENREADER(); /* 71 */
2617 test_SPI_SETFONTSMOOTHING(); /* 75 */
2618 test_SPI_SETLOWPOWERACTIVE(); /* 85 */
2619 test_SPI_SETPOWEROFFACTIVE(); /* 86 */
2620 test_SPI_SETSNAPTODEFBUTTON(); /* 95 */
2621 test_SPI_SETMOUSEHOVERWIDTH(); /* 99 */
2622 test_SPI_SETMOUSEHOVERHEIGHT(); /* 101 */
2623 test_SPI_SETMOUSEHOVERTIME(); /* 103 */
2624 test_SPI_SETWHEELSCROLLLINES(); /* 105 */
2625 test_SPI_SETMENUSHOWDELAY(); /* 107 */
2626 test_SPI_SETWHEELSCROLLCHARS(); /* 108 */
2627 test_SPI_SETWALLPAPER(); /* 115 */
2630 SendMessageA( ghTestWnd, WM_DESTROY, 0, 0 );
2631 return 0;
2634 /* test calculation of GetSystemMetrics values (mostly) from non client metrics,
2635 * icon metrics and minimized metrics.
2638 /* copied from wine's GdiGetCharDimensions, which is not available on most
2639 * windows versions */
2640 static LONG _GdiGetCharDimensions(HDC hdc, LPTEXTMETRICA lptm, LONG *height)
2642 SIZE sz;
2643 static const CHAR alphabet[] = {
2644 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q',
2645 'r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H',
2646 'I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',0};
2648 if(lptm && !GetTextMetricsA(hdc, lptm)) return 0;
2650 if(!GetTextExtentPointA(hdc, alphabet, 52, &sz)) return 0;
2652 if (height) *height = sz.cy;
2653 return (sz.cx / 26 + 1) / 2;
2656 /* get text metrics and/or "average" char width of the specified logfont
2657 * for the specified dc */
2658 static void get_text_metr_size( HDC hdc, LOGFONTA *plf, TEXTMETRICA * ptm, UINT *psz)
2660 HFONT hfont, hfontsav;
2661 TEXTMETRICA tm;
2662 if( !ptm) ptm = &tm;
2663 hfont = CreateFontIndirectA( plf);
2664 if( !hfont || ( hfontsav = SelectObject( hdc, hfont)) == NULL ) {
2665 ptm->tmHeight = -1;
2666 if( psz) *psz = 10;
2667 if( hfont) DeleteObject( hfont);
2668 return;
2670 GetTextMetricsA( hdc, ptm);
2671 if( psz)
2672 if( !(*psz = _GdiGetCharDimensions( hdc, ptm, NULL)))
2673 *psz = 10;
2674 SelectObject( hdc, hfontsav);
2675 DeleteObject( hfont);
2678 static int gsm_error_ctr;
2680 #define ok_gsm( i, e)\
2682 int exp = (e);\
2683 int act = GetSystemMetrics( (i));\
2684 if( exp != act) gsm_error_ctr++;\
2685 ok( !( exp != act),"GetSystemMetrics(%s): expected %d actual %d\n", #i, exp,act);\
2687 #define ok_gsm_2( i, e1, e2)\
2689 int exp1 = (e1);\
2690 int exp2 = (e2);\
2691 int act = GetSystemMetrics( (i));\
2692 if( exp1 != act && exp2 != act) gsm_error_ctr++;\
2693 ok( !( exp1 != act && exp2 != act), "GetSystemMetrics(%s): expected %d or %d actual %d\n", #i, exp1, exp2, act);\
2695 #define ok_gsm_3( i, e1, e2, e3)\
2697 int exp1 = (e1);\
2698 int exp2 = (e2);\
2699 int exp3 = (e3);\
2700 int act = GetSystemMetrics( (i));\
2701 if( exp1 != act && exp2 != act && exp3 != act) gsm_error_ctr++;\
2702 ok( !( exp1 != act && exp2 != act && exp3 != act),"GetSystemMetrics(%s): expected %d or %d or %d actual %d\n", #i, exp1, exp2, exp3, act);\
2705 static INT CALLBACK enum_all_fonts_proc(const LOGFONTA *elf, const TEXTMETRICA *ntm, DWORD type, LPARAM lparam)
2707 return lstrcmpiA(elf->lfFaceName, (const char *)lparam);
2710 static BOOL is_font_enumerated(const char *name)
2712 HDC hdc = CreateCompatibleDC(0);
2713 BOOL ret = FALSE;
2715 if (!EnumFontFamiliesA(hdc, NULL, enum_all_fonts_proc, (LPARAM)name))
2716 ret = TRUE;
2718 DeleteDC(hdc);
2719 return ret;
2722 static int get_cursor_size( int size )
2724 /* only certain sizes are allowed for cursors */
2725 if (size >= 64) return 64;
2726 if (size >= 48) return 48;
2727 return 32;
2730 static void test_GetSystemMetrics( void)
2732 TEXTMETRICA tmMenuFont;
2733 UINT IconSpacing, IconVerticalSpacing;
2734 BOOL rc;
2736 HDC hdc = CreateICA( "Display", 0, 0, 0);
2737 UINT avcwCaption;
2738 INT CaptionWidthfromreg, width, smicon, broken_val;
2739 MINIMIZEDMETRICS minim;
2740 NONCLIENTMETRICSA ncm;
2741 SIZE screen;
2743 assert(sizeof(ncm) == 344);
2745 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2746 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2747 ok(rc, "SystemParametersInfoA failed\n");
2749 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) - 1;
2750 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2751 ok(!rc, "SystemParametersInfoA should fail\n");
2753 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth) + 1;
2754 SetLastError(0xdeadbeef);
2755 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2756 ok(!rc, "SystemParametersInfoA should fail\n");
2758 ncm.cbSize = sizeof(ncm); /* Vista added padding */
2759 SetLastError(0xdeadbeef);
2760 ncm.iPaddedBorderWidth = 0xcccc;
2761 rc = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2762 ok(rc || broken(!rc) /* before Vista */, "SystemParametersInfoA failed\n");
2763 if (rc) ok( ncm.iPaddedBorderWidth == 0, "wrong iPaddedBorderWidth %u\n", ncm.iPaddedBorderWidth );
2765 minim.cbSize = sizeof( minim);
2766 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
2767 SystemParametersInfoA( SPI_GETMINIMIZEDMETRICS, 0, &minim, 0);
2768 rc = SystemParametersInfoA( SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
2769 if( !rc) {
2770 win_skip("SPI_GETNONCLIENTMETRICS is not available\n");
2771 return;
2774 ok(is_font_enumerated(ncm.lfCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfCaptionFont.lfFaceName);
2775 ok(is_font_enumerated(ncm.lfSmCaptionFont.lfFaceName), "font %s should be enumerated\n", ncm.lfSmCaptionFont.lfFaceName);
2776 ok(is_font_enumerated(ncm.lfMenuFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMenuFont.lfFaceName);
2777 ok(is_font_enumerated(ncm.lfStatusFont.lfFaceName), "font %s should be enumerated\n", ncm.lfStatusFont.lfFaceName);
2778 ok(is_font_enumerated(ncm.lfMessageFont.lfFaceName), "font %s should be enumerated\n", ncm.lfMessageFont.lfFaceName);
2780 /* CaptionWidth from the registry may have different value of iCaptionWidth
2781 * from the non client metrics (observed on WinXP) */
2782 CaptionWidthfromreg = metricfromreg(
2783 "Control Panel\\Desktop\\WindowMetrics","CaptionWidth", dpi);
2784 get_text_metr_size( hdc, &ncm.lfMenuFont, &tmMenuFont, NULL);
2785 get_text_metr_size( hdc, &ncm.lfCaptionFont, NULL, &avcwCaption);
2786 /* FIXME: use icon metric */
2787 if( !SystemParametersInfoA( SPI_ICONVERTICALSPACING, 0, &IconVerticalSpacing, 0))
2788 IconVerticalSpacing = 0;
2789 if( !SystemParametersInfoA( SPI_ICONHORIZONTALSPACING, 0, &IconSpacing, 0 ))
2790 IconSpacing = 0;
2791 /* reset error counters */
2792 gsm_error_ctr = 0;
2794 /* the tests: */
2796 /* SM_CXSCREEN, cannot test these two */
2797 /* SM_CYSCREEN */
2798 ok_gsm( SM_CXVSCROLL, ncm.iScrollWidth);
2799 ok_gsm( SM_CYHSCROLL, ncm.iScrollWidth);
2800 ok_gsm( SM_CYCAPTION, ncm.iCaptionHeight+1);
2801 ok_gsm( SM_CXBORDER, 1);
2802 ok_gsm( SM_CYBORDER, 1);
2803 ok_gsm( SM_CXDLGFRAME, 3);
2804 ok_gsm( SM_CYDLGFRAME, 3);
2805 ok_gsm( SM_CYVTHUMB, ncm.iScrollHeight);
2806 ok_gsm( SM_CXHTHUMB, ncm.iScrollHeight);
2807 /* These don't depend on the Shell Icon Size registry value */
2808 ok_gsm( SM_CXICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2809 ok_gsm( SM_CYICON, MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI ) );
2810 ok_gsm( SM_CXCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2811 ok_gsm( SM_CYCURSOR, get_cursor_size( MulDiv( 32, dpi, USER_DEFAULT_SCREEN_DPI )));
2812 ok_gsm( SM_CYMENU, ncm.iMenuHeight + 1);
2813 ok_gsm( SM_CXFULLSCREEN,
2814 GetSystemMetrics( SM_CXMAXIMIZED) - 2 * GetSystemMetrics( SM_CXFRAME));
2815 ok_gsm( SM_CYFULLSCREEN,
2816 GetSystemMetrics( SM_CYMAXIMIZED) - GetSystemMetrics( SM_CYMIN));
2817 /* SM_CYKANJIWINDOW */
2818 /* SM_MOUSEPRESENT */
2819 ok_gsm( SM_CYVSCROLL, ncm.iScrollHeight);
2820 ok_gsm( SM_CXHSCROLL, ncm.iScrollHeight);
2821 /* SM_DEBUG */
2822 /* SM_SWAPBUTTON */
2823 /* SM_RESERVED1 */
2824 /* SM_RESERVED2 */
2825 /* SM_RESERVED3 */
2826 /* SM_RESERVED4 */
2827 ok_gsm( SM_CXMIN, 3 * max( CaptionWidthfromreg >= 0 ? CaptionWidthfromreg : ncm.iCaptionWidth, 8) +
2828 GetSystemMetrics( SM_CYSIZE) + 4 + 4 * avcwCaption + 2 * GetSystemMetrics( SM_CXFRAME));
2829 ok_gsm( SM_CYMIN, GetSystemMetrics( SM_CYCAPTION) +
2830 2 * GetSystemMetrics( SM_CYFRAME));
2831 ok_gsm_2( SM_CXSIZE,
2832 ncm.iCaptionWidth, /* classic/standard windows style */
2833 GetSystemMetrics( SM_CYCAPTION) - 1 /* WinXP style */
2835 ok_gsm( SM_CYSIZE, ncm.iCaptionHeight);
2836 ok_gsm( SM_CXFRAME, ncm.iBorderWidth + 3);
2837 ok_gsm( SM_CYFRAME, ncm.iBorderWidth + 3);
2838 ok_gsm( SM_CXMINTRACK, GetSystemMetrics( SM_CXMIN));
2839 ok_gsm( SM_CYMINTRACK, GetSystemMetrics( SM_CYMIN));
2840 /* SM_CXDOUBLECLK */
2841 /* SM_CYDOUBLECLK */
2842 if( IconSpacing) ok_gsm( SM_CXICONSPACING, IconSpacing);
2843 if( IconVerticalSpacing) ok_gsm( SM_CYICONSPACING, IconVerticalSpacing);
2844 /* SM_MENUDROPALIGNMENT */
2845 /* SM_PENWINDOWS */
2846 /* SM_DBCSENABLED */
2847 /* SM_CMOUSEBUTTONS */
2848 /* SM_SECURE */
2849 ok_gsm( SM_CXEDGE, 2);
2850 ok_gsm( SM_CYEDGE, 2);
2851 /* sign-extension for iHorzGap/iVertGap is broken on Win9x */
2852 ok_gsm( SM_CXMINSPACING, GetSystemMetrics( SM_CXMINIMIZED) + (short)minim.iHorzGap );
2853 ok_gsm( SM_CYMINSPACING, GetSystemMetrics( SM_CYMINIMIZED) + (short)minim.iVertGap );
2855 smicon = MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI );
2856 width = CaptionWidthfromreg > 0 ? CaptionWidthfromreg : ncm.iCaptionWidth;
2857 if (!pIsProcessDPIAware || pIsProcessDPIAware())
2858 smicon = max( min( smicon, width - 2), 4 ) & ~1;
2859 todo_wine_if( real_dpi == dpi && smicon != (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI) & ~1) )
2861 broken_val = (min( ncm.iCaptionHeight, width ) - 2) & ~1;
2862 broken_val = min( broken_val, 20 );
2864 if (smicon == 4)
2866 ok_gsm_2( SM_CXSMICON, smicon, 6 );
2867 ok_gsm_2( SM_CYSMICON, smicon, 6 );
2869 else
2871 ok_gsm_2( SM_CXSMICON, smicon, broken_val );
2872 ok_gsm_2( SM_CYSMICON, smicon, broken_val );
2876 ok_gsm( SM_CYSMCAPTION, ncm.iSmCaptionHeight + 1);
2877 ok_gsm_3( SM_CXSMSIZE,
2878 ncm.iSmCaptionWidth, /* classic/standard windows style */
2879 GetSystemMetrics( SM_CYSMCAPTION) - 1, /* WinXP style */
2880 smcxsmsize /* winXP seems to cache this value: setnonclientmetric
2881 does not change it */
2883 ok_gsm( SM_CYSMSIZE, GetSystemMetrics( SM_CYSMCAPTION) - 1);
2884 ok_gsm( SM_CXMENUSIZE, ncm.iMenuWidth);
2885 ok_gsm( SM_CYMENUSIZE, ncm.iMenuHeight);
2886 /* SM_ARRANGE */
2887 ok_gsm( SM_CXMINIMIZED, minim.iWidth + 6);
2888 ok_gsm( SM_CYMINIMIZED, GetSystemMetrics( SM_CYCAPTION) + 5);
2889 screen.cx = GetSystemMetrics( SM_CXVIRTUALSCREEN );
2890 screen.cy = GetSystemMetrics( SM_CYVIRTUALSCREEN );
2891 if (!screen.cx || !screen.cy) /* not supported on NT4 */
2893 screen.cx = GetSystemMetrics( SM_CXSCREEN );
2894 screen.cy = GetSystemMetrics( SM_CYSCREEN );
2896 ok_gsm_3( SM_CXMAXTRACK, screen.cx + 4 + 2 * GetSystemMetrics(SM_CXFRAME),
2897 screen.cx - 4 + 2 * GetSystemMetrics(SM_CXFRAME), /* Vista */
2898 screen.cx + 2 * GetSystemMetrics(SM_CXFRAME)); /* Win8 */
2899 ok_gsm_3( SM_CYMAXTRACK, screen.cy + 4 + 2 * GetSystemMetrics(SM_CYFRAME),
2900 screen.cy - 4 + 2 * GetSystemMetrics(SM_CYFRAME), /* Vista */
2901 screen.cy + 2 * GetSystemMetrics(SM_CYFRAME)); /* Win8 */
2902 /* the next two cannot really be tested as they depend on (application)
2903 * toolbars */
2904 /* SM_CXMAXIMIZED */
2905 /* SM_CYMAXIMIZED */
2906 /* SM_NETWORK */
2907 /* */
2908 /* */
2909 /* */
2910 /* SM_CLEANBOOT */
2911 /* SM_CXDRAG */
2912 /* SM_CYDRAG */
2913 /* SM_SHOWSOUNDS */
2914 ok_gsm( SM_CXMENUCHECK,
2915 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2916 ok_gsm( SM_CYMENUCHECK,
2917 ((tmMenuFont.tmHeight + tmMenuFont.tmExternalLeading+1)/2)*2-1);
2918 /* SM_SLOWMACHINE */
2919 /* SM_MIDEASTENABLED */
2920 /* SM_MOUSEWHEELPRESENT */
2921 /* SM_XVIRTUALSCREEN */
2922 /* SM_YVIRTUALSCREEN */
2923 /* SM_CXVIRTUALSCREEN */
2924 /* SM_CYVIRTUALSCREEN */
2925 /* SM_CMONITORS */
2926 /* SM_SAMEDISPLAYFORMAT */
2927 /* SM_IMMENABLED */
2928 /* SM_CXFOCUSBORDER */
2929 /* SM_CYFOCUSBORDER */
2930 /* SM_TABLETPC */
2931 /* SM_MEDIACENTER */
2932 /* SM_CMETRICS */
2933 /* end of tests */
2934 if( gsm_error_ctr ) { /* if any errors where found */
2935 trace( "BorderWidth %d CaptionWidth %d CaptionHeight %d IconSpacing %d IconVerticalSpacing %d\n",
2936 ncm.iBorderWidth, ncm.iCaptionWidth, ncm.iCaptionHeight, IconSpacing, IconVerticalSpacing);
2937 trace( "MenuHeight %d MenuWidth %d ScrollHeight %d ScrollWidth %d SmCaptionHeight %d SmCaptionWidth %d\n",
2938 ncm.iMenuHeight, ncm.iMenuWidth, ncm.iScrollHeight, ncm.iScrollWidth, ncm.iSmCaptionHeight, ncm.iSmCaptionWidth);
2939 trace( "Captionfontchar width %d MenuFont %ld,%ld CaptionWidth from registry: %d screen %ld,%ld\n",
2940 avcwCaption, tmMenuFont.tmHeight, tmMenuFont.tmExternalLeading, CaptionWidthfromreg, screen.cx, screen.cy);
2943 DeleteDC(hdc);
2946 static void compare_font( const LOGFONTW *lf1, const LOGFONTW *lf2, int dpi, int custom_dpi, int line )
2948 ok_(__FILE__,line)( lf2->lfHeight == (dpi == custom_dpi) ? lf1->lfHeight : MulDiv( lf1->lfHeight, custom_dpi, 2 * dpi ),
2949 "wrong lfHeight %ld vs %ld\n", lf1->lfHeight, lf2->lfHeight );
2950 ok_(__FILE__,line)( abs( lf1->lfWidth - MulDiv( lf2->lfWidth, dpi, custom_dpi )) <= 1,
2951 "wrong lfWidth %ld vs %ld\n", lf1->lfWidth, lf2->lfWidth );
2952 ok_(__FILE__,line)( !memcmp( &lf1->lfEscapement, &lf2->lfEscapement,
2953 offsetof( LOGFONTW, lfFaceName ) - offsetof( LOGFONTW, lfEscapement )),
2954 "font differs\n" );
2955 ok_(__FILE__,line)( !lstrcmpW( lf1->lfFaceName, lf2->lfFaceName ), "wrong face name %s vs %s\n",
2956 wine_dbgstr_w( lf1->lfFaceName ), wine_dbgstr_w( lf2->lfFaceName ));
2959 static void test_metrics_for_dpi( int custom_dpi )
2961 int i, val;
2962 NONCLIENTMETRICSW ncm1, ncm2;
2963 ICONMETRICSW im1, im2;
2964 LOGFONTW lf1, lf2;
2965 BOOL ret;
2967 if (!pSystemParametersInfoForDpi)
2969 win_skip( "custom dpi metrics not supported\n" );
2970 return;
2973 ncm1.cbSize = sizeof(ncm1);
2974 ret = SystemParametersInfoW( SPI_GETNONCLIENTMETRICS, sizeof(ncm1), &ncm1, FALSE );
2975 ok( ret, "SystemParametersInfoW failed err %lu\n", GetLastError() );
2976 ncm2.cbSize = sizeof(ncm2);
2977 ret = pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof(ncm2), &ncm2, FALSE, custom_dpi );
2978 ok( ret, "SystemParametersInfoForDpi failed err %lu\n", GetLastError() );
2980 for (i = 0; i < 92; i++)
2982 int ret1 = GetSystemMetrics( i );
2983 int ret2 = pGetSystemMetricsForDpi( i, custom_dpi );
2984 switch (i)
2986 case SM_CXVSCROLL:
2987 case SM_CYHSCROLL:
2988 case SM_CYVTHUMB:
2989 case SM_CXHTHUMB:
2990 case SM_CXICON:
2991 case SM_CYICON:
2992 case SM_CYVSCROLL:
2993 case SM_CXHSCROLL:
2994 case SM_CYSIZE:
2995 case SM_CXICONSPACING:
2996 case SM_CYICONSPACING:
2997 case SM_CXSMSIZE:
2998 case SM_CYSMSIZE:
2999 case SM_CYMENUSIZE:
3000 ok( ret1 == MulDiv( ret2, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3001 break;
3002 case SM_CXSIZE:
3003 ok( ret1 == ncm1.iCaptionWidth && ret2 == ncm2.iCaptionWidth,
3004 "%u: wrong value %u vs %u caption %u vs %u\n",
3005 i, ret1, ret2, ncm1.iCaptionWidth, ncm2.iCaptionWidth );
3006 break;
3007 case SM_CXCURSOR:
3008 case SM_CYCURSOR:
3009 val = MulDiv( 32, custom_dpi, USER_DEFAULT_SCREEN_DPI );
3010 if (val < 48) val = 32;
3011 else if (val < 64) val = 48;
3012 else val = 64;
3013 ok( val == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3014 break;
3015 case SM_CYCAPTION:
3016 case SM_CYSMCAPTION:
3017 case SM_CYMENU:
3018 ok( ret1 - 1 == MulDiv( ret2 - 1, dpi, custom_dpi ), "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3019 break;
3020 case SM_CXMENUSIZE:
3021 ok( ret1 / 8 == MulDiv( ret2, dpi, custom_dpi ) / 8, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3022 break;
3023 case SM_CXFRAME:
3024 case SM_CYFRAME:
3025 ok( ret1 == ncm1.iBorderWidth + 3 && ret2 == ncm2.iBorderWidth + 3,
3026 "%u: wrong value %u vs %u borders %u+%u vs %u+%u\n", i, ret1, ret2,
3027 ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
3028 break;
3029 case SM_CXSMICON:
3030 case SM_CYSMICON:
3031 ok( ret1 == (MulDiv( 16, dpi, USER_DEFAULT_SCREEN_DPI ) & ~1) &&
3032 ret2 == (MulDiv( 16, custom_dpi, USER_DEFAULT_SCREEN_DPI ) & ~1),
3033 "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3034 break;
3035 case SM_CXMENUCHECK:
3036 case SM_CYMENUCHECK:
3037 ok( ret1 == ((get_tmheightW( &ncm1.lfMenuFont, 1 ) - 1) | 1) &&
3038 ret2 == ((get_tmheightW( &ncm2.lfMenuFont, 1 ) - 1) | 1),
3039 "%u: wrong value %u vs %u font %u vs %u\n", i, ret1, ret2,
3040 get_tmheightW( &ncm1.lfMenuFont, 1 ), get_tmheightW( &ncm2.lfMenuFont, 1 ));
3041 break;
3042 case SM_CYMIN:
3043 case SM_CYMINTRACK:
3044 val = pGetSystemMetricsForDpi( SM_CYCAPTION, custom_dpi );
3045 val += 2 * pGetSystemMetricsForDpi( SM_CYFRAME, custom_dpi );
3046 val += 2 * ncm2.iPaddedBorderWidth;
3047 ok( ret1 == ret2 || ret2 == val /* Win10 1709+ */, "%u: expected %u or %u, got %u\n", i, ret1, val, ret2 );
3048 break;
3049 case SM_CXMIN:
3050 case SM_CXMINTRACK:
3051 val = MulDiv( ret1 - 7, custom_dpi, dpi );
3052 ok( ret1 == ret2 || (ret2 >= val - 10 && ret2 <= val + 10) /* Win10 1709+ */,
3053 "%u: expected %u or %u, got %u\n", i, ret1, val, ret2 );
3054 break;
3055 default:
3056 ok( ret1 == ret2, "%u: wrong value %u vs %u\n", i, ret1, ret2 );
3057 break;
3060 im1.cbSize = sizeof(im1);
3061 ret = SystemParametersInfoW( SPI_GETICONMETRICS, sizeof(im1), &im1, FALSE );
3062 ok( ret, "SystemParametersInfoW failed err %lu\n", GetLastError() );
3063 im2.cbSize = sizeof(im2);
3064 ret = pSystemParametersInfoForDpi( SPI_GETICONMETRICS, sizeof(im2), &im2, FALSE, custom_dpi );
3065 ok( ret, "SystemParametersInfoForDpi failed err %lu\n", GetLastError() );
3066 ok( im1.iHorzSpacing == MulDiv( im2.iHorzSpacing, dpi, custom_dpi ), "wrong iHorzSpacing %u vs %u\n",
3067 im1.iHorzSpacing, im2.iHorzSpacing );
3068 ok( im1.iVertSpacing == MulDiv( im2.iVertSpacing, dpi, custom_dpi ), "wrong iVertSpacing %u vs %u\n",
3069 im1.iVertSpacing, im2.iVertSpacing );
3070 ok( im1.iTitleWrap == im2.iTitleWrap, "wrong iTitleWrap %u vs %u\n",
3071 im1.iTitleWrap, im2.iTitleWrap );
3072 compare_font( &im1.lfFont, &im2.lfFont, dpi, custom_dpi, __LINE__ );
3074 ret = SystemParametersInfoW( SPI_GETICONTITLELOGFONT, sizeof(lf1), &lf1, FALSE );
3075 ok( ret, "SystemParametersInfoW failed err %lu\n", GetLastError() );
3076 ret = pSystemParametersInfoForDpi( SPI_GETICONTITLELOGFONT, sizeof(lf2), &lf2, FALSE, custom_dpi );
3077 ok( ret, "SystemParametersInfoForDpi failed err %lu\n", GetLastError() );
3078 compare_font( &lf1, &lf2, dpi, custom_dpi, __LINE__ );
3080 /* on high-dpi iPaddedBorderWidth is used in addition to iBorderWidth */
3081 ok( ncm1.iBorderWidth + ncm1.iPaddedBorderWidth == MulDiv( ncm2.iBorderWidth + ncm2.iPaddedBorderWidth, dpi, custom_dpi ),
3082 "wrong iBorderWidth %u+%u vs %u+%u\n",
3083 ncm1.iBorderWidth, ncm1.iPaddedBorderWidth, ncm2.iBorderWidth, ncm2.iPaddedBorderWidth );
3084 ok( ncm1.iScrollWidth == MulDiv( ncm2.iScrollWidth, dpi, custom_dpi ),
3085 "wrong iScrollWidth %u vs %u\n", ncm1.iScrollWidth, ncm2.iScrollWidth );
3086 ok( ncm1.iScrollHeight == MulDiv( ncm2.iScrollHeight, dpi, custom_dpi ),
3087 "wrong iScrollHeight %u vs %u\n", ncm1.iScrollHeight, ncm2.iScrollHeight );
3088 ok( ((ncm1.iCaptionWidth + 1) & ~1) == ((MulDiv( ncm2.iCaptionWidth, dpi, custom_dpi ) + 1) & ~1),
3089 "wrong iCaptionWidth %u vs %u\n", ncm1.iCaptionWidth, ncm2.iCaptionWidth );
3090 ok( ncm1.iCaptionHeight == MulDiv( ncm2.iCaptionHeight, dpi, custom_dpi ),
3091 "wrong iCaptionHeight %u vs %u\n", ncm1.iCaptionHeight, ncm2.iCaptionHeight );
3092 compare_font( &ncm1.lfCaptionFont, &ncm2.lfCaptionFont, dpi, custom_dpi, __LINE__ );
3093 ok( ncm1.iSmCaptionHeight == MulDiv( ncm2.iSmCaptionHeight, dpi, custom_dpi ),
3094 "wrong iSmCaptionHeight %u vs %u\n", ncm1.iSmCaptionHeight, ncm2.iSmCaptionHeight );
3095 compare_font( &ncm1.lfSmCaptionFont, &ncm2.lfSmCaptionFont, dpi, custom_dpi, __LINE__ );
3096 ok( ncm1.iMenuHeight == MulDiv( ncm2.iMenuHeight, dpi, custom_dpi ),
3097 "wrong iMenuHeight %u vs %u\n", ncm1.iMenuHeight, ncm2.iMenuHeight );
3098 /* iSmCaptionWidth and iMenuWidth apparently need to be multiples of 8 */
3099 ok( ncm1.iSmCaptionWidth / 8 == MulDiv( ncm2.iSmCaptionWidth, dpi, custom_dpi ) / 8,
3100 "wrong iSmCaptionWidth %u vs %u\n", ncm1.iSmCaptionWidth, ncm2.iSmCaptionWidth );
3101 ok( ncm1.iMenuWidth / 8 == MulDiv( ncm2.iMenuWidth, dpi, custom_dpi ) / 8,
3102 "wrong iMenuWidth %u vs %u\n", ncm1.iMenuWidth, ncm2.iMenuWidth );
3103 compare_font( &ncm1.lfMenuFont, &ncm2.lfMenuFont, dpi, custom_dpi, __LINE__ );
3104 compare_font( &ncm1.lfStatusFont, &ncm2.lfStatusFont, dpi, custom_dpi, __LINE__ );
3105 compare_font( &ncm1.lfMessageFont, &ncm2.lfMessageFont, dpi, custom_dpi, __LINE__ );
3107 for (i = 1; i < 120; i++)
3109 if (i == SPI_GETICONTITLELOGFONT || i == SPI_GETNONCLIENTMETRICS || i == SPI_GETICONMETRICS)
3110 continue;
3111 SetLastError( 0xdeadbeef );
3112 ret = pSystemParametersInfoForDpi( i, 0, &val, 0, custom_dpi );
3113 ok( !ret, "%u: SystemParametersInfoForDpi succeeded\n", i );
3114 ok( GetLastError() == ERROR_INVALID_PARAMETER, "%u: wrong error %lu\n", i, GetLastError() );
3118 static BOOL get_primary_adapter_name(CHAR *name)
3120 DISPLAY_DEVICEA dd;
3121 DWORD adapter;
3123 dd.cb = sizeof(dd);
3124 for (adapter = 0; EnumDisplayDevicesA(NULL, adapter, &dd, 0); ++adapter)
3126 if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
3128 lstrcpyA(name, dd.DeviceName);
3129 return TRUE;
3133 return FALSE;
3136 static BOOL CALLBACK test_enum_display_settings(HMONITOR hmonitor, HDC hdc, LPRECT rect, LPARAM lparam)
3138 INT width, height;
3139 MONITORINFOEXA mi;
3140 DEVMODEA dm;
3141 BOOL ret;
3143 memset(&mi, 0, sizeof(mi));
3144 mi.cbSize = sizeof(mi);
3145 ret = GetMonitorInfoA(hmonitor, (MONITORINFO *)&mi);
3146 ok(ret, "GetMonitorInfoA failed, error %#lx\n", GetLastError());
3148 memset(&dm, 0, sizeof(dm));
3149 dm.dmSize = sizeof(dm);
3150 ret = EnumDisplaySettingsA(mi.szDevice, ENUM_CURRENT_SETTINGS, &dm);
3151 ok(ret, "EnumDisplaySettingsA failed, error %#lx\n", GetLastError());
3153 ok((dm.dmFields & (DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT)) == (DM_POSITION | DM_PELSWIDTH | DM_PELSHEIGHT),
3154 "Unexpected dmFields %#lx.\n", dm.dmFields);
3155 ok(dm.dmPosition.x == mi.rcMonitor.left, "Expect dmPosition.x %ld, got %ld\n", mi.rcMonitor.left, dm.dmPosition.x);
3156 ok(dm.dmPosition.y == mi.rcMonitor.top, "Expect dmPosition.y %ld, got %ld\n", mi.rcMonitor.top, dm.dmPosition.y);
3157 width = mi.rcMonitor.right - mi.rcMonitor.left;
3158 ok(dm.dmPelsWidth == width, "Expect dmPelsWidth %d, got %ld\n", width, dm.dmPelsWidth);
3159 height = mi.rcMonitor.bottom - mi.rcMonitor.top;
3160 ok(dm.dmPelsHeight == height, "Expect dmPelsHeight %d, got %ld\n", height, dm.dmPelsHeight);
3162 return TRUE;
3165 static void test_EnumDisplaySettings(void)
3167 static const DWORD mode_fields = DM_DISPLAYORIENTATION | DM_BITSPERPEL |
3168 DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY;
3169 static const DWORD setting_fields = DM_DISPLAYORIENTATION | DM_BITSPERPEL |
3170 DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYFLAGS | DM_DISPLAYFREQUENCY | DM_POSITION;
3171 CHAR primary_adapter[CCHDEVICENAME];
3172 DPI_AWARENESS_CONTEXT ctx = NULL;
3173 DWORD err, val, device, mode;
3174 BOOL attached, ret;
3175 DISPLAY_DEVICEA dd;
3176 DEVMODEA dm, dm2;
3177 DEVMODEW dmW;
3178 HDC hdc;
3180 /* Test invalid device names */
3181 memset(&dm, 0, sizeof(dm));
3182 dm.dmSize = sizeof(dm);
3183 SetLastError(0xdeadbeef);
3184 ret = EnumDisplaySettingsA("invalid", ENUM_CURRENT_SETTINGS, &dm);
3185 ok(!ret, "EnumDisplaySettingsA succeeded\n");
3186 ok(GetLastError() == 0xdeadbeef, "Expect error 0xdeadbeef, got %#lx\n", GetLastError());
3187 ok(dm.dmFields == 0, "Expect dmFields unchanged, got %#lx\n", dm.dmFields);
3189 /* Monitor device names are invalid */
3190 memset(&dm, 0, sizeof(dm));
3191 dm.dmSize = sizeof(dm);
3192 SetLastError(0xdeadbeef);
3193 ret = EnumDisplaySettingsA("\\\\.\\DISPLAY1\\Monitor0", ENUM_CURRENT_SETTINGS, &dm);
3194 ok(!ret, "EnumDisplaySettingsA succeeded\n");
3195 ok(GetLastError() == 0xdeadbeef, "Expect error 0xdeadbeef, got %#lx\n", GetLastError());
3196 ok(dm.dmFields == 0, "Expect dmFields unchanged, got %#lx\n", dm.dmFields);
3198 /* Test that passing NULL to device name parameter means to use the primary adapter */
3199 memset(&dm, 0, sizeof(dm));
3200 memset(&dm2, 0, sizeof(dm2));
3201 dm.dmSize = sizeof(dm);
3202 dm2.dmSize = sizeof(dm2);
3203 ret = get_primary_adapter_name(primary_adapter);
3204 ok(ret, "get_primary_adapter_name failed\n");
3205 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
3206 ok(ret, "EnumDisplaySettingsA failed, error %#lx\n", GetLastError());
3207 ret = EnumDisplaySettingsA(primary_adapter, ENUM_CURRENT_SETTINGS, &dm2);
3208 ok(ret, "EnumDisplaySettingsA failed, error %#lx\n", GetLastError());
3209 ok(!memcmp(&dm, &dm2, sizeof(dm)), "Expect NULL device is the primary device.\n");
3211 /* Test dmSize */
3212 /* EnumDisplaySettingsA/W modify dmSize and don't check for insufficient dmSize */
3213 memset(&dm, 0, sizeof(dm));
3214 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
3215 ok(ret, "EnumDisplaySettingsA failed, error %#lx\n", GetLastError());
3216 ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmICMMethod), "Expect dmSize %lu, got %u\n",
3217 FIELD_OFFSET(DEVMODEA, dmICMMethod), dm.dmSize);
3218 ok((dm.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#lx, got %#lx\n",
3219 setting_fields, dm.dmFields);
3221 memset(&dm, 0, sizeof(dm));
3222 dm.dmSize = sizeof(dm);
3223 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
3224 ok(ret, "EnumDisplaySettingsA failed, error %#lx\n", GetLastError());
3225 ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmICMMethod), "Expect dmSize %lu, got %u\n",
3226 FIELD_OFFSET(DEVMODEA, dmICMMethod), dm.dmSize);
3227 ok((dm.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#lx, got %#lx\n",
3228 setting_fields, dm.dmFields);
3230 memset(&dmW, 0, sizeof(dmW));
3231 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dmW);
3232 ok(ret, "EnumDisplaySettingsW failed, error %#lx\n", GetLastError());
3233 ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod), "Expect dmSize %lu, got %u\n",
3234 FIELD_OFFSET(DEVMODEW, dmICMMethod), dmW.dmSize);
3235 ok((dmW.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#lx, got %#lx\n",
3236 setting_fields, dmW.dmFields);
3238 memset(&dmW, 0, sizeof(dmW));
3239 dmW.dmSize = sizeof(dmW);
3240 ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &dmW);
3241 ok(ret, "EnumDisplaySettingsW failed, error %#lx\n", GetLastError());
3242 ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod), "Expect dmSize %lu, got %u\n",
3243 FIELD_OFFSET(DEVMODEW, dmICMMethod), dmW.dmSize);
3244 ok((dmW.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#lx, got %#lx\n",
3245 setting_fields, dmW.dmFields);
3247 /* EnumDisplaySettingsExA/W need dmSize to be at least FIELD_OFFSET(DEVMODEA/W, dmFields) + 1 to have valid dmFields */
3248 /* Crash on Windows when dmSize is zero */
3249 if (0)
3251 memset(&dm, 0, sizeof(dm));
3252 ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
3253 ok(!ret, "EnumDisplaySettingsExA succeed\n");
3255 memset(&dmW, 0, sizeof(dmW));
3256 ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &dmW, 0);
3257 ok(!ret, "EnumDisplaySettingsExA succeed\n");
3260 memset(&dm, 0, sizeof(dm));
3261 dm.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
3262 ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
3263 ok(ret, "EnumDisplaySettingsExA failed, error %#lx\n", GetLastError());
3264 todo_wine ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmFields), "Expect dmSize unchanged, got %u\n", dm.dmSize);
3265 todo_wine ok(dm.dmFields == 0, "Expect dmFields unchanged, got %#lx\n", dm.dmFields);
3267 memset(&dm, 0, sizeof(dm));
3268 dm.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + 1;
3269 ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
3270 ok(ret, "EnumDisplaySettingsExA failed, error %#lx\n", GetLastError());
3271 todo_wine ok(dm.dmSize == FIELD_OFFSET(DEVMODEA, dmFields) + 1, "Expect dmSize unchanged, got %u\n", dm.dmSize);
3272 todo_wine ok((dm.dmFields & setting_fields) == (DM_POSITION | DM_DISPLAYORIENTATION),
3273 "Expect dmFields to contain %#lx, got %#lx\n", DM_POSITION | DM_DISPLAYORIENTATION, dm.dmFields);
3274 /* Fields beyond dmSize don't get written */
3275 todo_wine ok(dm.dmPelsWidth == 0, "Expect dmPelsWidth unwritten\n");
3277 memset(&dmW, 0, sizeof(dmW));
3278 dmW.dmSize = FIELD_OFFSET(DEVMODEW, dmFields);
3279 ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &dmW, 0);
3280 ok(ret, "EnumDisplaySettingsExW failed, error %#lx\n", GetLastError());
3281 todo_wine ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmFields), "Expect dmSize unchanged, got %u\n", dmW.dmSize);
3282 todo_wine ok(dmW.dmFields == 0, "Expect dmFields unchanged, got %#lx\n", dmW.dmFields);
3284 memset(&dmW, 0, sizeof(dmW));
3285 dmW.dmSize = FIELD_OFFSET(DEVMODEW, dmFields) + 1;
3286 ret = EnumDisplaySettingsExW(NULL, ENUM_CURRENT_SETTINGS, &dmW, 0);
3287 ok(ret, "EnumDisplaySettingsExW failed, error %#lx\n", GetLastError());
3288 todo_wine ok(dmW.dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + 1, "Expect dmSize unchanged, got %u\n", dmW.dmSize);
3289 todo_wine ok((dmW.dmFields & setting_fields) == (DM_POSITION | DM_DISPLAYORIENTATION),
3290 "Expect dmFields to contain %#lx, got %#lx\n", DM_POSITION | DM_DISPLAYORIENTATION, dmW.dmFields);
3291 /* Fields beyond dmSize don't get written */
3292 todo_wine ok(dmW.dmPelsWidth == 0, "Expect dmPelsWidth unwritten\n");
3294 /* Test dmBitsPerPel */
3295 hdc = GetDC(0);
3296 val = GetDeviceCaps(hdc, BITSPIXEL);
3298 memset(&dm, 0, sizeof(dm));
3299 dm.dmSize = sizeof(dm);
3300 ret = EnumDisplaySettingsExA(NULL, ENUM_CURRENT_SETTINGS, &dm, 0);
3301 ok(ret, "EnumDisplaySettingsExA failed, error %#lx\n", GetLastError());
3302 ok((dm.dmFields & setting_fields) == setting_fields, "Expect dmFields to contain %#lx, got %#lx\n",
3303 setting_fields, dm.dmFields);
3304 ok(dm.dmBitsPerPel == val, "Expect dmBitsPerPel %ld, got %ld\n", val, dm.dmBitsPerPel);
3306 val = GetDeviceCaps(hdc, NUMCOLORS);
3307 if (dm.dmBitsPerPel <= 8)
3309 ok(val == 256, "Screen bpp is %ld, NUMCOLORS returned %ld\n", dm.dmBitsPerPel, val);
3311 else
3313 ok(val == -1, "Screen bpp is %ld, NUMCOLORS returned %ld\n", dm.dmBitsPerPel, val);
3316 ReleaseDC(0, hdc);
3318 /* Test dmPosition, dmPelsWidth and dmPelsHeight */
3319 /* Set DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE so that GetMonitorInfo() returns physical pixels */
3320 if (pSetThreadDpiAwarenessContext)
3321 ctx = pSetThreadDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE);
3322 EnumDisplayMonitors(NULL, NULL, test_enum_display_settings, 0);
3323 if (pSetThreadDpiAwarenessContext && ctx)
3324 pSetThreadDpiAwarenessContext(ctx);
3326 /* Test mode enumeration and other fields */
3327 dd.cb = sizeof(dd);
3328 for (device = 0; EnumDisplayDevicesA(NULL, device, &dd, 0); ++device)
3330 INT number;
3332 /* Skip software devices */
3333 if (sscanf(dd.DeviceName, "\\\\.\\DISPLAY%d", &number) != 1)
3334 continue;
3336 attached = dd.StateFlags & DISPLAY_DEVICE_ATTACHED_TO_DESKTOP;
3338 memset(&dm, 0, sizeof(dm));
3339 dm.dmSize = sizeof(dm);
3340 SetLastError(0xdeadbeef);
3341 for (mode = ENUM_REGISTRY_SETTINGS; EnumDisplaySettingsA(dd.DeviceName, mode, &dm); ++mode)
3343 if (mode == ENUM_CURRENT_SETTINGS)
3345 ok((dm.dmFields & setting_fields) == setting_fields,
3346 "Expect dmFields to contain %#lx, got %#lx\n", setting_fields, dm.dmFields);
3348 else
3350 ok((dm.dmFields & mode_fields) == mode_fields, "Expect dmFields to contain %#lx, got %#lx\n",
3351 mode_fields, dm.dmFields);
3354 ok(dm.dmDisplayOrientation == DMDO_DEFAULT, "Expect dmDisplayOrientation DMDO_DEFAULT, got %#lx\n",
3355 dm.dmDisplayOrientation);
3356 ok(dm.dmDisplayFlags == 0, "Expect dmDisplayFlags zero\n");
3358 if (mode == ENUM_CURRENT_SETTINGS && !attached)
3360 ok(dm.dmBitsPerPel == 0, "Expect dmBitsPerPel zero, got %lu\n", dm.dmBitsPerPel);
3361 ok(dm.dmPelsWidth == 0, "Expect dmPelsWidth zero, got %lu\n", dm.dmPelsWidth);
3362 ok(dm.dmPelsHeight == 0, "Expect dmPelsHeight zero, got %lu\n", dm.dmPelsHeight);
3363 ok(dm.dmDisplayFrequency == 0, "Expect dmDisplayFrequency zero, got %lu\n", dm.dmDisplayFrequency);
3365 else if (mode != ENUM_REGISTRY_SETTINGS)
3367 ok(dm.dmBitsPerPel, "Expect dmBitsPerPel not zero\n");
3368 ok(dm.dmPelsWidth, "Expect dmPelsWidth not zero\n");
3369 ok(dm.dmPelsHeight, "Expect dmPelsHeight not zero\n");
3370 ok(dm.dmDisplayFrequency, "Expect dmDisplayFrequency not zero\n");
3374 ok(mode >= 1, "Expect at least one valid mode gets enumerated.\n");
3376 err = GetLastError();
3377 ok(err == ERROR_NO_MORE_FILES ||
3378 err == ERROR_MOD_NOT_FOUND /* Win8 */ ||
3379 err == 0xdeadbeef, /* XP, 2003 */
3380 "Expected ERROR_NO_MORE_FILES, ERROR_MOD_NOT_FOUND or 0xdeadbeef, got %#lx\n", err);
3384 static void test_GetSysColorBrush(void)
3386 HBRUSH hbr;
3388 SetLastError(0xdeadbeef);
3389 hbr = GetSysColorBrush(-1);
3390 ok(hbr == NULL, "Expected NULL brush\n");
3391 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %lx\n", GetLastError());
3392 /* greater than max index */
3393 hbr = GetSysColorBrush(COLOR_MENUBAR);
3394 if (hbr)
3396 SetLastError(0xdeadbeef);
3397 hbr = GetSysColorBrush(COLOR_MENUBAR + 1);
3398 ok(hbr == NULL, "Expected NULL brush\n");
3399 ok(GetLastError() == 0xdeadbeef, "Expected last error not set, got %lx\n", GetLastError());
3401 else
3402 win_skip("COLOR_MENUBAR unsupported\n");
3405 static void test_dpi_stock_objects( HDC hdc )
3407 DPI_AWARENESS_CONTEXT context;
3408 HGDIOBJ obj[STOCK_LAST + 1], obj2[STOCK_LAST + 1];
3409 LOGFONTW lf, lf2;
3410 UINT i, dpi;
3412 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3413 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3414 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
3415 ok( !pIsProcessDPIAware(), "not aware\n" );
3416 for (i = 0; i <= STOCK_LAST; i++) obj[i] = GetStockObject( i );
3418 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
3419 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
3420 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
3421 ok( pIsProcessDPIAware(), "not aware\n" );
3422 for (i = 0; i <= STOCK_LAST; i++) obj2[i] = GetStockObject( i );
3424 for (i = 0; i <= STOCK_LAST; i++)
3426 switch (i)
3428 case OEM_FIXED_FONT:
3429 case SYSTEM_FIXED_FONT:
3430 ok( obj[i] != obj2[i], "%u: same object\n", i );
3431 break;
3432 case SYSTEM_FONT:
3433 case DEFAULT_GUI_FONT:
3434 ok( obj[i] != obj2[i], "%u: same object\n", i );
3435 GetObjectW( obj[i], sizeof(lf), &lf );
3436 GetObjectW( obj2[i], sizeof(lf2), &lf2 );
3437 ok( lf.lfHeight == MulDiv( lf2.lfHeight, USER_DEFAULT_SCREEN_DPI, real_dpi ),
3438 "%u: wrong height %ld / %ld\n", i, lf.lfHeight, lf2.lfHeight );
3439 break;
3440 default:
3441 ok( obj[i] == obj2[i], "%u: different object\n", i );
3442 break;
3446 pSetThreadDpiAwarenessContext( context );
3449 static void scale_point_dpi( POINT *pt, UINT src_dpi, UINT target_dpi )
3451 pt->x = MulDiv( pt->x, target_dpi, src_dpi );
3452 pt->y = MulDiv( pt->y, target_dpi, src_dpi );
3455 static void scale_rect_dpi( RECT *rect, UINT src_dpi, UINT target_dpi )
3457 rect->left = MulDiv( rect->left, target_dpi, src_dpi );
3458 rect->top = MulDiv( rect->top, target_dpi, src_dpi );
3459 rect->right = MulDiv( rect->right, target_dpi, src_dpi );
3460 rect->bottom = MulDiv( rect->bottom, target_dpi, src_dpi );
3463 static void scale_point_dpi_aware( POINT *pt, DPI_AWARENESS from, DPI_AWARENESS to )
3465 if (from == DPI_AWARENESS_UNAWARE && to != DPI_AWARENESS_UNAWARE)
3466 scale_point_dpi( pt, USER_DEFAULT_SCREEN_DPI, real_dpi );
3467 else if (from != DPI_AWARENESS_UNAWARE && to == DPI_AWARENESS_UNAWARE)
3468 scale_point_dpi( pt, real_dpi, USER_DEFAULT_SCREEN_DPI );
3471 static void scale_rect_dpi_aware( RECT *rect, DPI_AWARENESS from, DPI_AWARENESS to )
3473 if (from == DPI_AWARENESS_UNAWARE && to != DPI_AWARENESS_UNAWARE)
3474 scale_rect_dpi( rect, USER_DEFAULT_SCREEN_DPI, real_dpi );
3475 else if (from != DPI_AWARENESS_UNAWARE && to == DPI_AWARENESS_UNAWARE)
3476 scale_rect_dpi( rect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3479 static void test_dpi_mapping(void)
3481 HWND hwnd, child;
3482 HDC hdc;
3483 UINT win_dpi, units;
3484 POINT point;
3485 BOOL ret;
3486 HRGN rgn, update;
3487 RECT rect, orig, client, desktop, expect;
3488 ULONG_PTR i, j, k;
3489 WINDOWPLACEMENT wpl_orig, wpl;
3490 HMONITOR monitor;
3491 INT monitor_count;
3492 MONITORINFO mon_info;
3493 DPI_AWARENESS_CONTEXT context;
3495 if (!pLogicalToPhysicalPointForPerMonitorDPI)
3497 win_skip( "LogicalToPhysicalPointForPerMonitorDPI not supported\n" );
3498 return;
3500 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3501 GetWindowRect( GetDesktopWindow(), &desktop );
3502 monitor_count = GetSystemMetrics( SM_CMONITORS );
3503 for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
3505 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3506 /* test desktop rect */
3507 GetWindowRect( GetDesktopWindow(), &rect );
3508 expect = desktop;
3509 if (i == DPI_AWARENESS_UNAWARE) scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3510 ok( EqualRect( &expect, &rect ), "%Iu: wrong desktop rect %s expected %s\n",
3511 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3512 SetRect( &rect, 0, 0, GetSystemMetrics( SM_CXSCREEN ), GetSystemMetrics( SM_CYSCREEN ));
3513 ok( EqualRect( &expect, &rect ), "%Iu: wrong desktop rect %s expected %s\n",
3514 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3515 if (monitor_count < 2)
3517 SetRect( &rect, 0, 0, GetSystemMetrics( SM_CXVIRTUALSCREEN ), GetSystemMetrics( SM_CYVIRTUALSCREEN ));
3518 ok( EqualRect( &expect, &rect ), "%Iu: wrong virt desktop rect %s expected %s\n",
3519 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3521 SetRect( &rect, 0, 0, 1, 1 );
3522 monitor = MonitorFromRect( &rect, MONITOR_DEFAULTTOPRIMARY );
3523 ok( monitor != 0, "failed to get monitor\n" );
3524 mon_info.cbSize = sizeof(mon_info);
3525 ok( GetMonitorInfoW( monitor, &mon_info ), "GetMonitorInfoExW failed\n" );
3526 ok( EqualRect( &expect, &mon_info.rcMonitor ), "%Iu: wrong monitor rect %s expected %s\n",
3527 i, wine_dbgstr_rect(&mon_info.rcMonitor), wine_dbgstr_rect(&expect) );
3528 hdc = CreateDCA( "display", NULL, NULL, NULL );
3529 SetRect( &rect, 0, 0, GetDeviceCaps( hdc, HORZRES ), GetDeviceCaps( hdc, VERTRES ));
3530 ok( EqualRect( &expect, &rect ), "%Iu: wrong caps desktop rect %s expected %s\n",
3531 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3532 SetRect( &rect, 0, 0, GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ));
3533 todo_wine_if(monitor_count > 1)
3534 ok( EqualRect( &desktop, &rect ), "%Iu: wrong caps virt desktop rect %s expected %s\n",
3535 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&desktop) );
3536 DeleteDC( hdc );
3537 /* test message window rect */
3538 hwnd = CreateWindowA( "SysParamsTestClass", "test", WS_CHILD,
3539 10, 10, 20, 20, HWND_MESSAGE, 0, GetModuleHandleA(0), NULL );
3540 GetWindowRect( GetAncestor( hwnd, GA_PARENT ), &rect );
3541 SetRect( &expect, 0, 0, 100, 100 );
3542 if (i == DPI_AWARENESS_UNAWARE) scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3543 ok( EqualRect( &expect, &rect ), "%Iu: wrong message rect %s expected %s\n",
3544 i, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3545 DestroyWindow( hwnd );
3547 for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
3549 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
3550 hwnd = CreateWindowA( "SysParamsTestClass", "test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
3551 193, 177, 295, 303, 0, 0, GetModuleHandleA(0), NULL );
3552 ok( hwnd != 0, "creating window failed err %lu\n", GetLastError());
3553 child = CreateWindowA( "SysParamsTestClass", "child", WS_CHILD | WS_VISIBLE,
3554 50, 60, 70, 80, hwnd, 0, GetModuleHandleA(0), NULL );
3555 ok( child != 0, "creating child failed err %lu\n", GetLastError());
3556 GetWindowRect( hwnd, &orig );
3557 SetRect( &rect, 0, 0, 0, 0 );
3558 pAdjustWindowRectExForDpi( &rect, WS_OVERLAPPEDWINDOW, FALSE, 0, pGetDpiForWindow( hwnd ));
3559 SetRect( &client, orig.left - rect.left, orig.top - rect.top,
3560 orig.right - rect.right, orig.bottom - rect.bottom );
3561 ShowWindow( hwnd, SW_MINIMIZE );
3562 ShowWindow( hwnd, SW_RESTORE );
3563 GetWindowPlacement( hwnd, &wpl_orig );
3564 units = GetDialogBaseUnits();
3566 for (j = DPI_AWARENESS_UNAWARE; j <= DPI_AWARENESS_PER_MONITOR_AWARE; j++)
3568 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3569 /* test window rect */
3570 GetWindowRect( hwnd, &rect );
3571 expect = orig;
3572 scale_rect_dpi_aware( &expect, i, j );
3573 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong window rect %s expected %s\n",
3574 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3575 /* test client rect */
3576 GetClientRect( hwnd, &rect );
3577 expect = client;
3578 OffsetRect( &expect, -expect.left, -expect.top );
3579 scale_rect_dpi_aware( &expect, i, j );
3580 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong client rect %s expected %s\n",
3581 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3582 /* test window placement */
3583 GetWindowPlacement( hwnd, &wpl );
3584 point = wpl_orig.ptMinPosition;
3585 if (point.x != -1 || point.y != -1) scale_point_dpi_aware( &point, i, j );
3586 ok( wpl.ptMinPosition.x == point.x && wpl.ptMinPosition.y == point.y,
3587 "%Iu/%Iu: wrong placement min pos %ld,%ld expected %ld,%ld\n", i, j,
3588 wpl.ptMinPosition.x, wpl.ptMinPosition.y, point.x, point.y );
3589 point = wpl_orig.ptMaxPosition;
3590 if (point.x != -1 || point.y != -1) scale_point_dpi_aware( &point, i, j );
3591 ok( wpl.ptMaxPosition.x == point.x && wpl.ptMaxPosition.y == point.y,
3592 "%Iu/%Iu: wrong placement max pos %ld,%ld expected %ld,%ld\n", i, j,
3593 wpl.ptMaxPosition.x, wpl.ptMaxPosition.y, point.x, point.y );
3594 expect = wpl_orig.rcNormalPosition;
3595 scale_rect_dpi_aware( &expect, i, j );
3596 ok( EqualRect( &wpl.rcNormalPosition, &expect ),
3597 "%Iu/%Iu: wrong placement rect %s expect %s\n", i, j,
3598 wine_dbgstr_rect(&wpl.rcNormalPosition), wine_dbgstr_rect(&expect));
3599 /* test DC rect */
3600 hdc = GetDC( hwnd );
3601 GetClipBox( hdc, &rect );
3602 SetRect( &expect, 0, 0, client.right - client.left, client.bottom - client.top );
3603 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong clip box %s expected %s\n",
3604 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3605 /* test DC resolution */
3606 SetRect( &rect, 0, 0, GetDeviceCaps( hdc, HORZRES ), GetDeviceCaps( hdc, VERTRES ));
3607 expect = desktop;
3608 if (j == DPI_AWARENESS_UNAWARE) scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3609 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong DC resolution %s expected %s\n",
3610 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3611 SetRect( &rect, 0, 0, GetDeviceCaps( hdc, DESKTOPHORZRES ), GetDeviceCaps( hdc, DESKTOPVERTRES ));
3612 todo_wine_if(monitor_count > 1)
3613 ok( EqualRect( &desktop, &rect ), "%Iu/%Iu: wrong desktop resolution %s expected %s\n",
3614 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&desktop) );
3615 ReleaseDC( hwnd, hdc );
3616 /* test DC win rect */
3617 hdc = GetWindowDC( hwnd );
3618 GetClipBox( hdc, &rect );
3619 SetRect( &expect, 0, 0, 295, 303 );
3620 todo_wine
3621 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong clip box win DC %s expected %s\n",
3622 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3623 ReleaseDC( hwnd, hdc );
3624 /* test window invalidation */
3625 UpdateWindow( hwnd );
3626 update = CreateRectRgn( 0, 0, 0, 0 );
3627 ret = GetUpdateRgn( hwnd, update, FALSE );
3628 ok( ret == NULLREGION, "update region not empty\n" );
3629 rgn = CreateRectRgn( 20, 20, 25, 25 );
3630 for (k = DPI_AWARENESS_UNAWARE; k <= DPI_AWARENESS_PER_MONITOR_AWARE; k++)
3632 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~k );
3633 RedrawWindow( hwnd, 0, rgn, RDW_INVALIDATE );
3634 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3635 GetUpdateRgn( hwnd, update, FALSE );
3636 GetRgnBox( update, &rect );
3637 SetRect( &expect, 20, 20, 25, 25 );
3638 ok( EqualRect( &expect, &rect ), "%Iu/%Iu/%Iu: wrong update region %s expected %s\n",
3639 i, j, k, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3640 GetUpdateRect( hwnd, &rect, FALSE );
3641 scale_rect_dpi_aware( &expect, i, j );
3642 ok( EqualRect( &expect, &rect ), "%Iu/%Iu/%Iu: wrong update rect %s expected %s\n",
3643 i, j, k, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3644 UpdateWindow( hwnd );
3646 for (k = DPI_AWARENESS_UNAWARE; k <= DPI_AWARENESS_PER_MONITOR_AWARE; k++)
3648 RedrawWindow( hwnd, 0, rgn, RDW_INVALIDATE );
3649 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~k );
3650 GetUpdateRgn( hwnd, update, FALSE );
3651 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3652 GetRgnBox( update, &rect );
3653 SetRect( &expect, 20, 20, 25, 25 );
3654 ok( EqualRect( &expect, &rect ), "%Iu/%Iu/%Iu: wrong update region %s expected %s\n",
3655 i, j, k, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3656 GetUpdateRect( hwnd, &rect, FALSE );
3657 scale_rect_dpi_aware( &expect, i, j );
3658 ok( EqualRect( &expect, &rect ), "%Iu/%Iu/%Iu: wrong update rect %s expected %s\n",
3659 i, j, k, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3660 UpdateWindow( hwnd );
3662 /* test desktop window invalidation */
3663 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3664 GetClientRect( hwnd, &rect );
3665 InflateRect( &rect, -50, -50 );
3666 expect = rect;
3667 MapWindowPoints( hwnd, 0, (POINT *)&rect, 2 );
3668 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3669 RedrawWindow( 0, &rect, 0, RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN );
3670 GetUpdateRgn( hwnd, update, TRUE );
3671 GetRgnBox( update, &rect );
3672 if (i == DPI_AWARENESS_UNAWARE) scale_rect_dpi( &expect, real_dpi, USER_DEFAULT_SCREEN_DPI );
3673 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong update region %s expected %s\n",
3674 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3675 GetUpdateRect( hwnd, &rect, FALSE );
3676 scale_rect_dpi_aware( &expect, i, j );
3677 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong update rect %s expected %s\n",
3678 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3679 UpdateWindow( hwnd );
3680 DeleteObject( update );
3681 /* test dialog units */
3682 ret = GetDialogBaseUnits();
3683 point.x = LOWORD( units );
3684 point.y = HIWORD( units );
3685 scale_point_dpi_aware( &point, i, j );
3686 ok( LOWORD(ret) == point.x && HIWORD(ret) == point.y, "%Iu/%Iu: wrong units %d,%d / %ld,%ld\n",
3687 i, j, LOWORD(ret), HIWORD(ret), point.x, point.y );
3688 /* test window points mapping */
3689 SetRect( &rect, 0, 0, 100, 100 );
3690 rect.right = rect.left + 100;
3691 rect.bottom = rect.top + 100;
3692 MapWindowPoints( hwnd, 0, (POINT *)&rect, 2 );
3693 expect = client;
3694 scale_rect_dpi_aware( &expect, i, j );
3695 expect.right = expect.left + 100;
3696 expect.bottom = expect.top + 100;
3697 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong MapWindowPoints rect %s expected %s\n",
3698 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3699 SetRect( &rect, 50, 60, 70, 80 );
3700 scale_rect_dpi_aware( &rect, i, j );
3701 SetRect( &expect, 40, 30, 60, 80 );
3702 OffsetRect( &expect, -rect.left, -rect.top );
3703 SetRect( &rect, 40, 30, 60, 80 );
3704 MapWindowPoints( hwnd, child, (POINT *)&rect, 2 );
3705 ok( EqualRect( &expect, &rect ), "%Iu/%Iu: wrong MapWindowPoints child rect %s expected %s\n",
3706 i, j, wine_dbgstr_rect(&rect), wine_dbgstr_rect(&expect) );
3707 /* test logical<->physical coords mapping */
3708 win_dpi = pGetDpiForWindow( hwnd );
3709 if (i == DPI_AWARENESS_UNAWARE)
3710 ok( win_dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", win_dpi );
3711 else if (i == DPI_AWARENESS_SYSTEM_AWARE)
3712 ok( win_dpi == real_dpi, "wrong dpi %u / %u\n", win_dpi, real_dpi );
3713 point.x = 373;
3714 point.y = 377;
3715 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3716 ok( ret, "%Iu/%Iu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3717 ok( point.x == MulDiv( 373, real_dpi, win_dpi ) &&
3718 point.y == MulDiv( 377, real_dpi, win_dpi ),
3719 "%Iu/%Iu: wrong pos %ld,%ld dpi %u\n", i, j, point.x, point.y, win_dpi );
3720 point.x = 405;
3721 point.y = 423;
3722 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3723 ok( ret, "%Iu/%Iu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3724 ok( point.x == MulDiv( 405, win_dpi, real_dpi ) &&
3725 point.y == MulDiv( 423, win_dpi, real_dpi ),
3726 "%Iu/%Iu: wrong pos %ld,%ld dpi %u\n", i, j, point.x, point.y, win_dpi );
3727 /* point outside the window fails, but note that Windows (wrongly) checks against the
3728 * window rect transformed relative to the thread's awareness */
3729 GetWindowRect( hwnd, &rect );
3730 point.x = rect.left - 1;
3731 point.y = rect.top;
3732 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3733 ok( !ret, "%Iu/%Iu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3734 point.x++;
3735 point.y--;
3736 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3737 ok( !ret, "%Iu/%Iu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3738 point.y++;
3739 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3740 ok( ret, "%Iu/%Iu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3741 point.x = rect.right;
3742 point.y = rect.bottom + 1;
3743 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3744 ok( !ret, "%Iu/%Iu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3745 point.x++;
3746 point.y--;
3747 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3748 ok( !ret, "%Iu/%Iu: LogicalToPhysicalPointForPerMonitorDPI succeeded\n", i, j );
3749 point.x--;
3750 ret = pLogicalToPhysicalPointForPerMonitorDPI( hwnd, &point );
3751 ok( ret, "%Iu/%Iu: LogicalToPhysicalPointForPerMonitorDPI failed\n", i, j );
3752 /* get physical window rect */
3753 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
3754 GetWindowRect( hwnd, &rect );
3755 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
3756 point.x = rect.left - 1;
3757 point.y = rect.top;
3758 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3759 ok( !ret, "%Iu/%Iu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3760 point.x++;
3761 point.y--;
3762 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3763 ok( !ret, "%Iu/%Iu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3764 point.y++;
3765 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3766 ok( ret, "%Iu/%Iu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3767 point.x = rect.right;
3768 point.y = rect.bottom + 1;
3769 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3770 ok( !ret, "%Iu/%Iu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3771 point.x++;
3772 point.y--;
3773 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3774 ok( !ret, "%Iu/%Iu: PhysicalToLogicalPointForPerMonitorDPI succeeded\n", i, j );
3775 point.x--;
3776 ret = pPhysicalToLogicalPointForPerMonitorDPI( hwnd, &point );
3777 ok( ret, "%Iu/%Iu: PhysicalToLogicalPointForPerMonitorDPI failed\n", i, j );
3779 DestroyWindow( hwnd );
3781 pSetThreadDpiAwarenessContext( context );
3784 static void test_dpi_aware(void)
3786 BOOL ret;
3788 if (!pIsProcessDPIAware)
3790 win_skip("IsProcessDPIAware not available\n");
3791 return;
3794 ret = pSetProcessDPIAware();
3795 ok(ret, "got %d\n", ret);
3797 ret = pIsProcessDPIAware();
3798 ok(ret, "got %d\n", ret);
3800 dpi = real_dpi;
3801 test_GetSystemMetrics();
3802 test_metrics_for_dpi( 96 );
3803 test_metrics_for_dpi( 192 );
3806 static void test_SetProcessDpiAwarenessContext( ULONG arg )
3808 DPI_AWARENESS_CONTEXT contexts[] =
3810 (DPI_AWARENESS_CONTEXT)0x6010,
3811 (DPI_AWARENESS_CONTEXT)0x40006010,
3812 (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | (real_dpi << 8)),
3813 (DPI_AWARENESS_CONTEXT)0x12,
3814 (DPI_AWARENESS_CONTEXT)0x22,
3816 DPI_AWARENESS_CONTEXT context, ctx, old_ctx, expect_ctx;
3817 UINT ret, i;
3819 /* 0x11 is system aware DPI and only works with the current system DPI */
3820 if (arg == 0x11) context = contexts[2];
3821 else context = LongToHandle( arg ) /* sign-extend */;
3823 if (context == DPI_AWARENESS_CONTEXT_UNAWARE) expect_ctx = contexts[0];
3824 else if (context == DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED) expect_ctx = contexts[1];
3825 else if (context == DPI_AWARENESS_CONTEXT_SYSTEM_AWARE) expect_ctx = contexts[2];
3826 else if (context == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE) expect_ctx = contexts[3];
3827 else if (context == DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2) expect_ctx = contexts[4];
3828 else if ((arg & 0xff000000) == 0x80000000) expect_ctx = ULongToHandle( arg ) /* no sign-extend */;
3829 else expect_ctx = context;
3831 winetest_push_context( "%#lx", arg );
3833 ctx = pGetThreadDpiAwarenessContext();
3834 todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
3836 SetLastError( 0xdeadbeef );
3837 ret = pSetProcessDpiAwarenessContext( 0 );
3838 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3839 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3840 SetLastError( 0xdeadbeef );
3841 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x11 );
3842 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3843 ok( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_ACCESS_DENIED, "got %#lx\n", GetLastError() );
3844 SetLastError( 0xdeadbeef );
3845 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x21 );
3846 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3847 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3848 SetLastError( 0xdeadbeef );
3849 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x32 );
3850 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3851 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3852 SetLastError( 0xdeadbeef );
3853 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6012 );
3854 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3855 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3856 SetLastError( 0xdeadbeef );
3857 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6022 );
3858 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3859 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3860 SetLastError( 0xdeadbeef );
3861 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x40006011 );
3862 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3863 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3864 SetLastError( 0xdeadbeef );
3865 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x40000012 );
3866 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3867 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3868 SetLastError( 0xdeadbeef );
3869 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x7810 );
3870 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3871 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3872 SetLastError( 0xdeadbeef );
3873 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x1ff11 );
3874 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3875 todo_wine ok( GetLastError() == ERROR_ACCESS_DENIED, "got %#lx\n", GetLastError() );
3876 ctx = pGetThreadDpiAwarenessContext();
3877 todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
3879 SetLastError( 0xdeadbeef );
3880 ret = pSetProcessDpiAwarenessContext( context );
3881 todo_wine ok( ret, "SetProcessDpiAwarenessContext failed, error %lu\n", GetLastError() );
3882 todo_wine ok( GetLastError() == 0xdeadbeef, "got %#lx\n", GetLastError() );
3883 ctx = pGetThreadDpiAwarenessContext();
3884 todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3885 ok( ctx == expect_ctx, "got %p\n", ctx );
3887 for (i = 0; i < ARRAY_SIZE(contexts); i++)
3889 SetLastError( 0xdeadbeef );
3890 ret = pSetProcessDpiAwarenessContext( contexts[i] );
3891 ok( !ret, "SetProcessDpiAwarenessContext succeeded\n" );
3892 ok( GetLastError() == ERROR_ACCESS_DENIED, "got %#lx\n", GetLastError() );
3893 ctx = pGetThreadDpiAwarenessContext();
3894 todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3895 ok( ctx == expect_ctx, "got %p\n", ctx );
3898 /* thread DPI context overrides process DPI context */
3899 ctx = pGetThreadDpiAwarenessContext();
3900 todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3901 ok( ctx == expect_ctx, "got %p\n", ctx );
3902 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
3903 todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3904 ok( old_ctx == (DPI_AWARENESS_CONTEXT)ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx );
3905 ctx = pGetThreadDpiAwarenessContext();
3906 ok( ctx == (DPI_AWARENESS_CONTEXT)0x12, "got %p\n", ctx );
3907 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x22 );
3908 ok( old_ctx == ctx, "got %p\n", old_ctx );
3909 ctx = pGetThreadDpiAwarenessContext();
3910 ok( ctx == (DPI_AWARENESS_CONTEXT)0x22, "got %p\n", ctx );
3912 /* thread DPI context can be reset to process DPI context with 0x80000000, but needs to be valid */
3913 SetLastError( 0xdeadbeef );
3914 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000000 );
3915 ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" );
3916 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3917 SetLastError( 0xdeadbeef );
3918 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000010 );
3919 ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" );
3920 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %#lx\n", GetLastError() );
3922 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006010 );
3923 ok( old_ctx == ctx, "got %p\n", old_ctx );
3924 ctx = pGetThreadDpiAwarenessContext();
3925 todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3926 ok( ctx == expect_ctx, "got %p\n", ctx );
3927 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x80000011 | (real_dpi << 8)) );
3928 todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3929 ok( old_ctx == ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx );
3930 ctx = pGetThreadDpiAwarenessContext();
3931 todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3932 ok( ctx == expect_ctx, "got %p\n", ctx );
3933 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000012 );
3934 todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3935 ok( old_ctx == ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx );
3936 ctx = pGetThreadDpiAwarenessContext();
3937 todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3938 ok( ctx == expect_ctx, "got %p\n", ctx );
3939 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000022 );
3940 todo_wine_if( arg != 0x12 && arg != 0x80000012 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3941 ok( old_ctx == ULongToHandle( 0x80000000 | (UINT_PTR)expect_ctx ), "got %p\n", old_ctx );
3942 ctx = pGetThreadDpiAwarenessContext();
3943 todo_wine_if( arg != 0x12 && context != DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE )
3944 ok( ctx == expect_ctx, "got %p\n", ctx );
3946 winetest_pop_context();
3949 static void test_SetThreadDpiAwarenessContext(void)
3951 DPI_AWARENESS_CONTEXT ctx, old_ctx;
3953 if (!pSetThreadDpiAwarenessContext || !pGetThreadDpiAwarenessContext)
3955 win_skip( "(Set|Get)ThreadDpiAwarenessContext missing, skipping tests\n" );
3956 return;
3959 ctx = pGetThreadDpiAwarenessContext();
3960 todo_wine ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
3962 old_ctx = pSetThreadDpiAwarenessContext( 0 );
3963 ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" );
3964 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x11 );
3965 ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" );
3967 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
3968 todo_wine ok( old_ctx == (DPI_AWARENESS_CONTEXT)0x80006010, "got %p\n", old_ctx );
3969 ctx = pGetThreadDpiAwarenessContext();
3970 ok( ctx == (DPI_AWARENESS_CONTEXT)0x12, "got %p\n", ctx );
3971 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x22 );
3972 ok( old_ctx == ctx, "got %p\n", old_ctx );
3973 ctx = pGetThreadDpiAwarenessContext();
3974 ok( ctx == (DPI_AWARENESS_CONTEXT)0x22, "got %p\n", ctx );
3976 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x7810 );
3977 ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" );
3978 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6010 );
3979 ok( old_ctx == ctx, "got %p\n", old_ctx );
3980 ctx = pGetThreadDpiAwarenessContext();
3981 ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
3983 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | ((real_dpi + 1) << 8)) );
3984 ok( !old_ctx, "SetThreadDpiAwarenessContext succeeded\n" );
3985 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | (real_dpi << 8)) );
3986 ok( old_ctx == ctx, "got %p\n", old_ctx );
3987 ctx = pGetThreadDpiAwarenessContext();
3988 ok( ctx == (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | (real_dpi << 8)), "got %p\n", ctx );
3990 old_ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x40006010 );
3991 ok( old_ctx == ctx, "got %p\n", old_ctx );
3992 ctx = pGetThreadDpiAwarenessContext();
3993 ok( ctx == (DPI_AWARENESS_CONTEXT)0x40006010, "got %p\n", ctx );
3995 old_ctx = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
3996 ok( old_ctx == ctx, "got %p\n", old_ctx );
3997 ctx = pGetThreadDpiAwarenessContext();
3998 ok( ctx == (DPI_AWARENESS_CONTEXT)0x6010, "got %p\n", ctx );
3999 old_ctx = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4000 ok( old_ctx == ctx, "got %p\n", old_ctx );
4001 ctx = pGetThreadDpiAwarenessContext();
4002 ok( ctx == (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | (real_dpi << 8)), "got %p\n", ctx );
4003 old_ctx = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4004 ok( old_ctx == ctx, "got %p\n", old_ctx );
4005 ctx = pGetThreadDpiAwarenessContext();
4006 ok( ctx == (DPI_AWARENESS_CONTEXT)0x12, "got %p\n", ctx );
4007 old_ctx = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 );
4008 ok( old_ctx == ctx, "got %p\n", old_ctx );
4009 ctx = pGetThreadDpiAwarenessContext();
4010 ok( ctx == (DPI_AWARENESS_CONTEXT)0x22, "got %p\n", ctx );
4011 old_ctx = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED );
4012 ok( old_ctx == ctx, "got %p\n", old_ctx );
4013 ctx = pGetThreadDpiAwarenessContext();
4014 ok( ctx == (DPI_AWARENESS_CONTEXT)0x40006010, "got %p\n", ctx );
4016 /* restore process-wide DPI awareness context */
4017 ctx = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006010 );
4018 ok( ctx == (DPI_AWARENESS_CONTEXT)0x40006010, "got %p\n", ctx );
4021 static void test_IsValidDpiAwarenessContext(void)
4023 UINT_PTR i;
4024 BOOL ret;
4026 if (!pIsValidDpiAwarenessContext)
4028 win_skip( "IsValidDpiAwarenessContext missing, skipping tests\n" );
4029 return;
4032 ret = pIsValidDpiAwarenessContext( 0 );
4033 ok( !ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4035 /* commonly seen dpi awareness contexts */
4036 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
4037 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4038 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x22 );
4039 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4040 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6010 );
4041 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4042 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6011 );
4043 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4044 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x40006010 );
4045 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4047 ret = pIsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4048 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4049 ret = pIsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4050 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4051 ret = pIsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4052 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4053 ret = pIsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 );
4054 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4055 ret = pIsValidDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED );
4056 ok( ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4057 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-6 );
4058 ok( !ret, "IsValidDpiAwarenessContext returned %u\n", ret );
4060 for (i = 1; i < 0xff; i++)
4062 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)i );
4063 if (i == 0x12 || i == 0x22) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", i );
4064 /* 0x0011 is rejected on win11 */
4065 else if (i != 0x11) ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", i );
4067 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)(i | 0x6000) );
4068 if (i == 0x10 || i == 0x11) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", (i | 0x6000) );
4069 /* 0x6013 is accepted on win11 */
4070 else if (i != 0x13) ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", (i | 0x6000) );
4072 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 8) | 0x10) );
4073 if (i == 0x60) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", ((i << 8) | 0x10) );
4074 else ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 8) | 0x10) );
4075 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 8) | 0x11) );
4076 if (i != 0xff) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", ((i << 8) | 0x11) );
4077 else ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 8) | 0x11) );
4078 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 8) | 0x12) );
4079 ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 8) | 0x12) );
4080 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 8) | 0x22) );
4081 ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 8) | 0x22) );
4083 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 16) | 0x6010) );
4084 ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 16) | 0x6010) );
4085 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 16) | (real_dpi << 8) | 0x11) );
4086 if (i == 1) ok( ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 16) | (real_dpi << 8) | 0x11) );
4087 else ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 16) | (real_dpi << 8) | 0x11) );
4088 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 16) | 0x12) );
4089 ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 16) | 0x12) );
4090 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 16) | 0x22) );
4091 ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 16) | 0x22) );
4093 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 24) | 0x6010) );
4094 if (i & 0x1f) ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 24) | 0x6010) );
4095 /* 0x20000000 is rejected on win11 */
4096 else if (!(i & 0x20)) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", ((i << 24) | 0x6010) );
4097 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 24) | (real_dpi << 8) | 0x11) );
4098 if (i & 0x5f) ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 24) | (real_dpi << 8) | 0x11) );
4099 /* 0x20000000 is rejected on win11 */
4100 else if (!(i & 0x20)) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", ((i << 24) | (real_dpi << 8) | 0x11) );
4101 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 24) | 0x12) );
4102 if (i & 0x5f) ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 24) | 0x12) );
4103 /* 0x20000000 is rejected on win11 */
4104 else if (!(i & 0x20)) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", ((i << 24) | 0x12) );
4105 ret = pIsValidDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)((i << 24) | 0x22) );
4106 if (i & 0x5f) ok( !ret, "IsValidDpiAwarenessContext %#Ix succeeded\n", ((i << 24) | 0x22) );
4107 /* 0x20000000 is rejected on win11 */
4108 else if (!(i & 0x20)) ok( ret, "IsValidDpiAwarenessContext %#Ix failed\n", ((i << 24) | 0x22) );
4112 static void test_GetDpiFromDpiAwarenessContext(void)
4114 UINT ret;
4116 if (!pGetDpiFromDpiAwarenessContext)
4118 win_skip( "GetDpiFromDpiAwarenessContext missing, skipping tests\n" );
4119 return;
4122 ret = pGetDpiFromDpiAwarenessContext( 0 );
4123 ok( !ret, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4125 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x11 );
4126 ok( ret == 0, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4127 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
4128 ok( ret == 0, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4129 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x22 );
4130 ok( ret == 0, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4131 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6010 );
4132 ok( ret == 96, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4133 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6011 );
4134 ok( ret == 96, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4135 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6111 );
4136 ok( ret == 97, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4137 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x7811 );
4138 ok( ret == 120, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4139 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x10011 );
4140 ok( ret == 256, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4141 ret = pGetDpiFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x40006010 );
4142 ok( ret == 96, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4144 ret = pGetDpiFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4145 ok( ret == 96, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4146 ret = pGetDpiFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4147 ok( ret == real_dpi, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4148 ret = pGetDpiFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4149 ok( ret == 0, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4150 ret = pGetDpiFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 );
4151 ok( ret == 0, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4152 ret = pGetDpiFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED );
4153 ok( ret == 96, "GetDpiFromDpiAwarenessContext returned %u\n", ret );
4156 static void test_AreDpiAwarenessContextsEqual(void)
4158 BOOL ret;
4160 if (!pAreDpiAwarenessContextsEqual)
4162 win_skip( "AreDpiAwarenessContextsEqual missing, skipping tests\n" );
4163 return;
4166 ret = pAreDpiAwarenessContextsEqual( 0, 0 );
4167 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4169 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x12, (DPI_AWARENESS_CONTEXT)0x12 );
4170 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4171 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x22, (DPI_AWARENESS_CONTEXT)0x22 );
4172 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4173 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x6010, (DPI_AWARENESS_CONTEXT)0x6010 );
4174 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4175 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x6011, (DPI_AWARENESS_CONTEXT)0x6011 );
4176 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4177 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x6111, (DPI_AWARENESS_CONTEXT)0x6111 );
4178 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4179 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x7811, (DPI_AWARENESS_CONTEXT)0x7811 );
4180 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4181 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x40006010, (DPI_AWARENESS_CONTEXT)0x40006010 );
4182 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4184 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_UNAWARE, DPI_AWARENESS_CONTEXT_UNAWARE );
4185 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4186 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4187 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4188 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4189 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4190 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 );
4191 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4192 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED );
4193 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4195 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_UNAWARE, (DPI_AWARENESS_CONTEXT)0x6010 );
4196 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4197 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x6010, DPI_AWARENESS_CONTEXT_UNAWARE );
4198 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4199 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_UNAWARE, (DPI_AWARENESS_CONTEXT)0x10 );
4200 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4202 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | (real_dpi << 8)) );
4203 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4204 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)((UINT_PTR)0x11 | (real_dpi << 8)), DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4205 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4206 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE, (DPI_AWARENESS_CONTEXT)0x11 );
4207 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4209 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE, (DPI_AWARENESS_CONTEXT)0x12 );
4210 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4211 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x12, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4212 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4213 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2, (DPI_AWARENESS_CONTEXT)0x22 );
4214 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4215 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x22, DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 );
4216 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4217 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, (DPI_AWARENESS_CONTEXT)0x40006010 );
4218 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4219 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x40006010, DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED );
4220 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4221 ret = pAreDpiAwarenessContextsEqual( DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED, (DPI_AWARENESS_CONTEXT)0x40000010 );
4222 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4224 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x10, (DPI_AWARENESS_CONTEXT)0x6010 );
4225 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4226 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x11, (DPI_AWARENESS_CONTEXT)0x6011 );
4227 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4228 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x12, (DPI_AWARENESS_CONTEXT)0x6012 );
4229 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4230 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x22, (DPI_AWARENESS_CONTEXT)0x6022 );
4231 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4232 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x20006010, (DPI_AWARENESS_CONTEXT)0x6010 );
4233 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4234 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x40006010, (DPI_AWARENESS_CONTEXT)0x6010 );
4235 ok( !ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4236 ret = pAreDpiAwarenessContextsEqual( (DPI_AWARENESS_CONTEXT)0x80006010, (DPI_AWARENESS_CONTEXT)0x6010 );
4237 ok( ret, "AreDpiAwarenessContextsEqual returned %u\n", ret );
4240 static void test_GetAwarenessFromDpiAwarenessContext(void)
4242 DPI_AWARENESS ret;
4244 if (!pGetAwarenessFromDpiAwarenessContext)
4246 win_skip( "GetAwarenessFromDpiAwarenessContext missing, skipping tests\n" );
4247 return;
4250 ret = pGetAwarenessFromDpiAwarenessContext( 0 );
4251 ok( ret == -1, "got %u\n", ret );
4253 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
4254 ok( ret == DPI_AWARENESS_PER_MONITOR_AWARE, "got %u\n", ret );
4255 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x22 );
4256 ok( ret == DPI_AWARENESS_PER_MONITOR_AWARE, "got %u\n", ret );
4257 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6010 );
4258 ok( ret == DPI_AWARENESS_UNAWARE, "got %u\n", ret );
4259 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6011 );
4260 ok( ret == DPI_AWARENESS_SYSTEM_AWARE, "got %u\n", ret );
4261 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x6111 );
4262 ok( ret == DPI_AWARENESS_SYSTEM_AWARE, "got %u\n", ret );
4263 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x7811 );
4264 ok( ret == DPI_AWARENESS_SYSTEM_AWARE, "got %u\n", ret );
4265 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x10011 );
4266 ok( ret == DPI_AWARENESS_SYSTEM_AWARE, "got %u\n", ret );
4267 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x40006010 );
4268 ok( ret == DPI_AWARENESS_UNAWARE, "got %u\n", ret );
4269 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80000012 );
4270 ok( ret == DPI_AWARENESS_PER_MONITOR_AWARE, "got %u\n", ret );
4271 ret = pGetAwarenessFromDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006010 );
4272 ok( ret == DPI_AWARENESS_UNAWARE, "got %u\n", ret );
4274 ret = pGetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4275 ok( ret == DPI_AWARENESS_UNAWARE, "got %u\n", ret );
4276 ret = pGetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4277 ok( ret == DPI_AWARENESS_SYSTEM_AWARE, "got %u\n", ret );
4278 ret = pGetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4279 ok( ret == DPI_AWARENESS_PER_MONITOR_AWARE, "got %u\n", ret );
4280 ret = pGetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 );
4281 ok( ret == DPI_AWARENESS_PER_MONITOR_AWARE, "got %u\n", ret );
4282 ret = pGetAwarenessFromDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE_GDISCALED );
4283 ok( ret == DPI_AWARENESS_UNAWARE, "got %u\n", ret );
4286 static void test_dpi_context(void)
4288 DPI_AWARENESS awareness;
4289 DPI_AWARENESS_CONTEXT context;
4290 BOOL ret;
4291 UINT dpi;
4292 HDC hdc = GetDC( 0 );
4294 context = pGetThreadDpiAwarenessContext();
4295 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6010, "wrong context %p\n", context );
4296 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4297 todo_wine
4298 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
4299 todo_wine
4300 ok( !pIsProcessDPIAware(), "already aware\n" );
4301 dpi = pGetDpiForSystem();
4302 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
4303 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
4304 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
4305 todo_wine_if (real_dpi != USER_DEFAULT_SCREEN_DPI)
4306 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
4307 SetLastError( 0xdeadbeef );
4308 ret = pSetProcessDpiAwarenessContext( NULL );
4309 ok( !ret, "got %d\n", ret );
4310 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
4311 SetLastError( 0xdeadbeef );
4312 ret = pSetProcessDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-6 );
4313 ok( !ret, "got %d\n", ret );
4314 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
4315 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4316 todo_wine
4317 ok( ret, "got %d\n", ret );
4318 ok( pIsProcessDPIAware(), "not aware\n" );
4319 real_dpi = pGetDpiForSystem();
4320 SetLastError( 0xdeadbeef );
4321 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4322 ok( !ret, "got %d\n", ret );
4323 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
4324 SetLastError( 0xdeadbeef );
4325 ret = pSetProcessDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4326 ok( !ret, "got %d\n", ret );
4327 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
4329 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_INVALID );
4330 ok( !ret, "got %d\n", ret );
4331 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
4332 ret = pSetProcessDpiAwarenessInternal( DPI_AWARENESS_UNAWARE );
4333 ok( !ret, "got %d\n", ret );
4334 ok( GetLastError() == ERROR_ACCESS_DENIED, "wrong error %lu\n", GetLastError() );
4335 ret = pGetProcessDpiAwarenessInternal( 0, &awareness );
4336 ok( ret, "got %d\n", ret );
4337 todo_wine
4338 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
4339 ret = pGetProcessDpiAwarenessInternal( GetCurrentProcess(), &awareness );
4340 ok( ret, "got %d\n", ret );
4341 todo_wine
4342 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong value %d\n", awareness );
4343 SetLastError(0xdeadbeef);
4344 ret = pGetProcessDpiAwarenessInternal( (HANDLE)0xdeadbeef, &awareness );
4345 todo_wine
4346 ok( !ret || broken(ret) /* <= win10 1709 */, "got %d\n", ret );
4347 if (!ret)
4349 ok( GetLastError() == ERROR_INVALID_PARAMETER, "got %lu\n", GetLastError() );
4350 ok( awareness == DPI_AWARENESS_INVALID, "wrong value %d\n", awareness );
4352 else ok( awareness == DPI_AWARENESS_UNAWARE, "wrong value %d\n", awareness );
4354 ret = pIsProcessDPIAware();
4355 ok(ret, "got %d\n", ret);
4356 context = pGetThreadDpiAwarenessContext();
4357 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context );
4358 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4359 todo_wine
4360 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
4361 SetLastError( 0xdeadbeef );
4362 context = pSetThreadDpiAwarenessContext( 0 );
4363 ok( !context, "got %p\n", context );
4364 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
4365 SetLastError( 0xdeadbeef );
4366 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)-6 );
4367 ok( !context, "got %p\n", context );
4368 ok( GetLastError() == ERROR_INVALID_PARAMETER, "wrong error %lu\n", GetLastError() );
4369 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4370 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context );
4371 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4372 todo_wine
4373 ok( awareness == DPI_AWARENESS_SYSTEM_AWARE, "wrong awareness %u\n", awareness );
4374 dpi = pGetDpiForSystem();
4375 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
4376 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
4377 ok( dpi == USER_DEFAULT_SCREEN_DPI, "wrong dpi %u\n", dpi );
4378 ok( !pIsProcessDPIAware(), "still aware\n" );
4379 context = pGetThreadDpiAwarenessContext();
4380 ok( context == (DPI_AWARENESS_CONTEXT)0x6010, "wrong context %p\n", context );
4381 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4382 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
4383 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4384 ok( context == (DPI_AWARENESS_CONTEXT)0x6010, "wrong context %p\n", context );
4385 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4386 ok( awareness == DPI_AWARENESS_UNAWARE, "wrong awareness %u\n", awareness );
4387 dpi = pGetDpiForSystem();
4388 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
4389 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
4390 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
4391 context = pGetThreadDpiAwarenessContext();
4392 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
4393 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4394 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
4395 context = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_SYSTEM_AWARE );
4396 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
4397 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4398 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
4399 dpi = pGetDpiForSystem();
4400 ok( dpi == real_dpi, "wrong dpi %u/%u\n", dpi, real_dpi );
4401 dpi = GetDeviceCaps( hdc, LOGPIXELSX );
4402 ok( dpi == real_dpi, "wrong dpi %u\n", dpi );
4403 ok( pIsProcessDPIAware(), "not aware\n" );
4404 context = pGetThreadDpiAwarenessContext();
4405 ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context );
4406 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006010 );
4407 ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context );
4408 context = pGetThreadDpiAwarenessContext();
4409 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context );
4410 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x80006011 );
4411 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context );
4412 context = pGetThreadDpiAwarenessContext();
4413 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context );
4414 context = pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)0x12 );
4415 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x80006011, "wrong context %p\n", context );
4416 context = pSetThreadDpiAwarenessContext( context );
4417 ok( context == (DPI_AWARENESS_CONTEXT)0x12, "wrong context %p\n", context );
4418 context = pGetThreadDpiAwarenessContext();
4419 todo_wine ok( context == (DPI_AWARENESS_CONTEXT)0x6011, "wrong context %p\n", context );
4421 if (real_dpi != USER_DEFAULT_SCREEN_DPI) test_dpi_stock_objects( hdc );
4422 ReleaseDC( 0, hdc );
4425 static LRESULT CALLBACK dpi_winproc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
4427 DPI_AWARENESS_CONTEXT ctx = pGetWindowDpiAwarenessContext( hwnd );
4428 DPI_AWARENESS_CONTEXT ctx2 = pGetThreadDpiAwarenessContext();
4429 DWORD pos, pos2;
4431 ok( pGetAwarenessFromDpiAwarenessContext( ctx ) == pGetAwarenessFromDpiAwarenessContext( ctx2 ),
4432 "msg %04x wrong awareness %p / %p\n", msg, ctx, ctx2 );
4433 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4434 pos = GetMessagePos();
4435 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE );
4436 pos2 = GetMessagePos();
4437 ok( pos == pos2, "wrong pos %08lx / %08lx\n", pos, pos2 );
4438 pSetThreadDpiAwarenessContext( ctx2 );
4439 return DefWindowProcA( hwnd, msg, wp, lp );
4442 static void test_dpi_window(void)
4444 DPI_AWARENESS_CONTEXT context, orig;
4445 DPI_AWARENESS awareness;
4446 ULONG_PTR i, j;
4447 UINT dpi;
4448 HWND hwnd, child, ret;
4449 MSG msg = { 0, WM_USER + 1, 0, 0 };
4451 if (!pGetWindowDpiAwarenessContext)
4453 win_skip( "GetWindowDpiAwarenessContext not supported\n" );
4454 return;
4456 orig = pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4457 for (i = DPI_AWARENESS_UNAWARE; i <= DPI_AWARENESS_PER_MONITOR_AWARE; i++)
4459 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~i );
4460 hwnd = CreateWindowA( "DpiTestClass", "Test",
4461 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
4462 ok( hwnd != 0, "failed to create window\n" );
4463 context = pGetWindowDpiAwarenessContext( hwnd );
4464 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4465 ok( awareness == i, "%Iu: wrong awareness %u\n", i, awareness );
4466 dpi = pGetDpiForWindow( hwnd );
4467 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
4468 "%Iu: got %u / %u\n", i, dpi, real_dpi );
4469 if (pGetDpiForMonitorInternal)
4471 BOOL res;
4472 SetLastError( 0xdeadbeef );
4473 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 0, &dpi, NULL );
4474 ok( !res, "succeeded\n" );
4475 ok( GetLastError() == ERROR_INVALID_ADDRESS, "wrong error %lu\n", GetLastError() );
4476 SetLastError( 0xdeadbeef );
4477 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 3, &dpi, &dpi );
4478 ok( !res, "succeeded\n" );
4479 ok( GetLastError() == ERROR_BAD_ARGUMENTS, "wrong error %lu\n", GetLastError() );
4480 SetLastError( 0xdeadbeef );
4481 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 3, &dpi, NULL );
4482 ok( !res, "succeeded\n" );
4483 ok( GetLastError() == ERROR_BAD_ARGUMENTS, "wrong error %lu\n", GetLastError() );
4484 res = pGetDpiForMonitorInternal( MonitorFromWindow( hwnd, 0 ), 0, &dpi, &dpi );
4485 ok( res, "failed err %lu\n", GetLastError() );
4486 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
4487 "%Iu: got %u / %u\n", i, dpi, real_dpi );
4489 msg.hwnd = hwnd;
4490 for (j = DPI_AWARENESS_UNAWARE; j <= DPI_AWARENESS_PER_MONITOR_AWARE; j++)
4492 pSetThreadDpiAwarenessContext( (DPI_AWARENESS_CONTEXT)~j );
4493 SendMessageA( hwnd, WM_USER, 0, 0 );
4494 DispatchMessageA( &msg );
4495 CallWindowProcA( dpi_winproc, hwnd, WM_USER + 2, 0, 0 );
4496 child = CreateWindowA( "DpiTestClass", "Test",
4497 WS_CHILD, 0, 0, 100, 100, hwnd, 0, GetModuleHandleA(0), NULL );
4498 context = pGetWindowDpiAwarenessContext( child );
4499 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4500 ok( awareness == i, "%Iu/%Iu: wrong awareness %u\n", i, j, awareness );
4501 dpi = pGetDpiForWindow( child );
4502 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
4503 "%Iu/%Iu: got %u / %u\n", i, j, dpi, real_dpi );
4504 ret = SetParent( child, NULL );
4505 ok( ret != 0, "SetParent failed err %lu\n", GetLastError() );
4506 context = pGetWindowDpiAwarenessContext( child );
4507 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4508 ok( awareness == i, "%Iu/%Iu: wrong awareness %u\n", i, j, awareness );
4509 dpi = pGetDpiForWindow( child );
4510 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
4511 "%Iu/%Iu: got %u / %u\n", i, j, dpi, real_dpi );
4512 DestroyWindow( child );
4513 child = CreateWindowA( "DpiTestClass", "Test",
4514 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
4515 context = pGetWindowDpiAwarenessContext( child );
4516 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4517 ok( awareness == j, "%Iu/%Iu: wrong awareness %u\n", i, j, awareness );
4518 dpi = pGetDpiForWindow( child );
4519 ok( dpi == (j == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
4520 "%Iu/%Iu: got %u / %u\n", i, j, dpi, real_dpi );
4521 ret = SetParent( child, hwnd );
4522 ok( ret != 0 || GetLastError() == ERROR_INVALID_STATE,
4523 "SetParent failed err %lu\n", GetLastError() );
4524 context = pGetWindowDpiAwarenessContext( child );
4525 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4526 ok( awareness == (ret ? i : j), "%Iu/%Iu: wrong awareness %u\n", i, j, awareness );
4527 dpi = pGetDpiForWindow( child );
4528 ok( dpi == (i == DPI_AWARENESS_UNAWARE ? USER_DEFAULT_SCREEN_DPI : real_dpi),
4529 "%Iu/%Iu: got %u / %u\n", i, j, dpi, real_dpi );
4530 DestroyWindow( child );
4532 DestroyWindow( hwnd );
4535 SetLastError( 0xdeadbeef );
4536 context = pGetWindowDpiAwarenessContext( (HWND)0xdeadbeef );
4537 ok( !context, "got %p\n", context );
4538 ok( GetLastError() == ERROR_INVALID_WINDOW_HANDLE, "wrong error %lu\n", GetLastError() );
4539 SetLastError( 0xdeadbeef );
4540 dpi = pGetDpiForWindow( (HWND)0xdeadbeef );
4541 ok( !dpi, "got %u\n", dpi );
4542 ok( GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_WINDOW_HANDLE,
4543 "wrong error %lu\n", GetLastError() );
4545 SetLastError( 0xdeadbeef );
4546 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
4547 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4548 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
4549 dpi = pGetDpiForWindow( GetDesktopWindow() );
4550 ok( dpi == real_dpi, "got %u / %u\n", dpi, real_dpi );
4552 pSetThreadDpiAwarenessContext( DPI_AWARENESS_CONTEXT_UNAWARE );
4553 SetLastError( 0xdeadbeef );
4554 context = pGetWindowDpiAwarenessContext( GetDesktopWindow() );
4555 awareness = pGetAwarenessFromDpiAwarenessContext( context );
4556 ok( awareness == DPI_AWARENESS_PER_MONITOR_AWARE, "wrong awareness %u\n", awareness );
4557 dpi = pGetDpiForWindow( GetDesktopWindow() );
4558 ok( dpi == real_dpi, "got %u / %u\n", dpi, real_dpi );
4560 pSetThreadDpiAwarenessContext( orig );
4563 static void test_GetAutoRotationState(void)
4565 AR_STATE state;
4566 BOOL ret;
4568 if (!pGetAutoRotationState)
4570 win_skip("GetAutoRotationState not supported\n");
4571 return;
4574 SetLastError(0xdeadbeef);
4575 ret = pGetAutoRotationState(NULL);
4576 ok(!ret, "Expected GetAutoRotationState to fail\n");
4577 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %ld\n", GetLastError());
4579 state = 0;
4580 ret = pGetAutoRotationState(&state);
4581 ok(ret, "Expected GetAutoRotationState to succeed, error %ld\n", GetLastError());
4584 static void test_LOGFONT_charset(void)
4586 CHARSETINFO csi;
4587 LOGFONTA lf;
4588 NONCLIENTMETRICSA ncm;
4589 BOOL ret;
4591 ret = TranslateCharsetInfo(ULongToPtr(GetACP()), &csi, TCI_SRCCODEPAGE);
4592 ok(ret, "TranslateCharsetInfo(%d) error %lu\n", GetACP(), GetLastError());
4594 GetObjectA(GetStockObject(DEFAULT_GUI_FONT), sizeof(lf), &lf);
4595 ok(lf.lfCharSet == csi.ciCharset, "got %d, expected %d\n", lf.lfCharSet, csi.ciCharset);
4597 ret = SystemParametersInfoA(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, FALSE);
4598 ok(ret, "SystemParametersInfoW error %lu\n", GetLastError());
4599 ok(lf.lfCharSet == DEFAULT_CHARSET, "got %d\n", lf.lfCharSet);
4601 ncm.cbSize = FIELD_OFFSET(NONCLIENTMETRICSA, iPaddedBorderWidth);
4602 ret = SystemParametersInfoA(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
4603 ok(ret, "SystemParametersInfoW error %lu\n", GetLastError());
4604 ok(ncm.lfCaptionFont.lfCharSet == DEFAULT_CHARSET, "got %d\n", ncm.lfCaptionFont.lfCharSet);
4605 ok(ncm.lfSmCaptionFont.lfCharSet == DEFAULT_CHARSET, "got %d\n", ncm.lfSmCaptionFont.lfCharSet);
4608 START_TEST(sysparams)
4610 int argc;
4611 char** argv;
4612 WNDCLASSA wc;
4613 MSG msg;
4614 HDC hdc;
4615 HANDLE hThread;
4616 DWORD dwThreadId;
4617 HANDLE hInstance, hdll;
4619 hdll = GetModuleHandleA("user32.dll");
4620 pIsProcessDPIAware = (void*)GetProcAddress(hdll, "IsProcessDPIAware");
4621 pSetProcessDPIAware = (void*)GetProcAddress(hdll, "SetProcessDPIAware");
4622 pGetDpiForSystem = (void*)GetProcAddress(hdll, "GetDpiForSystem");
4623 pGetDpiForWindow = (void*)GetProcAddress(hdll, "GetDpiForWindow");
4624 pGetDpiForMonitorInternal = (void*)GetProcAddress(hdll, "GetDpiForMonitorInternal");
4625 pSetProcessDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessContext");
4626 pGetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "GetProcessDpiAwarenessInternal");
4627 pSetProcessDpiAwarenessInternal = (void*)GetProcAddress(hdll, "SetProcessDpiAwarenessInternal");
4628 pGetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetThreadDpiAwarenessContext");
4629 pSetThreadDpiAwarenessContext = (void*)GetProcAddress(hdll, "SetThreadDpiAwarenessContext");
4630 pGetWindowDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetWindowDpiAwarenessContext");
4631 pGetAwarenessFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetAwarenessFromDpiAwarenessContext");
4632 pIsValidDpiAwarenessContext = (void*)GetProcAddress(hdll, "IsValidDpiAwarenessContext");
4633 pGetSystemMetricsForDpi = (void*)GetProcAddress(hdll, "GetSystemMetricsForDpi");
4634 pSystemParametersInfoForDpi = (void*)GetProcAddress(hdll, "SystemParametersInfoForDpi");
4635 pAdjustWindowRectExForDpi = (void*)GetProcAddress(hdll, "AdjustWindowRectExForDpi");
4636 pLogicalToPhysicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "LogicalToPhysicalPointForPerMonitorDPI");
4637 pPhysicalToLogicalPointForPerMonitorDPI = (void*)GetProcAddress(hdll, "PhysicalToLogicalPointForPerMonitorDPI");
4638 pGetAutoRotationState = (void*)GetProcAddress(hdll, "GetAutoRotationState");
4639 pAreDpiAwarenessContextsEqual = (void*)GetProcAddress(hdll, "AreDpiAwarenessContextsEqual");
4640 pGetDpiFromDpiAwarenessContext = (void*)GetProcAddress(hdll, "GetDpiFromDpiAwarenessContext");
4642 hInstance = GetModuleHandleA( NULL );
4643 hdc = GetDC(0);
4644 dpi = GetDeviceCaps( hdc, LOGPIXELSY);
4645 real_dpi = get_real_dpi();
4646 ReleaseDC( 0, hdc);
4648 /* This test requires interactivity, if we don't have it, give up */
4649 if (!SystemParametersInfoA( SPI_SETBEEP, TRUE, 0, SPIF_UPDATEINIFILE | SPIF_SENDCHANGE ) &&
4650 GetLastError()==ERROR_REQUIRES_INTERACTIVE_WINDOWSTATION) return;
4652 argc = winetest_get_mainargs(&argv);
4653 strict=(argc >= 3 && strcmp(argv[2],"strict")==0);
4655 if (argc > 3 && !strcmp( argv[2], "SetProcessDpiAwarenessContext" ))
4657 test_SetProcessDpiAwarenessContext( strtoul( argv[3], NULL, 16 ) );
4658 return;
4661 trace("dpi %d real_dpi %d, strict %d\n", dpi, real_dpi, strict);
4663 test_LOGFONT_charset();
4665 trace("testing GetSystemMetrics with your current desktop settings\n");
4666 test_GetSystemMetrics( );
4667 test_metrics_for_dpi( 192 );
4668 test_EnumDisplaySettings( );
4669 test_GetSysColorBrush( );
4670 test_GetAutoRotationState( );
4671 test_SetThreadDpiAwarenessContext();
4672 test_IsValidDpiAwarenessContext();
4673 test_GetDpiFromDpiAwarenessContext();
4674 test_AreDpiAwarenessContextsEqual();
4675 test_GetAwarenessFromDpiAwarenessContext();
4677 change_counter = 0;
4678 change_last_param = 0;
4680 wc.lpszClassName = "SysParamsTestClass";
4681 wc.lpfnWndProc = SysParamsTestWndProc;
4682 wc.style = CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
4683 wc.hInstance = hInstance;
4684 wc.hIcon = LoadIconA( 0, (LPCSTR)IDI_APPLICATION );
4685 wc.hCursor = LoadCursorA( 0, (LPCSTR)IDC_ARROW );
4686 wc.hbrBackground = (HBRUSH)( COLOR_WINDOW + 1 );
4687 wc.lpszMenuName = 0;
4688 wc.cbClsExtra = 0;
4689 wc.cbWndExtra = 0;
4690 RegisterClassA( &wc );
4691 wc.lpszClassName = "DpiTestClass";
4692 wc.lpfnWndProc = dpi_winproc;
4693 RegisterClassA( &wc );
4695 ghTestWnd = CreateWindowA( "SysParamsTestClass", "Test System Parameters Application",
4696 WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, 0, 0, hInstance, NULL );
4698 hThread = CreateThread( NULL, 0, SysParamsThreadFunc, 0, 0, &dwThreadId );
4699 assert( hThread );
4700 CloseHandle( hThread );
4702 while( GetMessageA( &msg, 0, 0, 0 )) {
4703 TranslateMessage( &msg );
4704 DispatchMessageA( &msg );
4707 if (pSetThreadDpiAwarenessContext)
4709 test_dpi_context();
4710 test_dpi_mapping();
4711 test_dpi_window();
4713 else win_skip( "SetThreadDpiAwarenessContext not supported\n" );
4715 test_dpi_aware();
4717 if (!pSetProcessDpiAwarenessContext || !pSetThreadDpiAwarenessContext || !pGetThreadDpiAwarenessContext)
4718 win_skip( "SetProcessDpiAwarenessContext not supported\n" );
4719 else
4721 run_in_process( argv, "SetProcessDpiAwarenessContext 0x6010" );
4722 run_in_process( argv, "SetProcessDpiAwarenessContext 0x11" );
4723 run_in_process( argv, "SetProcessDpiAwarenessContext 0x12" );
4724 run_in_process( argv, "SetProcessDpiAwarenessContext 0x22" );
4725 run_in_process( argv, "SetProcessDpiAwarenessContext 0x40006010" );
4726 run_in_process( argv, "SetProcessDpiAwarenessContext 0x80006010" );
4727 run_in_process( argv, "SetProcessDpiAwarenessContext 0x80000012" );
4728 run_in_process( argv, "SetProcessDpiAwarenessContext 0x80000022" );
4730 /* user32 allows abstract DPI contexts to be used */
4731 run_in_process( argv, "SetProcessDpiAwarenessContext 0xffffffff" );
4732 run_in_process( argv, "SetProcessDpiAwarenessContext 0xfffffffe" );
4733 run_in_process( argv, "SetProcessDpiAwarenessContext 0xfffffffd" );
4734 run_in_process( argv, "SetProcessDpiAwarenessContext 0xfffffffc" );
4735 run_in_process( argv, "SetProcessDpiAwarenessContext 0xfffffffb" );