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