2 * Unit tests for dc functions
4 * Copyright (c) 2005 Huw Davies
5 * Copyright (c) 2005 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #define WINVER 0x0501 /* request latest DEVMODE */
24 #define NONAMELESSSTRUCT
25 #define NONAMELESSUNION
30 #include "wine/test.h"
41 static DWORD (WINAPI
*pSetLayout
)(HDC hdc
, DWORD layout
);
43 static void dump_region(HRGN hrgn
)
51 printf( "(null) region\n" );
54 if (!(size
= GetRegionData( hrgn
, 0, NULL
))) return;
55 if (!(data
= HeapAlloc( GetProcessHeap(), 0, size
))) return;
56 GetRegionData( hrgn
, size
, data
);
57 printf( "%d rects:", data
->rdh
.nCount
);
58 for (i
= 0, rect
= (RECT
*)data
->Buffer
; i
< data
->rdh
.nCount
; i
++, rect
++)
59 printf( " (%d,%d)-(%d,%d)", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
61 HeapFree( GetProcessHeap(), 0, data
);
64 static void test_dc_values(void)
66 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
70 ok( hdc
!= NULL
, "CreateDC failed\n" );
71 color
= SetBkColor( hdc
, 0x12345678 );
72 ok( color
== 0xffffff, "initial color %08x\n", color
);
73 color
= GetBkColor( hdc
);
74 ok( color
== 0x12345678, "wrong color %08x\n", color
);
75 color
= SetBkColor( hdc
, 0xffffffff );
76 ok( color
== 0x12345678, "wrong color %08x\n", color
);
77 color
= GetBkColor( hdc
);
78 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
79 color
= SetBkColor( hdc
, 0 );
80 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
81 color
= GetBkColor( hdc
);
82 ok( color
== 0, "wrong color %08x\n", color
);
84 color
= SetTextColor( hdc
, 0xffeeddcc );
85 ok( color
== 0, "initial color %08x\n", color
);
86 color
= GetTextColor( hdc
);
87 ok( color
== 0xffeeddcc, "wrong color %08x\n", color
);
88 color
= SetTextColor( hdc
, 0xffffffff );
89 ok( color
== 0xffeeddcc, "wrong color %08x\n", color
);
90 color
= GetTextColor( hdc
);
91 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
92 color
= SetTextColor( hdc
, 0 );
93 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
94 color
= GetTextColor( hdc
);
95 ok( color
== 0, "wrong color %08x\n", color
);
97 extra
= GetTextCharacterExtra( hdc
);
98 ok( extra
== 0, "initial extra %d\n", extra
);
99 SetTextCharacterExtra( hdc
, 123 );
100 extra
= GetTextCharacterExtra( hdc
);
101 ok( extra
== 123, "initial extra %d\n", extra
);
102 SetMapMode( hdc
, MM_LOMETRIC
);
103 extra
= GetTextCharacterExtra( hdc
);
104 ok( extra
== 123, "initial extra %d\n", extra
);
105 SetMapMode( hdc
, MM_TEXT
);
106 extra
= GetTextCharacterExtra( hdc
);
107 ok( extra
== 123, "initial extra %d\n", extra
);
112 static void test_savedc_2(void)
120 hwnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,
123 ShowWindow(hwnd
, SW_SHOW
);
126 hrgn
= CreateRectRgn(0, 0, 0, 0);
130 ok(hdc
!= NULL
, "GetDC failed\n");
132 ret
= GetClipBox(hdc
, &rc_clip
);
133 ok(ret
== SIMPLEREGION
|| broken(ret
== COMPLEXREGION
), "GetClipBox returned %d instead of SIMPLEREGION\n", ret
);
134 ret
= GetClipRgn(hdc
, hrgn
);
135 ok(ret
== 0, "GetClipRgn returned %d instead of 0\n", ret
);
136 ret
= GetRgnBox(hrgn
, &rc
);
137 ok(ret
== NULLREGION
, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
138 ret
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
139 /*dump_region(hrgn);*/
140 SetRect(&rc
, 0, 0, 100, 100);
141 ok(EqualRect(&rc
, &rc_clip
),
142 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
143 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
144 rc_clip
.left
, rc_clip
.top
, rc_clip
.right
, rc_clip
.bottom
);
147 ok(ret
== 1, "ret = %d\n", ret
);
149 ret
= IntersectClipRect(hdc
, 0, 0, 50, 50);
150 if (ret
== COMPLEXREGION
)
152 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
153 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret
);
154 /* let's make sure that it's a simple region */
155 ret
= GetClipRgn(hdc
, hrgn
);
156 ok(ret
== 1, "GetClipRgn returned %d instead of 1\n", ret
);
160 ok(ret
== SIMPLEREGION
, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret
);
162 ret
= GetClipBox(hdc
, &rc_clip
);
163 ok(ret
== SIMPLEREGION
|| broken(ret
== COMPLEXREGION
), "GetClipBox returned %d instead of SIMPLEREGION\n", ret
);
164 SetRect(&rc
, 0, 0, 50, 50);
165 ok(EqualRect(&rc
, &rc_clip
),
166 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
167 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
168 rc_clip
.left
, rc_clip
.top
, rc_clip
.right
, rc_clip
.bottom
);
170 ret
= RestoreDC(hdc
, 1);
171 ok(ret
, "ret = %d\n", ret
);
173 ret
= GetClipBox(hdc
, &rc_clip
);
174 ok(ret
== SIMPLEREGION
|| broken(ret
== COMPLEXREGION
), "GetClipBox returned %d instead of SIMPLEREGION\n", ret
);
175 SetRect(&rc
, 0, 0, 100, 100);
176 ok(EqualRect(&rc
, &rc_clip
),
177 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
178 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
179 rc_clip
.left
, rc_clip
.top
, rc_clip
.right
, rc_clip
.bottom
);
182 ReleaseDC(hwnd
, hdc
);
186 static void test_savedc(void)
188 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
191 ok(hdc
!= NULL
, "CreateDC rets %p\n", hdc
);
194 ok(ret
== 1, "ret = %d\n", ret
);
196 ok(ret
== 2, "ret = %d\n", ret
);
198 ok(ret
== 3, "ret = %d\n", ret
);
199 ret
= RestoreDC(hdc
, -1);
200 ok(ret
, "ret = %d\n", ret
);
202 ok(ret
== 3, "ret = %d\n", ret
);
203 ret
= RestoreDC(hdc
, 1);
204 ok(ret
, "ret = %d\n", ret
);
206 ok(ret
== 1, "ret = %d\n", ret
);
208 ok(ret
== 2, "ret = %d\n", ret
);
210 ok(ret
== 3, "ret = %d\n", ret
);
211 ret
= RestoreDC(hdc
, -2);
212 ok(ret
, "ret = %d\n", ret
);
214 ok(ret
== 2, "ret = %d\n", ret
);
215 ret
= RestoreDC(hdc
, -2);
216 ok(ret
, "ret = %d\n", ret
);
218 ok(ret
== 1, "ret = %d\n", ret
);
220 ok(ret
== 2, "ret = %d\n", ret
);
221 ret
= RestoreDC(hdc
, -4);
222 ok(!ret
, "ret = %d\n", ret
);
223 ret
= RestoreDC(hdc
, 3);
224 ok(!ret
, "ret = %d\n", ret
);
226 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
227 ret
= RestoreDC(hdc
, -3);
229 broken(ret
), /* Win9x */
232 /* Trying to clear an empty save stack fails. */
233 ret
= RestoreDC(hdc
, -3);
234 ok(!ret
, "ret = %d\n", ret
);
238 broken(ret
== 1), /* Win9x */
241 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
242 ret
= RestoreDC(hdc
, 0);
244 broken(ret
), /* Win9x */
247 /* Trying to clear an empty save stack fails. */
248 ret
= RestoreDC(hdc
, 0);
249 ok(!ret
, "ret = %d\n", ret
);
251 ret
= RestoreDC(hdc
, 1);
253 broken(!ret
), /* Win9x */
259 static void test_GdiConvertToDevmodeW(void)
261 DEVMODEW
* (WINAPI
*pGdiConvertToDevmodeW
)(const DEVMODEA
*);
266 pGdiConvertToDevmodeW
= (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
267 if (!pGdiConvertToDevmodeW
)
269 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
273 ret
= EnumDisplaySettingsA(NULL
, ENUM_CURRENT_SETTINGS
, &dmA
);
274 ok(ret
, "EnumDisplaySettingsExA error %u\n", GetLastError());
275 ok(dmA
.dmSize
>= FIELD_OFFSET(DEVMODEA
, dmICMMethod
), "dmSize is too small: %04x\n", dmA
.dmSize
);
276 ok(dmA
.dmSize
<= sizeof(DEVMODEA
), "dmSize is too large: %04x\n", dmA
.dmSize
);
278 dmW
= pGdiConvertToDevmodeW(&dmA
);
279 ok(dmW
->dmSize
>= FIELD_OFFSET(DEVMODEW
, dmICMMethod
), "dmSize is too small: %04x\n", dmW
->dmSize
);
280 ok(dmW
->dmSize
<= sizeof(DEVMODEW
), "dmSize is too large: %04x\n", dmW
->dmSize
);
281 HeapFree(GetProcessHeap(), 0, dmW
);
283 dmA
.dmSize
= FIELD_OFFSET(DEVMODEA
, dmFields
) + sizeof(dmA
.dmFields
);
284 dmW
= pGdiConvertToDevmodeW(&dmA
);
285 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmFields
) + sizeof(dmW
->dmFields
),
286 "wrong size %u\n", dmW
->dmSize
);
287 HeapFree(GetProcessHeap(), 0, dmW
);
289 dmA
.dmICMMethod
= DMICMMETHOD_NONE
;
290 dmA
.dmSize
= FIELD_OFFSET(DEVMODEA
, dmICMMethod
) + sizeof(dmA
.dmICMMethod
);
291 dmW
= pGdiConvertToDevmodeW(&dmA
);
292 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmICMMethod
) + sizeof(dmW
->dmICMMethod
),
293 "wrong size %u\n", dmW
->dmSize
);
294 ok(dmW
->dmICMMethod
== DMICMMETHOD_NONE
,
295 "expected DMICMMETHOD_NONE, got %u\n", dmW
->dmICMMethod
);
296 HeapFree(GetProcessHeap(), 0, dmW
);
299 dmW
= pGdiConvertToDevmodeW(&dmA
);
300 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmPanningHeight
) + sizeof(dmW
->dmPanningHeight
),
301 "wrong size %u\n", dmW
->dmSize
);
302 HeapFree(GetProcessHeap(), 0, dmW
);
304 SetLastError(0xdeadbeef);
306 dmW
= pGdiConvertToDevmodeW(&dmA
);
307 ok(!dmW
, "GdiConvertToDevmodeW should fail\n");
308 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
310 /* this is the minimal dmSize that XP accepts */
311 dmA
.dmSize
= FIELD_OFFSET(DEVMODEA
, dmFields
);
312 dmW
= pGdiConvertToDevmodeW(&dmA
);
313 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmFields
),
314 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW
, dmFields
), dmW
->dmSize
);
315 HeapFree(GetProcessHeap(), 0, dmW
);
318 static void test_device_caps( HDC hdc
, HDC ref_dc
, const char *descr
, int scale
)
320 static const int caps
[] =
339 /* TEXTCAPS broken on printer DC on winxp */
368 if (GetObjectType( hdc
) == OBJ_METADC
)
370 for (i
= 0; i
< sizeof(caps
)/sizeof(caps
[0]); i
++)
371 ok( GetDeviceCaps( hdc
, caps
[i
] ) == (caps
[i
] == TECHNOLOGY
? DT_METAFILE
: 0),
372 "wrong caps on %s for %u: %u\n", descr
, caps
[i
],
373 GetDeviceCaps( hdc
, caps
[i
] ) );
375 SetLastError( 0xdeadbeef );
376 ret
= GetDeviceGammaRamp( hdc
, &ramp
);
377 ok( !ret
, "GetDeviceGammaRamp succeeded on %s\n", descr
);
378 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef), /* nt4 */
379 "wrong error %u on %s\n", GetLastError(), descr
);
380 type
= GetClipBox( hdc
, &rect
);
381 ok( type
== ERROR
, "GetClipBox returned %d on %s\n", type
, descr
);
383 SetBoundsRect( hdc
, NULL
, DCB_RESET
| DCB_ENABLE
);
384 SetMapMode( hdc
, MM_TEXT
);
385 Rectangle( hdc
, 2, 2, 5, 5 );
386 type
= GetBoundsRect( hdc
, &rect
, DCB_RESET
);
387 ok( !type
, "GetBoundsRect succeeded on %s\n", descr
);
388 type
= SetBoundsRect( hdc
, &rect
, DCB_RESET
| DCB_ENABLE
);
389 ok( !type
, "SetBoundsRect succeeded on %s\n", descr
);
393 for (i
= 0; i
< sizeof(caps
)/sizeof(caps
[0]); i
++)
396 INT hdc_caps
= GetDeviceCaps( hdc
, caps
[i
] );
411 ok( abs(hdc_caps
- GetDeviceCaps( ref_dc
, caps
[i
] )) <= precision
,
412 "mismatched caps on %s for %u: %u/%u (scale %d)\n", descr
, caps
[i
],
413 hdc_caps
, GetDeviceCaps( ref_dc
, caps
[i
] ), scale
);
416 SetLastError( 0xdeadbeef );
417 ret
= GetDeviceGammaRamp( hdc
, &ramp
);
418 if (GetObjectType( hdc
) != OBJ_DC
|| GetDeviceCaps( hdc
, TECHNOLOGY
) == DT_RASPRINTER
)
420 ok( !ret
, "GetDeviceGammaRamp succeeded on %s (type %d)\n", descr
, GetObjectType( hdc
) );
421 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef), /* nt4 */
422 "wrong error %u on %s\n", GetLastError(), descr
);
425 ok( ret
|| broken(!ret
) /* NT4 */, "GetDeviceGammaRamp failed on %s (type %d), error %u\n", descr
, GetObjectType( hdc
), GetLastError() );
426 type
= GetClipBox( hdc
, &rect
);
427 if (GetObjectType( hdc
) == OBJ_ENHMETADC
)
428 todo_wine
ok( type
== SIMPLEREGION
, "GetClipBox returned %d on memdc for %s\n", type
, descr
);
430 ok( type
== SIMPLEREGION
, "GetClipBox returned %d on memdc for %s\n", type
, descr
);
432 type
= GetBoundsRect( hdc
, &rect
, 0 );
433 ok( type
== DCB_RESET
|| broken(type
== DCB_SET
) /* XP */,
434 "GetBoundsRect returned type %x for %s\n", type
, descr
);
435 if (type
== DCB_RESET
)
436 ok( rect
.left
== 0 && rect
.top
== 0 && rect
.right
== 0 && rect
.bottom
== 0,
437 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
438 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, type
, descr
);
439 type
= SetBoundsRect( hdc
, NULL
, DCB_RESET
| DCB_ENABLE
);
440 ok( type
== (DCB_RESET
| DCB_DISABLE
) || broken(type
== (DCB_SET
| DCB_ENABLE
)) /* XP */,
441 "SetBoundsRect returned %x for %s (hdc type %d)\n", type
, descr
, GetObjectType( hdc
) );
443 SetMapMode( hdc
, MM_TEXT
);
444 Rectangle( hdc
, 2, 2, 4, 4 );
445 type
= GetBoundsRect( hdc
, &rect
, DCB_RESET
);
446 if (GetObjectType( hdc
) == OBJ_ENHMETADC
|| (GetObjectType( hdc
) == OBJ_DC
&& GetDeviceCaps( hdc
, TECHNOLOGY
) == DT_RASPRINTER
))
448 ok( rect
.left
== 2 && rect
.top
== 2 && rect
.right
== 4 && rect
.bottom
== 4 && type
== DCB_SET
,
449 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
450 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, type
, descr
);
452 ok( rect
.left
== 2 && rect
.top
== 2 && rect
.right
== 4 && rect
.bottom
== 4 && type
== DCB_SET
,
453 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
454 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, type
, descr
);
457 type
= GetClipBox( ref_dc
, &rect
);
458 if (type
!= COMPLEXREGION
&& type
!= ERROR
) /* region can be complex on multi-monitor setups */
462 ok( type
== SIMPLEREGION
, "GetClipBox returned %d on %s\n", type
, descr
);
463 if (GetDeviceCaps( ref_dc
, TECHNOLOGY
) == DT_RASDISPLAY
)
465 if (GetSystemMetrics( SM_CXSCREEN
) != GetSystemMetrics( SM_CXVIRTUALSCREEN
))
466 todo_wine
ok( GetDeviceCaps( ref_dc
, DESKTOPHORZRES
) == GetSystemMetrics( SM_CXSCREEN
),
467 "Got DESKTOPHORZRES %d on %s, expected %d\n",
468 GetDeviceCaps( ref_dc
, DESKTOPHORZRES
), descr
, GetSystemMetrics( SM_CXSCREEN
) );
470 ok( GetDeviceCaps( ref_dc
, DESKTOPHORZRES
) == GetSystemMetrics( SM_CXSCREEN
),
471 "Got DESKTOPHORZRES %d on %s, expected %d\n",
472 GetDeviceCaps( ref_dc
, DESKTOPHORZRES
), descr
, GetSystemMetrics( SM_CXSCREEN
) );
474 if (GetSystemMetrics( SM_CYSCREEN
) != GetSystemMetrics( SM_CYVIRTUALSCREEN
))
475 todo_wine
ok( GetDeviceCaps( ref_dc
, DESKTOPVERTRES
) == GetSystemMetrics( SM_CYSCREEN
),
476 "Got DESKTOPVERTRES %d on %s, expected %d\n",
477 GetDeviceCaps( ref_dc
, DESKTOPVERTRES
), descr
, GetSystemMetrics( SM_CYSCREEN
) );
479 ok( GetDeviceCaps( ref_dc
, DESKTOPVERTRES
) == GetSystemMetrics( SM_CYSCREEN
),
480 "Got DESKTOPVERTRES %d on %s, expected %d\n",
481 GetDeviceCaps( ref_dc
, DESKTOPVERTRES
), descr
, GetSystemMetrics( SM_CYSCREEN
) );
483 SetRect( &ref_rect
, GetSystemMetrics( SM_XVIRTUALSCREEN
), GetSystemMetrics( SM_YVIRTUALSCREEN
),
484 GetSystemMetrics( SM_XVIRTUALSCREEN
) + GetSystemMetrics( SM_CXVIRTUALSCREEN
),
485 GetSystemMetrics( SM_YVIRTUALSCREEN
) + GetSystemMetrics( SM_CYVIRTUALSCREEN
) );
489 SetRect( &ref_rect
, 0, 0, GetDeviceCaps( ref_dc
, DESKTOPHORZRES
),
490 GetDeviceCaps( ref_dc
, DESKTOPVERTRES
) );
493 if (GetDeviceCaps( ref_dc
, TECHNOLOGY
) == DT_RASDISPLAY
&& GetObjectType( hdc
) != OBJ_ENHMETADC
&&
494 (GetSystemMetrics( SM_XVIRTUALSCREEN
) || GetSystemMetrics( SM_YVIRTUALSCREEN
)))
495 todo_wine
ok( EqualRect( &rect
, &ref_rect
), "GetClipBox returned %d,%d,%d,%d on %s\n",
496 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, descr
);
498 ok( EqualRect( &rect
, &ref_rect
), "GetClipBox returned %d,%d,%d,%d on %s\n",
499 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, descr
);
502 SetBoundsRect( ref_dc
, NULL
, DCB_RESET
| DCB_ACCUMULATE
);
503 SetMapMode( ref_dc
, MM_TEXT
);
504 Rectangle( ref_dc
, 3, 3, 5, 5 );
505 type
= GetBoundsRect( ref_dc
, &rect
, DCB_RESET
);
506 /* it may or may not work on non-memory DCs */
507 ok( (rect
.left
== 0 && rect
.top
== 0 && rect
.right
== 0 && rect
.bottom
== 0 && type
== DCB_RESET
) ||
508 (rect
.left
== 3 && rect
.top
== 3 && rect
.right
== 5 && rect
.bottom
== 5 && type
== DCB_SET
),
509 "GetBoundsRect returned %d,%d,%d,%d type %x on %s\n",
510 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, type
, descr
);
512 if (GetObjectType( hdc
) == OBJ_MEMDC
)
514 char buffer
[sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
)];
515 BITMAPINFO
*info
= (BITMAPINFO
*)buffer
;
518 memset( buffer
, 0, sizeof(buffer
) );
519 info
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
520 info
->bmiHeader
.biWidth
= 16;
521 info
->bmiHeader
.biHeight
= 16;
522 info
->bmiHeader
.biPlanes
= 1;
523 info
->bmiHeader
.biBitCount
= 8;
524 info
->bmiHeader
.biCompression
= BI_RGB
;
525 dib
= CreateDIBSection( ref_dc
, info
, DIB_RGB_COLORS
, NULL
, NULL
, 0 );
526 old
= SelectObject( hdc
, dib
);
528 for (i
= 0; i
< sizeof(caps
)/sizeof(caps
[0]); i
++)
529 ok( GetDeviceCaps( hdc
, caps
[i
] ) == GetDeviceCaps( ref_dc
, caps
[i
] ),
530 "mismatched caps on %s and DIB for %u: %u/%u\n", descr
, caps
[i
],
531 GetDeviceCaps( hdc
, caps
[i
] ), GetDeviceCaps( ref_dc
, caps
[i
] ) );
533 SetLastError( 0xdeadbeef );
534 ret
= GetDeviceGammaRamp( hdc
, &ramp
);
535 ok( !ret
, "GetDeviceGammaRamp succeeded on %s\n", descr
);
536 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef), /* nt4 */
537 "wrong error %u on %s\n", GetLastError(), descr
);
539 type
= GetClipBox( hdc
, &rect
);
540 ok( type
== SIMPLEREGION
, "GetClipBox returned %d on memdc for %s\n", type
, descr
);
541 ok( rect
.left
== 0 && rect
.top
== 0 && rect
.right
== 16 && rect
.bottom
== 16,
542 "GetClipBox returned %d,%d,%d,%d on memdc for %s\n",
543 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, descr
);
545 SetBoundsRect( hdc
, NULL
, DCB_RESET
| DCB_ENABLE
);
546 SetMapMode( hdc
, MM_TEXT
);
547 Rectangle( hdc
, 5, 5, 12, 14 );
548 type
= GetBoundsRect( hdc
, &rect
, DCB_RESET
);
549 ok( rect
.left
== 5 && rect
.top
== 5 && rect
.right
== 12 && rect
.bottom
== 14 && type
== DCB_SET
,
550 "GetBoundsRect returned %d,%d,%d,%d type %x on memdc for %s\n",
551 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
, type
, descr
);
553 SelectObject( hdc
, old
);
557 /* restore hdc state */
558 SetBoundsRect( hdc
, NULL
, DCB_RESET
| DCB_DISABLE
);
559 SetBoundsRect( ref_dc
, NULL
, DCB_RESET
| DCB_DISABLE
);
562 static void test_CreateCompatibleDC(void)
565 HDC hdc
, hNewDC
, hdcMetafile
, screen_dc
;
570 bitmap
= CreateBitmap( 10, 10, 1, 1, NULL
);
572 bRet
= EnumDisplaySettingsA(NULL
, ENUM_CURRENT_SETTINGS
, &dm
);
573 ok(bRet
, "EnumDisplaySettingsEx failed\n");
574 dm
.u1
.s1
.dmScale
= 200;
575 dm
.dmFields
|= DM_SCALE
;
576 hdc
= CreateDCA( "DISPLAY", NULL
, NULL
, &dm
);
578 screen_dc
= CreateDCA( "DISPLAY", NULL
, NULL
, NULL
);
579 test_device_caps( hdc
, screen_dc
, "display dc", 1 );
580 ResetDCA( hdc
, &dm
);
581 test_device_caps( hdc
, screen_dc
, "display dc", 1 );
584 /* Create a DC compatible with the screen */
585 hdc
= CreateCompatibleDC(NULL
);
586 ok(hdc
!= NULL
, "CreateCompatibleDC returned %p\n", hdc
);
587 ok( SelectObject( hdc
, bitmap
) != 0, "SelectObject failed\n" );
588 caps
= GetDeviceCaps( hdc
, TECHNOLOGY
);
589 ok( caps
== DT_RASDISPLAY
, "wrong caps %u\n", caps
);
591 test_device_caps( hdc
, screen_dc
, "display dc", 1 );
593 /* Delete this DC, this should succeed */
594 bRet
= DeleteDC(hdc
);
595 ok(bRet
== TRUE
, "DeleteDC returned %u\n", bRet
);
597 /* Try to create a DC compatible to the deleted DC. This has to fail */
598 hNewDC
= CreateCompatibleDC(hdc
);
599 ok(hNewDC
== NULL
, "CreateCompatibleDC returned %p\n", hNewDC
);
602 hdcMetafile
= CreateEnhMetaFileA(hdc
, NULL
, NULL
, NULL
);
603 ok(hdcMetafile
!= 0, "CreateEnhMetaFileA failed\n");
604 hNewDC
= CreateCompatibleDC( hdcMetafile
);
605 ok(hNewDC
!= NULL
, "CreateCompatibleDC failed\n");
606 ok( SelectObject( hNewDC
, bitmap
) != 0, "SelectObject failed\n" );
607 caps
= GetDeviceCaps( hdcMetafile
, TECHNOLOGY
);
608 ok( caps
== DT_RASDISPLAY
, "wrong caps %u\n", caps
);
609 test_device_caps( hdcMetafile
, hdc
, "enhmetafile dc", 1 );
610 ResetDCA( hdcMetafile
, &dm
);
611 test_device_caps( hdcMetafile
, hdc
, "enhmetafile dc", 1 );
613 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile
));
616 hdcMetafile
= CreateMetaFileA(NULL
);
617 ok(hdcMetafile
!= 0, "CreateEnhMetaFileA failed\n");
618 hNewDC
= CreateCompatibleDC( hdcMetafile
);
619 ok(hNewDC
== NULL
, "CreateCompatibleDC succeeded\n");
620 caps
= GetDeviceCaps( hdcMetafile
, TECHNOLOGY
);
621 ok( caps
== DT_METAFILE
, "wrong caps %u\n", caps
);
622 test_device_caps( hdcMetafile
, screen_dc
, "metafile dc", 1 );
623 ResetDCA( hdcMetafile
, &dm
);
624 test_device_caps( hdcMetafile
, screen_dc
, "metafile dc", 1 );
625 DeleteMetaFile( CloseMetaFile( hdcMetafile
));
627 DeleteObject( bitmap
);
628 DeleteDC( screen_dc
);
631 static void test_DC_bitmap(void)
635 HBITMAP hbmp
, oldhbmp
;
639 /* fill bitmap data with b&w pattern */
640 for( i
= 0; i
< 64; i
++) bits
[i
] = i
& 1 ? 0 : 0xffffff;
643 ok( hdc
!= NULL
, "CreateDC rets %p\n", hdc
);
644 bitspixel
= GetDeviceCaps( hdc
, BITSPIXEL
);
645 /* create a memory dc */
646 hdcmem
= CreateCompatibleDC( hdc
);
647 ok( hdcmem
!= NULL
, "CreateCompatibleDC rets %p\n", hdcmem
);
649 /* test monochrome bitmap: should always work */
650 hbmp
= CreateBitmap(32, 32, 1, 1, bits
);
651 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
652 oldhbmp
= SelectObject( hdcmem
, hbmp
);
653 ok( oldhbmp
!= NULL
, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
654 col
= GetPixel( hdcmem
, 0, 0);
655 ok( col
== 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col
);
656 col
= GetPixel( hdcmem
, 1, 1);
657 ok( col
== 0x000000, "GetPixel returned %08x, expected 00000000\n", col
);
658 col
= GetPixel( hdcmem
, 100, 1);
659 ok( col
== CLR_INVALID
, "GetPixel returned %08x, expected ffffffff\n", col
);
660 SelectObject( hdcmem
, oldhbmp
);
663 /* test with 2 bits color depth, not likely to succeed */
664 hbmp
= CreateBitmap(16, 16, 1, 2, bits
);
665 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
666 oldhbmp
= SelectObject( hdcmem
, hbmp
);
668 ok( !oldhbmp
, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
669 if( oldhbmp
) SelectObject( hdcmem
, oldhbmp
);
672 /* test with 16 bits color depth, might succeed */
673 hbmp
= CreateBitmap(6, 6, 1, 16, bits
);
674 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
675 oldhbmp
= SelectObject( hdcmem
, hbmp
);
676 if( bitspixel
== 16) {
677 ok( oldhbmp
!= NULL
, "SelectObject returned NULL\n" );
678 col
= GetPixel( hdcmem
, 0, 0);
680 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col
);
681 col
= GetPixel( hdcmem
, 1, 1);
683 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col
);
685 if( oldhbmp
) SelectObject( hdcmem
, oldhbmp
);
688 /* test with 32 bits color depth, probably succeed */
689 hbmp
= CreateBitmap(4, 4, 1, 32, bits
);
690 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
691 oldhbmp
= SelectObject( hdcmem
, hbmp
);
692 if( bitspixel
== 32) {
693 ok( oldhbmp
!= NULL
, "SelectObject returned NULL\n" );
694 col
= GetPixel( hdcmem
, 0, 0);
696 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col
);
697 col
= GetPixel( hdcmem
, 1, 1);
699 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col
);
701 if( oldhbmp
) SelectObject( hdcmem
, oldhbmp
);
706 static void test_DeleteDC(void)
714 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
|WS_VISIBLE
, 0,0,100,100,
716 ok(hwnd
!= 0, "CreateWindowExA failed\n");
719 ok(hdc
!= 0, "GetDC failed\n");
720 ret
= GetObjectType(hdc
);
721 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
723 ok(ret
, "DeleteDC failed\n");
724 ret
= GetObjectType(hdc
);
725 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
727 hdc
= GetWindowDC(hwnd
);
728 ok(hdc
!= 0, "GetDC failed\n");
729 ret
= GetObjectType(hdc
);
730 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
732 ok(ret
, "DeleteDC failed\n");
733 ret
= GetObjectType(hdc
);
734 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
738 /* desktop window DC */
739 hwnd
= GetDesktopWindow();
740 ok(hwnd
!= 0, "GetDesktopWindow failed\n");
743 ok(hdc
!= 0, "GetDC failed\n");
744 ret
= GetObjectType(hdc
);
745 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
747 ok(ret
, "DeleteDC failed\n");
748 ret
= GetObjectType(hdc
);
749 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
751 hdc
= GetWindowDC(hwnd
);
752 ok(hdc
!= 0, "GetDC failed\n");
753 ret
= GetObjectType(hdc
);
754 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
756 ok(ret
, "DeleteDC failed\n");
757 ret
= GetObjectType(hdc
);
758 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
761 memset(&cls
, 0, sizeof(cls
));
762 cls
.cbSize
= sizeof(cls
);
763 cls
.style
= CS_CLASSDC
;
764 cls
.hInstance
= GetModuleHandleA(NULL
);
765 cls
.lpszClassName
= "Wine class DC";
766 cls
.lpfnWndProc
= DefWindowProcA
;
767 ret
= RegisterClassExA(&cls
);
768 ok(ret
, "RegisterClassExA failed\n");
770 hwnd
= CreateWindowExA(0, "Wine class DC", NULL
, WS_POPUP
|WS_VISIBLE
, 0,0,100,100,
772 ok(hwnd
!= 0, "CreateWindowExA failed\n");
775 ok(hdc
!= 0, "GetDC failed\n");
776 ret
= GetObjectType(hdc
);
777 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
779 ok(ret
, "DeleteDC failed\n");
780 ret
= GetObjectType(hdc
);
781 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
782 ret
= ReleaseDC(hwnd
, hdc
);
783 ok(ret
, "ReleaseDC failed\n");
784 ret
= GetObjectType(hdc
);
785 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
789 hdc
= GetWindowDC(hwnd
);
790 ok(hdc
!= 0, "GetDC failed\n");
791 ret
= GetObjectType(hdc
);
792 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
794 ok(ret
, "DeleteDC failed\n");
795 ret
= GetObjectType(hdc
);
796 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
800 ret
= GetObjectType(hdc_test
);
801 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
803 ret
= UnregisterClassA("Wine class DC", GetModuleHandleA(NULL
));
804 ok(ret
, "UnregisterClassA failed\n");
806 ret
= GetObjectType(hdc_test
);
808 ok(!ret
, "GetObjectType should fail for a deleted DC\n");
811 memset(&cls
, 0, sizeof(cls
));
812 cls
.cbSize
= sizeof(cls
);
813 cls
.style
= CS_OWNDC
;
814 cls
.hInstance
= GetModuleHandleA(NULL
);
815 cls
.lpszClassName
= "Wine own DC";
816 cls
.lpfnWndProc
= DefWindowProcA
;
817 ret
= RegisterClassExA(&cls
);
818 ok(ret
, "RegisterClassExA failed\n");
820 hwnd
= CreateWindowExA(0, "Wine own DC", NULL
, WS_POPUP
|WS_VISIBLE
, 0,0,100,100,
822 ok(hwnd
!= 0, "CreateWindowExA failed\n");
825 ok(hdc
!= 0, "GetDC failed\n");
826 ret
= GetObjectType(hdc
);
827 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
829 ok(ret
, "DeleteDC failed\n");
830 ret
= GetObjectType(hdc
);
831 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
832 ret
= ReleaseDC(hwnd
, hdc
);
833 ok(ret
, "ReleaseDC failed\n");
834 ret
= GetObjectType(hdc
);
835 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
837 hdc
= GetWindowDC(hwnd
);
838 ok(hdc
!= 0, "GetDC failed\n");
839 ret
= GetObjectType(hdc
);
840 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
842 ok(ret
, "DeleteDC failed\n");
843 ret
= GetObjectType(hdc
);
844 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
848 ret
= UnregisterClassA("Wine own DC", GetModuleHandleA(NULL
));
849 ok(ret
, "UnregisterClassA failed\n");
852 static void test_boundsrect(void)
854 char buffer
[sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
)];
855 BITMAPINFO
*info
= (BITMAPINFO
*)buffer
;
857 HBITMAP bitmap
, dib
, old
;
858 RECT rect
, expect
, set_rect
;
862 hdc
= CreateCompatibleDC(0);
863 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
864 bitmap
= CreateCompatibleBitmap( hdc
, 200, 200 );
865 old
= SelectObject( hdc
, bitmap
);
867 ret
= GetBoundsRect(hdc
, NULL
, 0);
868 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
870 ret
= GetBoundsRect(hdc
, NULL
, ~0U);
871 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
873 /* Test parameter handling order. */
874 SetRect(&set_rect
, 10, 20, 40, 50);
875 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
877 "Expected return flag DCB_RESET to be set, got %u\n", ret
);
879 ret
= GetBoundsRect(hdc
, NULL
, DCB_RESET
);
881 "Expected GetBoundsRect to return 0, got %u\n", ret
);
883 ret
= GetBoundsRect(hdc
, &rect
, 0);
885 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret
);
886 SetRect(&expect
, 0, 0, 0, 0);
887 ok(EqualRect(&rect
, &expect
) ||
888 broken(EqualRect(&rect
, &set_rect
)), /* nt4 sp1-5 */
889 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
890 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
892 ret
= GetBoundsRect(NULL
, NULL
, 0);
893 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
895 ret
= GetBoundsRect(NULL
, NULL
, ~0U);
896 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
898 ret
= SetBoundsRect(NULL
, NULL
, 0);
899 ok(ret
== 0, "Expected SetBoundsRect to return 0, got %u\n", ret
);
901 ret
= SetBoundsRect(NULL
, NULL
, ~0U);
902 ok(ret
== 0, "Expected SetBoundsRect to return 0, got %u\n", ret
);
904 SetRect(&set_rect
, 10, 20, 40, 50);
905 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
906 ok(ret
== (DCB_RESET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
908 ret
= GetBoundsRect(hdc
, &rect
, 0);
909 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
910 SetRect(&expect
, 10, 20, 40, 50);
911 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
912 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
914 SetMapMode( hdc
, MM_ANISOTROPIC
);
915 SetViewportExtEx( hdc
, 2, 2, NULL
);
916 ret
= GetBoundsRect(hdc
, &rect
, 0);
917 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
918 SetRect(&expect
, 5, 10, 20, 25);
919 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
920 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
922 SetViewportOrgEx( hdc
, 20, 30, NULL
);
923 ret
= GetBoundsRect(hdc
, &rect
, 0);
924 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
925 SetRect(&expect
, -5, -5, 10, 10);
926 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
927 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
929 SetRect(&set_rect
, 10, 20, 40, 50);
930 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
931 ok(ret
== (DCB_SET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
933 ret
= GetBoundsRect(hdc
, &rect
, 0);
934 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
935 SetRect(&expect
, 10, 20, 40, 50);
936 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
937 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
939 SetMapMode( hdc
, MM_TEXT
);
940 SetViewportOrgEx( hdc
, 0, 0, NULL
);
941 ret
= GetBoundsRect(hdc
, &rect
, 0);
942 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
943 SetRect(&expect
, 40, 70, 100, 130);
944 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
945 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
949 pSetLayout( hdc
, LAYOUT_RTL
);
950 ret
= GetBoundsRect(hdc
, &rect
, 0);
951 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
952 SetRect(&expect
, 159, 70, 99, 130);
953 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
954 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
955 SetRect(&set_rect
, 50, 25, 30, 35);
956 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
957 ok(ret
== (DCB_SET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
958 ret
= GetBoundsRect(hdc
, &rect
, 0);
959 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
960 SetRect(&expect
, 50, 25, 30, 35);
961 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
962 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
964 pSetLayout( hdc
, LAYOUT_LTR
);
965 ret
= GetBoundsRect(hdc
, &rect
, 0);
966 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
967 SetRect(&expect
, 149, 25, 169, 35);
968 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
969 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
972 /* empty rect resets, except on nt4 */
973 SetRect(&expect
, 20, 20, 10, 10);
974 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
975 ok(ret
== (DCB_SET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
976 ret
= GetBoundsRect(hdc
, &rect
, 0);
977 ok(ret
== DCB_RESET
|| broken(ret
== DCB_SET
) /* nt4 */,
978 "GetBoundsRect returned %x\n", ret
);
979 if (ret
== DCB_RESET
)
981 SetRect(&expect
, 0, 0, 0, 0);
982 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
983 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
985 SetRect(&expect
, 20, 20, 20, 20);
986 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
987 ok(ret
== (DCB_RESET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
988 ret
= GetBoundsRect(hdc
, &rect
, 0);
989 ok(ret
== DCB_RESET
, "GetBoundsRect returned %x\n", ret
);
990 SetRect(&expect
, 0, 0, 0, 0);
991 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
992 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
995 SetBoundsRect( hdc
, NULL
, DCB_RESET
| DCB_ENABLE
);
996 MoveToEx( hdc
, 10, 10, NULL
);
997 LineTo( hdc
, 20, 20 );
998 ret
= GetBoundsRect( hdc
, &rect
, 0 );
999 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1000 SetRect( &expect
, 10, 10, 21, 21 );
1001 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1002 SetRect( &rect
, 8, 8, 23, 23 );
1004 SetBoundsRect( hdc
, &rect
, DCB_ACCUMULATE
);
1005 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1006 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1007 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1009 level
= SaveDC( hdc
);
1010 LineTo( hdc
, 30, 25 );
1011 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1012 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1013 SetRect( &expect
, 8, 8, 31, 26 );
1014 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1015 SetBoundsRect( hdc
, NULL
, DCB_DISABLE
);
1016 LineTo( hdc
, 40, 40 );
1017 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1018 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1019 SetRect( &expect
, 8, 8, 31, 26 );
1020 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1021 SetRect( &rect
, 6, 6, 30, 30 );
1022 SetBoundsRect( hdc
, &rect
, DCB_ACCUMULATE
);
1023 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1024 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1025 SetRect( &expect
, 6, 6, 31, 30 );
1026 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1028 RestoreDC( hdc
, level
);
1029 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1030 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1031 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1032 LineTo( hdc
, 40, 40 );
1033 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1034 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1035 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1037 SelectObject( hdc
, old
);
1038 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1039 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1040 SetRect( &expect
, 6, 6, 1, 1 );
1041 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1042 SetBoundsRect( hdc
, NULL
, DCB_ENABLE
);
1043 LineTo( hdc
, 50, 40 );
1045 SelectObject( hdc
, bitmap
);
1046 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1047 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1048 SetRect( &expect
, 6, 6, 51, 41 );
1049 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1050 SelectObject( hdc
, GetStockObject( NULL_PEN
));
1051 LineTo( hdc
, 50, 50 );
1052 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1053 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1054 SetRect( &expect
, 6, 6, 51, 51 );
1055 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1057 memset( buffer
, 0, sizeof(buffer
) );
1058 info
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
1059 info
->bmiHeader
.biWidth
= 256;
1060 info
->bmiHeader
.biHeight
= 256;
1061 info
->bmiHeader
.biPlanes
= 1;
1062 info
->bmiHeader
.biBitCount
= 8;
1063 info
->bmiHeader
.biCompression
= BI_RGB
;
1064 dib
= CreateDIBSection( 0, info
, DIB_RGB_COLORS
, NULL
, NULL
, 0 );
1065 ok( dib
!= 0, "failed to create DIB\n" );
1066 SelectObject( hdc
, dib
);
1067 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1068 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1069 SetRect( &expect
, 6, 6, 51, 51 );
1070 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1071 LineTo( hdc
, 55, 30 );
1072 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1073 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1074 SetRect( &expect
, 6, 6, 56, 51 );
1075 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1076 LineTo( hdc
, 300, 30 );
1077 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1078 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1079 SetRect( &expect
, 6, 6, 256, 51 );
1080 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1081 LineTo( hdc
, -300, -300 );
1082 ret
= GetBoundsRect( hdc
, &rect
, 0 );
1083 ok( ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
1084 SetRect( &expect
, 0, 0, 256, 51 );
1085 ok( EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n", rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
1087 /* test the wide pen heuristics */
1088 SetBoundsRect( hdc
, NULL
, DCB_ENABLE
| DCB_RESET
);
1089 for (i
= 0; i
< 1000; i
++)
1091 static const UINT endcaps
[3] = { PS_ENDCAP_ROUND
, PS_ENDCAP_SQUARE
, PS_ENDCAP_FLAT
};
1092 static const UINT joins
[3] = { PS_JOIN_ROUND
, PS_JOIN_BEVEL
, PS_JOIN_MITER
};
1093 LOGBRUSH brush
= { BS_SOLID
, RGB(0,0,0), 0 };
1094 UINT join
= joins
[i
% 3];
1095 UINT endcap
= endcaps
[(i
/ 3) % 3];
1096 INT inflate
, width
= 1 + i
/ 9;
1097 HPEN pen
= ExtCreatePen( PS_GEOMETRIC
| join
| endcap
| PS_SOLID
, width
, &brush
, 0, NULL
);
1098 HPEN old
= SelectObject( hdc
, pen
);
1099 MoveToEx( hdc
, 100, 100, NULL
);
1100 LineTo( hdc
, 160, 100 );
1101 LineTo( hdc
, 100, 160 );
1102 LineTo( hdc
, 160, 160 );
1103 GetBoundsRect( hdc
, &rect
, DCB_RESET
);
1104 SetRect( &expect
, 100, 100, 161, 161 );
1106 inflate
= width
+ 2;
1107 if (join
== PS_JOIN_MITER
)
1110 if (endcap
== PS_ENDCAP_SQUARE
)
1111 InflateRect( &expect
, (inflate
* 3 + 1) / 2, (inflate
* 3 + 1) / 2 );
1113 InflateRect( &expect
, inflate
, inflate
);
1117 if (endcap
== PS_ENDCAP_SQUARE
)
1118 InflateRect( &expect
, inflate
- inflate
/ 4, inflate
- inflate
/ 4 );
1120 InflateRect( &expect
, (inflate
+ 1) / 2, (inflate
+ 1) / 2 );
1122 expect
.left
= max( expect
.left
, 0 );
1123 expect
.top
= max( expect
.top
, 0 );
1124 expect
.right
= min( expect
.right
, 256 );
1125 expect
.bottom
= min( expect
.bottom
, 256 );
1126 ok( EqualRect(&rect
, &expect
),
1127 "Got %d,%d,%d,%d expected %d,%d,%d,%d %u/%x/%x\n",
1128 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
,
1129 expect
.left
, expect
.top
, expect
.right
, expect
.bottom
, width
, endcap
, join
);
1130 DeleteObject( SelectObject( hdc
, old
));
1134 DeleteObject( bitmap
);
1135 DeleteObject( dib
);
1138 static void test_desktop_colorres(void)
1140 HDC hdc
= GetDC(NULL
);
1141 int bitspixel
, colorres
;
1143 bitspixel
= GetDeviceCaps(hdc
, BITSPIXEL
);
1144 ok(bitspixel
!= 0, "Expected to get valid BITSPIXEL capability value\n");
1146 colorres
= GetDeviceCaps(hdc
, COLORRES
);
1148 broken(colorres
== 0), /* Win9x */
1149 "Expected to get valid COLORRES capability value\n");
1157 "Expected COLORRES to be 18, got %d\n", colorres
);
1161 "Expected COLORRES to be 16, got %d\n", colorres
);
1166 "Expected COLORRES to be 24, got %d\n", bitspixel
);
1169 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel
, colorres
);
1174 ReleaseDC(NULL
, hdc
);
1177 static void test_gamma(void)
1180 HDC hdc
= GetDC(NULL
);
1181 WORD oldramp
[3][256], ramp
[3][256];
1184 ret
= GetDeviceGammaRamp(hdc
, &oldramp
);
1187 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
1191 /* try to set back old ramp */
1192 ret
= SetDeviceGammaRamp(hdc
, &oldramp
);
1195 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
1199 memcpy(ramp
, oldramp
, sizeof(ramp
));
1201 /* set one color ramp to zeros */
1202 memset(ramp
[0], 0, sizeof(ramp
[0]));
1203 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
1204 ok(!ret
, "SetDeviceGammaRamp succeeded\n");
1206 /* set one color ramp to a flat straight rising line */
1207 for (i
= 0; i
< 256; i
++) ramp
[0][i
] = i
;
1208 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
1209 todo_wine
ok(!ret
, "SetDeviceGammaRamp succeeded\n");
1211 /* set one color ramp to a steep straight rising line */
1212 for (i
= 0; i
< 256; i
++) ramp
[0][i
] = i
* 256;
1213 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
1214 ok(ret
, "SetDeviceGammaRamp failed\n");
1216 /* try a bright gamma ramp */
1218 ramp
[0][1] = 0x7FFF;
1219 for (i
= 2; i
< 256; i
++) ramp
[0][i
] = 0xFFFF;
1220 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
1221 ok(!ret
, "SetDeviceGammaRamp succeeded\n");
1223 /* try ramps which are not uniform */
1225 for (i
= 1; i
< 256; i
++) ramp
[0][i
] = ramp
[0][i
- 1] + 512;
1226 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
1227 ok(ret
, "SetDeviceGammaRamp failed\n");
1229 for (i
= 2; i
< 256; i
+=2)
1231 ramp
[0][i
- 1] = ramp
[0][i
- 2];
1232 ramp
[0][i
] = ramp
[0][i
- 2] + 512;
1234 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
1235 ok(ret
, "SetDeviceGammaRamp failed\n");
1237 /* cleanup: set old ramp again */
1238 ret
= SetDeviceGammaRamp(hdc
, &oldramp
);
1239 ok(ret
, "SetDeviceGammaRamp failed\n");
1242 ReleaseDC(NULL
, hdc
);
1245 static BOOL
is_postscript_printer(HDC hdc
)
1249 if (ExtEscape(hdc
, GETTECHNOLOGY
, 0, NULL
, sizeof(tech
), tech
) > 0)
1250 return strcmp(tech
, "PostScript") == 0;
1255 static HDC
create_printer_dc(int scale
, BOOL reset
)
1259 PRINTER_INFO_2A
*pbuf
= NULL
;
1260 DRIVER_INFO_3A
*dbuf
= NULL
;
1263 HMODULE winspool
= LoadLibraryA( "winspool.drv" );
1264 BOOL (WINAPI
*pOpenPrinterA
)(LPSTR
, HANDLE
*, LPPRINTER_DEFAULTSA
);
1265 BOOL (WINAPI
*pGetDefaultPrinterA
)(LPSTR
, LPDWORD
);
1266 BOOL (WINAPI
*pGetPrinterA
)(HANDLE
, DWORD
, LPBYTE
, DWORD
, LPDWORD
);
1267 BOOL (WINAPI
*pGetPrinterDriverA
)(HANDLE
, LPSTR
, DWORD
, LPBYTE
, DWORD
, LPDWORD
);
1268 BOOL (WINAPI
*pClosePrinter
)(HANDLE
);
1270 pGetDefaultPrinterA
= (void *)GetProcAddress( winspool
, "GetDefaultPrinterA" );
1271 pOpenPrinterA
= (void *)GetProcAddress( winspool
, "OpenPrinterA" );
1272 pGetPrinterA
= (void *)GetProcAddress( winspool
, "GetPrinterA" );
1273 pGetPrinterDriverA
= (void *)GetProcAddress( winspool
, "GetPrinterDriverA" );
1274 pClosePrinter
= (void *)GetProcAddress( winspool
, "ClosePrinter" );
1276 if (!pGetDefaultPrinterA
|| !pOpenPrinterA
|| !pGetPrinterA
|| !pGetPrinterDriverA
|| !pClosePrinter
)
1279 len
= sizeof(buffer
);
1280 if (!pGetDefaultPrinterA( buffer
, &len
)) goto done
;
1281 if (!pOpenPrinterA( buffer
, &hprn
, NULL
)) goto done
;
1283 pGetPrinterA( hprn
, 2, NULL
, 0, &len
);
1284 pbuf
= HeapAlloc( GetProcessHeap(), 0, len
);
1285 if (!pGetPrinterA( hprn
, 2, (LPBYTE
)pbuf
, len
, &len
)) goto done
;
1287 pGetPrinterDriverA( hprn
, NULL
, 3, NULL
, 0, &len
);
1288 dbuf
= HeapAlloc( GetProcessHeap(), 0, len
);
1289 if (!pGetPrinterDriverA( hprn
, NULL
, 3, (LPBYTE
)dbuf
, len
, &len
)) goto done
;
1291 pbuf
->pDevMode
->u1
.s1
.dmScale
= scale
;
1292 pbuf
->pDevMode
->dmFields
|= DM_SCALE
;
1294 hdc
= CreateDCA( dbuf
->pDriverPath
, pbuf
->pPrinterName
, pbuf
->pPortName
, pbuf
->pDevMode
);
1295 trace( "hdc %p for driver '%s' printer '%s' port '%s' is %sPostScript\n", hdc
,
1296 dbuf
->pDriverPath
, pbuf
->pPrinterName
, pbuf
->pPortName
,
1297 is_postscript_printer(hdc
) ? "" : "NOT " );
1299 if (reset
) ResetDCA( hdc
, pbuf
->pDevMode
);
1301 HeapFree( GetProcessHeap(), 0, dbuf
);
1302 HeapFree( GetProcessHeap(), 0, pbuf
);
1303 if (hprn
) pClosePrinter( hprn
);
1304 if (winspool
) FreeLibrary( winspool
);
1305 if (!hdc
) skip( "could not create a DC for the default printer\n" );
1309 static void test_printer_dc(void)
1311 HDC memdc
, display_memdc
, enhmf_dc
;
1316 hdc
= create_printer_dc(100, FALSE
);
1317 hdc_200
= create_printer_dc(200, FALSE
);
1319 if (!hdc
|| !hdc_200
) return;
1321 test_device_caps( hdc
, hdc_200
, "printer dc", is_postscript_printer(hdc
) ? 2 : 1 );
1322 DeleteDC( hdc_200
);
1324 hdc_200
= create_printer_dc(200, TRUE
);
1325 test_device_caps( hdc
, hdc_200
, "printer dc", is_postscript_printer(hdc
) ? 2 : 1 );
1326 DeleteDC( hdc_200
);
1328 memdc
= CreateCompatibleDC( hdc
);
1329 display_memdc
= CreateCompatibleDC( 0 );
1331 ok( memdc
!= NULL
, "CreateCompatibleDC failed for printer\n" );
1332 ok( display_memdc
!= NULL
, "CreateCompatibleDC failed for screen\n" );
1334 ret
= GetDeviceCaps( hdc
, TECHNOLOGY
);
1335 ok( ret
== DT_RASPRINTER
, "wrong type %u\n", ret
);
1337 ret
= GetDeviceCaps( memdc
, TECHNOLOGY
);
1338 ok( ret
== DT_RASPRINTER
, "wrong type %u\n", ret
);
1340 ret
= GetDeviceCaps( display_memdc
, TECHNOLOGY
);
1341 ok( ret
== DT_RASDISPLAY
, "wrong type %u\n", ret
);
1343 bmp
= CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc
, BITSPIXEL
), NULL
);
1344 orig
= SelectObject( memdc
, bmp
);
1345 ok( orig
!= NULL
, "SelectObject failed\n" );
1346 ok( BitBlt( hdc
, 10, 10, 20, 20, memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1348 test_device_caps( memdc
, hdc
, "printer dc", 1 );
1350 ok( !SelectObject( display_memdc
, bmp
), "SelectObject succeeded\n" );
1351 SelectObject( memdc
, orig
);
1352 DeleteObject( bmp
);
1354 bmp
= CreateBitmap( 100, 100, 1, 1, NULL
);
1355 orig
= SelectObject( display_memdc
, bmp
);
1356 ok( orig
!= NULL
, "SelectObject failed\n" );
1357 ok( !SelectObject( memdc
, bmp
), "SelectObject succeeded\n" );
1358 ok( BitBlt( hdc
, 10, 10, 20, 20, display_memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1359 ok( BitBlt( memdc
, 10, 10, 20, 20, display_memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1360 ok( BitBlt( display_memdc
, 10, 10, 20, 20, memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1362 ret
= GetPixel( hdc
, 0, 0 );
1363 ok( ret
== CLR_INVALID
, "wrong pixel value %x\n", ret
);
1365 enhmf_dc
= CreateEnhMetaFileA( hdc
, NULL
, NULL
, NULL
);
1366 ok(enhmf_dc
!= 0, "CreateEnhMetaFileA failed\n");
1367 test_device_caps( enhmf_dc
, hdc
, "enhmetafile printer dc", 1 );
1368 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc
));
1370 enhmf_dc
= CreateEnhMetaFileA( hdc
, NULL
, NULL
, NULL
);
1371 ok(enhmf_dc
!= 0, "CreateEnhMetaFileA failed\n");
1372 test_device_caps( enhmf_dc
, hdc
, "enhmetafile printer dc", 1 );
1373 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc
));
1376 DeleteDC( display_memdc
);
1378 DeleteObject( bmp
);
1383 pSetLayout
= (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
1387 test_GdiConvertToDevmodeW();
1388 test_CreateCompatibleDC();
1392 test_desktop_colorres();