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
22 #define WINVER 0x0501 /* request latest DEVMODE */
27 #include "wine/test.h"
34 static DWORD (WINAPI
*pSetLayout
)(HDC hdc
, DWORD layout
);
36 static void dump_region(HRGN hrgn
)
44 printf( "(null) region\n" );
47 if (!(size
= GetRegionData( hrgn
, 0, NULL
))) return;
48 if (!(data
= HeapAlloc( GetProcessHeap(), 0, size
))) return;
49 GetRegionData( hrgn
, size
, data
);
50 printf( "%d rects:", data
->rdh
.nCount
);
51 for (i
= 0, rect
= (RECT
*)data
->Buffer
; i
< data
->rdh
.nCount
; i
++, rect
++)
52 printf( " (%d,%d)-(%d,%d)", rect
->left
, rect
->top
, rect
->right
, rect
->bottom
);
54 HeapFree( GetProcessHeap(), 0, data
);
57 static void test_dc_values(void)
59 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
62 ok( hdc
!= NULL
, "CreateDC failed\n" );
63 color
= SetBkColor( hdc
, 0x12345678 );
64 ok( color
== 0xffffff, "initial color %08x\n", color
);
65 color
= GetBkColor( hdc
);
66 ok( color
== 0x12345678, "wrong color %08x\n", color
);
67 color
= SetBkColor( hdc
, 0xffffffff );
68 ok( color
== 0x12345678, "wrong color %08x\n", color
);
69 color
= GetBkColor( hdc
);
70 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
71 color
= SetBkColor( hdc
, 0 );
72 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
73 color
= GetBkColor( hdc
);
74 ok( color
== 0, "wrong color %08x\n", color
);
76 color
= SetTextColor( hdc
, 0xffeeddcc );
77 ok( color
== 0, "initial color %08x\n", color
);
78 color
= GetTextColor( hdc
);
79 ok( color
== 0xffeeddcc, "wrong color %08x\n", color
);
80 color
= SetTextColor( hdc
, 0xffffffff );
81 ok( color
== 0xffeeddcc, "wrong color %08x\n", color
);
82 color
= GetTextColor( hdc
);
83 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
84 color
= SetTextColor( hdc
, 0 );
85 ok( color
== 0xffffffff, "wrong color %08x\n", color
);
86 color
= GetTextColor( hdc
);
87 ok( color
== 0, "wrong color %08x\n", color
);
92 static void test_savedc_2(void)
100 hwnd
= CreateWindowExA(0, "static", "", WS_POPUP
, 0,0,100,100,
103 ShowWindow(hwnd
, SW_SHOW
);
106 hrgn
= CreateRectRgn(0, 0, 0, 0);
110 ok(hdc
!= NULL
, "GetDC failed\n");
112 ret
= GetClipBox(hdc
, &rc_clip
);
113 ok(ret
== SIMPLEREGION
|| broken(ret
== COMPLEXREGION
), "GetClipBox returned %d instead of SIMPLEREGION\n", ret
);
114 ret
= GetClipRgn(hdc
, hrgn
);
115 ok(ret
== 0, "GetClipRgn returned %d instead of 0\n", ret
);
116 ret
= GetRgnBox(hrgn
, &rc
);
117 ok(ret
== NULLREGION
, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
118 ret
, rc
.left
, rc
.top
, rc
.right
, rc
.bottom
);
119 /*dump_region(hrgn);*/
120 SetRect(&rc
, 0, 0, 100, 100);
121 ok(EqualRect(&rc
, &rc_clip
),
122 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
123 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
124 rc_clip
.left
, rc_clip
.top
, rc_clip
.right
, rc_clip
.bottom
);
129 ok(ret
== 1, "ret = %d\n", ret
);
132 ret
= IntersectClipRect(hdc
, 0, 0, 50, 50);
133 if (ret
== COMPLEXREGION
)
135 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
136 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret
);
137 /* let's make sure that it's a simple region */
138 ret
= GetClipRgn(hdc
, hrgn
);
139 ok(ret
== 1, "GetClipRgn returned %d instead of 1\n", ret
);
143 ok(ret
== SIMPLEREGION
, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret
);
145 ret
= GetClipBox(hdc
, &rc_clip
);
146 ok(ret
== SIMPLEREGION
|| broken(ret
== COMPLEXREGION
), "GetClipBox returned %d instead of SIMPLEREGION\n", ret
);
147 SetRect(&rc
, 0, 0, 50, 50);
148 ok(EqualRect(&rc
, &rc_clip
),
149 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
150 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
151 rc_clip
.left
, rc_clip
.top
, rc_clip
.right
, rc_clip
.bottom
);
153 ret
= RestoreDC(hdc
, 1);
154 ok(ret
, "ret = %d\n", ret
);
156 ret
= GetClipBox(hdc
, &rc_clip
);
157 ok(ret
== SIMPLEREGION
|| broken(ret
== COMPLEXREGION
), "GetClipBox returned %d instead of SIMPLEREGION\n", ret
);
158 SetRect(&rc
, 0, 0, 100, 100);
159 ok(EqualRect(&rc
, &rc_clip
),
160 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
161 rc
.left
, rc
.top
, rc
.right
, rc
.bottom
,
162 rc_clip
.left
, rc_clip
.top
, rc_clip
.right
, rc_clip
.bottom
);
165 ReleaseDC(hwnd
, hdc
);
169 static void test_savedc(void)
171 HDC hdc
= CreateDCA("DISPLAY", NULL
, NULL
, NULL
);
174 ok(hdc
!= NULL
, "CreateDC rets %p\n", hdc
);
177 ok(ret
== 1, "ret = %d\n", ret
);
179 ok(ret
== 2, "ret = %d\n", ret
);
181 ok(ret
== 3, "ret = %d\n", ret
);
182 ret
= RestoreDC(hdc
, -1);
183 ok(ret
, "ret = %d\n", ret
);
185 ok(ret
== 3, "ret = %d\n", ret
);
186 ret
= RestoreDC(hdc
, 1);
187 ok(ret
, "ret = %d\n", ret
);
189 ok(ret
== 1, "ret = %d\n", ret
);
191 ok(ret
== 2, "ret = %d\n", ret
);
193 ok(ret
== 3, "ret = %d\n", ret
);
194 ret
= RestoreDC(hdc
, -2);
195 ok(ret
, "ret = %d\n", ret
);
197 ok(ret
== 2, "ret = %d\n", ret
);
198 ret
= RestoreDC(hdc
, -2);
199 ok(ret
, "ret = %d\n", ret
);
201 ok(ret
== 1, "ret = %d\n", ret
);
203 ok(ret
== 2, "ret = %d\n", ret
);
204 ret
= RestoreDC(hdc
, -4);
205 ok(!ret
, "ret = %d\n", ret
);
206 ret
= RestoreDC(hdc
, 3);
207 ok(!ret
, "ret = %d\n", ret
);
209 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
210 ret
= RestoreDC(hdc
, -3);
212 broken(ret
), /* Win9x */
215 /* Trying to clear an empty save stack fails. */
216 ret
= RestoreDC(hdc
, -3);
217 ok(!ret
, "ret = %d\n", ret
);
221 broken(ret
== 1), /* Win9x */
224 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
225 ret
= RestoreDC(hdc
, 0);
227 broken(ret
), /* Win9x */
230 /* Trying to clear an empty save stack fails. */
231 ret
= RestoreDC(hdc
, 0);
232 ok(!ret
, "ret = %d\n", ret
);
234 ret
= RestoreDC(hdc
, 1);
236 broken(!ret
), /* Win9x */
242 static void test_GdiConvertToDevmodeW(void)
244 DEVMODEW
* (WINAPI
*pGdiConvertToDevmodeW
)(const DEVMODEA
*);
249 pGdiConvertToDevmodeW
= (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
250 if (!pGdiConvertToDevmodeW
)
252 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
256 ret
= EnumDisplaySettingsA(NULL
, ENUM_CURRENT_SETTINGS
, &dmA
);
257 ok(ret
, "EnumDisplaySettingsExA error %u\n", GetLastError());
258 ok(dmA
.dmSize
>= FIELD_OFFSET(DEVMODEA
, dmICMMethod
), "dmSize is too small: %04x\n", dmA
.dmSize
);
259 ok(dmA
.dmSize
<= sizeof(DEVMODEA
), "dmSize is too large: %04x\n", dmA
.dmSize
);
261 dmW
= pGdiConvertToDevmodeW(&dmA
);
262 ok(dmW
->dmSize
>= FIELD_OFFSET(DEVMODEW
, dmICMMethod
), "dmSize is too small: %04x\n", dmW
->dmSize
);
263 ok(dmW
->dmSize
<= sizeof(DEVMODEW
), "dmSize is too large: %04x\n", dmW
->dmSize
);
264 HeapFree(GetProcessHeap(), 0, dmW
);
266 dmA
.dmSize
= FIELD_OFFSET(DEVMODEA
, dmFields
) + sizeof(dmA
.dmFields
);
267 dmW
= pGdiConvertToDevmodeW(&dmA
);
268 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmFields
) + sizeof(dmW
->dmFields
),
269 "wrong size %u\n", dmW
->dmSize
);
270 HeapFree(GetProcessHeap(), 0, dmW
);
272 dmA
.dmICMMethod
= DMICMMETHOD_NONE
;
273 dmA
.dmSize
= FIELD_OFFSET(DEVMODEA
, dmICMMethod
) + sizeof(dmA
.dmICMMethod
);
274 dmW
= pGdiConvertToDevmodeW(&dmA
);
275 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmICMMethod
) + sizeof(dmW
->dmICMMethod
),
276 "wrong size %u\n", dmW
->dmSize
);
277 ok(dmW
->dmICMMethod
== DMICMMETHOD_NONE
,
278 "expected DMICMMETHOD_NONE, got %u\n", dmW
->dmICMMethod
);
279 HeapFree(GetProcessHeap(), 0, dmW
);
282 dmW
= pGdiConvertToDevmodeW(&dmA
);
283 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmPanningHeight
) + sizeof(dmW
->dmPanningHeight
),
284 "wrong size %u\n", dmW
->dmSize
);
285 HeapFree(GetProcessHeap(), 0, dmW
);
287 SetLastError(0xdeadbeef);
289 dmW
= pGdiConvertToDevmodeW(&dmA
);
290 ok(!dmW
, "GdiConvertToDevmodeW should fail\n");
291 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
293 /* this is the minimal dmSize that XP accepts */
294 dmA
.dmSize
= FIELD_OFFSET(DEVMODEA
, dmFields
);
295 dmW
= pGdiConvertToDevmodeW(&dmA
);
296 ok(dmW
->dmSize
== FIELD_OFFSET(DEVMODEW
, dmFields
),
297 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW
, dmFields
), dmW
->dmSize
);
298 HeapFree(GetProcessHeap(), 0, dmW
);
301 static void test_device_caps( HDC hdc
, HDC ref_dc
, const char *descr
)
303 static const int caps
[] =
322 /* TEXTCAPS broken on printer DC on winxp */
349 if (GetObjectType( hdc
) == OBJ_METADC
)
351 for (i
= 0; i
< sizeof(caps
)/sizeof(caps
[0]); i
++)
352 ok( GetDeviceCaps( hdc
, caps
[i
] ) == (caps
[i
] == TECHNOLOGY
? DT_METAFILE
: 0),
353 "wrong caps on %s for %u: %u\n", descr
, caps
[i
],
354 GetDeviceCaps( hdc
, caps
[i
] ) );
356 SetLastError( 0xdeadbeef );
357 ret
= GetDeviceGammaRamp( hdc
, &ramp
);
358 ok( !ret
, "GetDeviceGammaRamp succeeded on %s\n", descr
);
359 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef), /* nt4 */
360 "wrong error %u on %s\n", GetLastError(), descr
);
364 for (i
= 0; i
< sizeof(caps
)/sizeof(caps
[0]); i
++)
365 ok( GetDeviceCaps( hdc
, caps
[i
] ) == GetDeviceCaps( ref_dc
, caps
[i
] ),
366 "mismatched caps on %s for %u: %u/%u\n", descr
, caps
[i
],
367 GetDeviceCaps( hdc
, caps
[i
] ), GetDeviceCaps( ref_dc
, caps
[i
] ) );
369 SetLastError( 0xdeadbeef );
370 ret
= GetDeviceGammaRamp( hdc
, &ramp
);
371 ok( !ret
, "GetDeviceGammaRamp succeeded on %s\n", descr
);
372 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef), /* nt4 */
373 "wrong error %u on %s\n", GetLastError(), descr
);
376 if (GetObjectType( hdc
) == OBJ_MEMDC
)
378 char buffer
[sizeof(BITMAPINFOHEADER
) + 256 * sizeof(RGBQUAD
)];
379 BITMAPINFO
*info
= (BITMAPINFO
*)buffer
;
382 memset( buffer
, 0, sizeof(buffer
) );
383 info
->bmiHeader
.biSize
= sizeof(BITMAPINFOHEADER
);
384 info
->bmiHeader
.biWidth
= 16;
385 info
->bmiHeader
.biHeight
= 16;
386 info
->bmiHeader
.biPlanes
= 1;
387 info
->bmiHeader
.biBitCount
= 8;
388 info
->bmiHeader
.biCompression
= BI_RGB
;
389 dib
= CreateDIBSection( ref_dc
, info
, DIB_RGB_COLORS
, NULL
, NULL
, 0 );
390 old
= SelectObject( hdc
, dib
);
392 for (i
= 0; i
< sizeof(caps
)/sizeof(caps
[0]); i
++)
393 ok( GetDeviceCaps( hdc
, caps
[i
] ) == GetDeviceCaps( ref_dc
, caps
[i
] ),
394 "mismatched caps on %s and DIB for %u: %u/%u\n", descr
, caps
[i
],
395 GetDeviceCaps( hdc
, caps
[i
] ), GetDeviceCaps( ref_dc
, caps
[i
] ) );
397 SetLastError( 0xdeadbeef );
398 ret
= GetDeviceGammaRamp( hdc
, &ramp
);
399 ok( !ret
, "GetDeviceGammaRamp succeeded on %s\n", descr
);
400 ok( GetLastError() == ERROR_INVALID_PARAMETER
|| broken(GetLastError() == 0xdeadbeef), /* nt4 */
401 "wrong error %u on %s\n", GetLastError(), descr
);
403 SelectObject( hdc
, old
);
408 static void test_CreateCompatibleDC(void)
411 HDC hdc
, hNewDC
, hdcMetafile
, screen_dc
;
415 screen_dc
= GetDC( 0 );
416 bitmap
= CreateBitmap( 10, 10, 1, 1, NULL
);
418 /* Create a DC compatible with the screen */
419 hdc
= CreateCompatibleDC(NULL
);
420 ok(hdc
!= NULL
, "CreateCompatibleDC returned %p\n", hdc
);
421 ok( SelectObject( hdc
, bitmap
) != 0, "SelectObject failed\n" );
422 caps
= GetDeviceCaps( hdc
, TECHNOLOGY
);
423 ok( caps
== DT_RASDISPLAY
, "wrong caps %u\n", caps
);
425 test_device_caps( hdc
, screen_dc
, "display dc" );
427 /* Delete this DC, this should succeed */
428 bRet
= DeleteDC(hdc
);
429 ok(bRet
== TRUE
, "DeleteDC returned %u\n", bRet
);
431 /* Try to create a DC compatible to the deleted DC. This has to fail */
432 hNewDC
= CreateCompatibleDC(hdc
);
433 ok(hNewDC
== NULL
, "CreateCompatibleDC returned %p\n", hNewDC
);
436 hdcMetafile
= CreateEnhMetaFileA(hdc
, NULL
, NULL
, NULL
);
437 ok(hdcMetafile
!= 0, "CreateEnhMetaFileA failed\n");
438 hNewDC
= CreateCompatibleDC( hdcMetafile
);
439 ok(hNewDC
!= NULL
, "CreateCompatibleDC failed\n");
440 ok( SelectObject( hNewDC
, bitmap
) != 0, "SelectObject failed\n" );
441 caps
= GetDeviceCaps( hdcMetafile
, TECHNOLOGY
);
442 ok( caps
== DT_RASDISPLAY
, "wrong caps %u\n", caps
);
443 caps
= GetDeviceCaps( hNewDC
, TECHNOLOGY
);
444 ok( caps
== DT_RASDISPLAY
, "wrong caps %u\n", caps
);
446 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile
));
449 hdcMetafile
= CreateMetaFileA(NULL
);
450 ok(hdcMetafile
!= 0, "CreateEnhMetaFileA failed\n");
451 hNewDC
= CreateCompatibleDC( hdcMetafile
);
452 ok(hNewDC
== NULL
, "CreateCompatibleDC succeeded\n");
453 caps
= GetDeviceCaps( hdcMetafile
, TECHNOLOGY
);
454 ok( caps
== DT_METAFILE
, "wrong caps %u\n", caps
);
455 test_device_caps( hdcMetafile
, screen_dc
, "metafile dc" );
456 DeleteMetaFile( CloseMetaFile( hdcMetafile
));
458 DeleteObject( bitmap
);
459 ReleaseDC( 0, screen_dc
);
462 static void test_DC_bitmap(void)
466 HBITMAP hbmp
, oldhbmp
;
470 /* fill bitmap data with b&w pattern */
471 for( i
= 0; i
< 64; i
++) bits
[i
] = i
& 1 ? 0 : 0xffffff;
474 ok( hdc
!= NULL
, "CreateDC rets %p\n", hdc
);
475 bitspixel
= GetDeviceCaps( hdc
, BITSPIXEL
);
476 /* create a memory dc */
477 hdcmem
= CreateCompatibleDC( hdc
);
478 ok( hdcmem
!= NULL
, "CreateCompatibleDC rets %p\n", hdcmem
);
480 /* test monochrome bitmap: should always work */
481 hbmp
= CreateBitmap(32, 32, 1, 1, bits
);
482 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
483 oldhbmp
= SelectObject( hdcmem
, hbmp
);
484 ok( oldhbmp
!= NULL
, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
485 col
= GetPixel( hdcmem
, 0, 0);
486 ok( col
== 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col
);
487 col
= GetPixel( hdcmem
, 1, 1);
488 ok( col
== 0x000000, "GetPixel returned %08x, expected 00000000\n", col
);
489 col
= GetPixel( hdcmem
, 100, 1);
490 ok( col
== CLR_INVALID
, "GetPixel returned %08x, expected ffffffff\n", col
);
491 SelectObject( hdcmem
, oldhbmp
);
494 /* test with 2 bits color depth, not likely to succeed */
495 hbmp
= CreateBitmap(16, 16, 1, 2, bits
);
496 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
497 oldhbmp
= SelectObject( hdcmem
, hbmp
);
499 ok( !oldhbmp
, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
500 if( oldhbmp
) SelectObject( hdcmem
, oldhbmp
);
503 /* test with 16 bits color depth, might succeed */
504 hbmp
= CreateBitmap(6, 6, 1, 16, bits
);
505 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
506 oldhbmp
= SelectObject( hdcmem
, hbmp
);
507 if( bitspixel
== 16) {
508 ok( oldhbmp
!= NULL
, "SelectObject returned NULL\n" );
509 col
= GetPixel( hdcmem
, 0, 0);
511 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col
);
512 col
= GetPixel( hdcmem
, 1, 1);
514 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col
);
516 if( oldhbmp
) SelectObject( hdcmem
, oldhbmp
);
519 /* test with 32 bits color depth, probably succeed */
520 hbmp
= CreateBitmap(4, 4, 1, 32, bits
);
521 ok( hbmp
!= NULL
, "CreateBitmap returns %p\n", hbmp
);
522 oldhbmp
= SelectObject( hdcmem
, hbmp
);
523 if( bitspixel
== 32) {
524 ok( oldhbmp
!= NULL
, "SelectObject returned NULL\n" );
525 col
= GetPixel( hdcmem
, 0, 0);
527 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col
);
528 col
= GetPixel( hdcmem
, 1, 1);
530 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col
);
532 if( oldhbmp
) SelectObject( hdcmem
, oldhbmp
);
537 static void test_DeleteDC(void)
545 hwnd
= CreateWindowExA(0, "static", NULL
, WS_POPUP
|WS_VISIBLE
, 0,0,100,100,
547 ok(hwnd
!= 0, "CreateWindowExA failed\n");
550 ok(hdc
!= 0, "GetDC failed\n");
551 ret
= GetObjectType(hdc
);
552 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
554 ok(ret
, "DeleteDC failed\n");
555 ret
= GetObjectType(hdc
);
556 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
558 hdc
= GetWindowDC(hwnd
);
559 ok(hdc
!= 0, "GetDC failed\n");
560 ret
= GetObjectType(hdc
);
561 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
563 ok(ret
, "DeleteDC failed\n");
564 ret
= GetObjectType(hdc
);
565 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
569 /* desktop window DC */
570 hwnd
= GetDesktopWindow();
571 ok(hwnd
!= 0, "GetDesktopWindow failed\n");
574 ok(hdc
!= 0, "GetDC failed\n");
575 ret
= GetObjectType(hdc
);
576 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
578 ok(ret
, "DeleteDC failed\n");
579 ret
= GetObjectType(hdc
);
580 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
582 hdc
= GetWindowDC(hwnd
);
583 ok(hdc
!= 0, "GetDC failed\n");
584 ret
= GetObjectType(hdc
);
585 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
587 ok(ret
, "DeleteDC failed\n");
588 ret
= GetObjectType(hdc
);
589 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
592 memset(&cls
, 0, sizeof(cls
));
593 cls
.cbSize
= sizeof(cls
);
594 cls
.style
= CS_CLASSDC
;
595 cls
.hInstance
= GetModuleHandle(0);
596 cls
.lpszClassName
= "Wine class DC";
597 cls
.lpfnWndProc
= DefWindowProcA
;
598 ret
= RegisterClassExA(&cls
);
599 ok(ret
, "RegisterClassExA failed\n");
601 hwnd
= CreateWindowExA(0, "Wine class DC", NULL
, WS_POPUP
|WS_VISIBLE
, 0,0,100,100,
603 ok(hwnd
!= 0, "CreateWindowExA failed\n");
606 ok(hdc
!= 0, "GetDC failed\n");
607 ret
= GetObjectType(hdc
);
608 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
610 ok(ret
, "DeleteDC failed\n");
611 ret
= GetObjectType(hdc
);
612 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
613 ret
= ReleaseDC(hwnd
, hdc
);
614 ok(ret
, "ReleaseDC failed\n");
615 ret
= GetObjectType(hdc
);
616 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
620 hdc
= GetWindowDC(hwnd
);
621 ok(hdc
!= 0, "GetDC failed\n");
622 ret
= GetObjectType(hdc
);
623 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
625 ok(ret
, "DeleteDC failed\n");
626 ret
= GetObjectType(hdc
);
627 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
631 ret
= GetObjectType(hdc_test
);
632 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
634 ret
= UnregisterClassA("Wine class DC", GetModuleHandle(NULL
));
635 ok(ret
, "UnregisterClassA failed\n");
637 ret
= GetObjectType(hdc_test
);
639 ok(!ret
, "GetObjectType should fail for a deleted DC\n");
642 memset(&cls
, 0, sizeof(cls
));
643 cls
.cbSize
= sizeof(cls
);
644 cls
.style
= CS_OWNDC
;
645 cls
.hInstance
= GetModuleHandle(0);
646 cls
.lpszClassName
= "Wine own DC";
647 cls
.lpfnWndProc
= DefWindowProcA
;
648 ret
= RegisterClassExA(&cls
);
649 ok(ret
, "RegisterClassExA failed\n");
651 hwnd
= CreateWindowExA(0, "Wine own DC", NULL
, WS_POPUP
|WS_VISIBLE
, 0,0,100,100,
653 ok(hwnd
!= 0, "CreateWindowExA failed\n");
656 ok(hdc
!= 0, "GetDC failed\n");
657 ret
= GetObjectType(hdc
);
658 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
660 ok(ret
, "DeleteDC failed\n");
661 ret
= GetObjectType(hdc
);
662 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
663 ret
= ReleaseDC(hwnd
, hdc
);
664 ok(ret
, "ReleaseDC failed\n");
665 ret
= GetObjectType(hdc
);
666 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
668 hdc
= GetWindowDC(hwnd
);
669 ok(hdc
!= 0, "GetDC failed\n");
670 ret
= GetObjectType(hdc
);
671 ok(ret
== OBJ_DC
, "expected OBJ_DC, got %d\n", ret
);
673 ok(ret
, "DeleteDC failed\n");
674 ret
= GetObjectType(hdc
);
675 ok(!ret
|| broken(ret
) /* win9x */, "GetObjectType should fail for a deleted DC\n");
679 ret
= UnregisterClassA("Wine own DC", GetModuleHandle(NULL
));
680 ok(ret
, "UnregisterClassA failed\n");
683 static void test_boundsrect(void)
687 RECT rect
, expect
, set_rect
;
690 hdc
= CreateCompatibleDC(0);
691 ok(hdc
!= NULL
, "CreateCompatibleDC failed\n");
692 bitmap
= CreateCompatibleBitmap( hdc
, 200, 200 );
693 SelectObject( hdc
, bitmap
);
695 ret
= GetBoundsRect(hdc
, NULL
, 0);
696 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
698 ret
= GetBoundsRect(hdc
, NULL
, ~0U);
699 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
701 /* Test parameter handling order. */
702 SetRect(&set_rect
, 10, 20, 40, 50);
703 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
705 "Expected return flag DCB_RESET to be set, got %u\n", ret
);
707 ret
= GetBoundsRect(hdc
, NULL
, DCB_RESET
);
709 "Expected GetBoundsRect to return 0, got %u\n", ret
);
711 ret
= GetBoundsRect(hdc
, &rect
, 0);
713 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret
);
714 SetRect(&expect
, 0, 0, 0, 0);
715 ok(EqualRect(&rect
, &expect
) ||
716 broken(EqualRect(&rect
, &set_rect
)), /* nt4 sp1-5 */
717 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
718 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
720 ret
= GetBoundsRect(NULL
, NULL
, 0);
721 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
723 ret
= GetBoundsRect(NULL
, NULL
, ~0U);
724 ok(ret
== 0, "Expected GetBoundsRect to return 0, got %u\n", ret
);
726 ret
= SetBoundsRect(NULL
, NULL
, 0);
727 ok(ret
== 0, "Expected SetBoundsRect to return 0, got %u\n", ret
);
729 ret
= SetBoundsRect(NULL
, NULL
, ~0U);
730 ok(ret
== 0, "Expected SetBoundsRect to return 0, got %u\n", ret
);
732 SetRect(&set_rect
, 10, 20, 40, 50);
733 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
734 ok(ret
== (DCB_RESET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
736 ret
= GetBoundsRect(hdc
, &rect
, 0);
737 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
738 SetRect(&expect
, 10, 20, 40, 50);
739 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
740 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
742 SetMapMode( hdc
, MM_ANISOTROPIC
);
743 SetViewportExtEx( hdc
, 2, 2, NULL
);
744 ret
= GetBoundsRect(hdc
, &rect
, 0);
745 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
746 SetRect(&expect
, 5, 10, 20, 25);
747 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
748 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
750 SetViewportOrgEx( hdc
, 20, 30, NULL
);
751 ret
= GetBoundsRect(hdc
, &rect
, 0);
752 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
753 SetRect(&expect
, -5, -5, 10, 10);
754 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
755 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
757 SetRect(&set_rect
, 10, 20, 40, 50);
758 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
759 ok(ret
== (DCB_SET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
761 ret
= GetBoundsRect(hdc
, &rect
, 0);
762 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
763 SetRect(&expect
, 10, 20, 40, 50);
764 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
765 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
767 SetMapMode( hdc
, MM_TEXT
);
768 SetViewportOrgEx( hdc
, 0, 0, NULL
);
769 ret
= GetBoundsRect(hdc
, &rect
, 0);
770 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
771 SetRect(&expect
, 40, 70, 100, 130);
772 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
773 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
777 pSetLayout( hdc
, LAYOUT_RTL
);
778 ret
= GetBoundsRect(hdc
, &rect
, 0);
779 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
780 SetRect(&expect
, 159, 70, 99, 130);
781 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
782 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
783 SetRect(&set_rect
, 50, 25, 30, 35);
784 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
785 ok(ret
== (DCB_SET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
786 ret
= GetBoundsRect(hdc
, &rect
, 0);
787 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
788 SetRect(&expect
, 50, 25, 30, 35);
789 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
790 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
792 pSetLayout( hdc
, LAYOUT_LTR
);
793 ret
= GetBoundsRect(hdc
, &rect
, 0);
794 ok(ret
== DCB_SET
, "GetBoundsRect returned %x\n", ret
);
795 SetRect(&expect
, 149, 25, 169, 35);
796 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
797 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
800 /* empty rect resets, except on nt4 */
801 SetRect(&expect
, 20, 20, 10, 10);
802 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
803 ok(ret
== (DCB_SET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
804 ret
= GetBoundsRect(hdc
, &rect
, 0);
805 ok(ret
== DCB_RESET
|| broken(ret
== DCB_SET
) /* nt4 */,
806 "GetBoundsRect returned %x\n", ret
);
807 if (ret
== DCB_RESET
)
809 SetRect(&expect
, 0, 0, 0, 0);
810 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
811 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
813 SetRect(&expect
, 20, 20, 20, 20);
814 ret
= SetBoundsRect(hdc
, &set_rect
, DCB_SET
);
815 ok(ret
== (DCB_RESET
| DCB_DISABLE
), "SetBoundsRect returned %x\n", ret
);
816 ret
= GetBoundsRect(hdc
, &rect
, 0);
817 ok(ret
== DCB_RESET
, "GetBoundsRect returned %x\n", ret
);
818 SetRect(&expect
, 0, 0, 0, 0);
819 ok(EqualRect(&rect
, &expect
), "Got (%d,%d)-(%d,%d)\n",
820 rect
.left
, rect
.top
, rect
.right
, rect
.bottom
);
824 DeleteObject( bitmap
);
827 static void test_desktop_colorres(void)
829 HDC hdc
= GetDC(NULL
);
830 int bitspixel
, colorres
;
832 bitspixel
= GetDeviceCaps(hdc
, BITSPIXEL
);
833 ok(bitspixel
!= 0, "Expected to get valid BITSPIXEL capability value\n");
835 colorres
= GetDeviceCaps(hdc
, COLORRES
);
837 broken(colorres
== 0), /* Win9x */
838 "Expected to get valid COLORRES capability value\n");
846 "Expected COLORRES to be 18, got %d\n", colorres
);
850 "Expected COLORRES to be 16, got %d\n", colorres
);
855 "Expected COLORRES to be 24, got %d\n", bitspixel
);
858 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel
, colorres
);
863 ReleaseDC(NULL
, hdc
);
866 static void test_gamma(void)
869 HDC hdc
= GetDC(NULL
);
870 WORD oldramp
[3][256], ramp
[3][256];
873 ret
= GetDeviceGammaRamp(hdc
, &oldramp
);
876 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
880 /* try to set back old ramp */
881 ret
= SetDeviceGammaRamp(hdc
, &oldramp
);
884 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
888 memcpy(ramp
, oldramp
, sizeof(ramp
));
890 /* set one color ramp to zeros */
891 memset(ramp
[0], 0, sizeof(ramp
[0]));
892 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
893 ok(!ret
, "SetDeviceGammaRamp succeeded\n");
895 /* set one color ramp to a flat straight rising line */
896 for (i
= 0; i
< 256; i
++) ramp
[0][i
] = i
;
897 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
898 todo_wine
ok(!ret
, "SetDeviceGammaRamp succeeded\n");
900 /* set one color ramp to a steep straight rising line */
901 for (i
= 0; i
< 256; i
++) ramp
[0][i
] = i
* 256;
902 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
903 ok(ret
, "SetDeviceGammaRamp failed\n");
905 /* try a bright gamma ramp */
908 for (i
= 2; i
< 256; i
++) ramp
[0][i
] = 0xFFFF;
909 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
910 ok(!ret
, "SetDeviceGammaRamp succeeded\n");
912 /* try ramps which are not uniform */
914 for (i
= 1; i
< 256; i
++) ramp
[0][i
] = ramp
[0][i
- 1] + 512;
915 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
916 ok(ret
, "SetDeviceGammaRamp failed\n");
918 for (i
= 2; i
< 256; i
+=2)
920 ramp
[0][i
- 1] = ramp
[0][i
- 2];
921 ramp
[0][i
] = ramp
[0][i
- 2] + 512;
923 ret
= SetDeviceGammaRamp(hdc
, &ramp
);
924 ok(ret
, "SetDeviceGammaRamp failed\n");
926 /* cleanup: set old ramp again */
927 ret
= SetDeviceGammaRamp(hdc
, &oldramp
);
928 ok(ret
, "SetDeviceGammaRamp failed\n");
931 ReleaseDC(NULL
, hdc
);
934 static HDC
create_printer_dc(void)
938 PRINTER_INFO_2A
*pbuf
= NULL
;
939 DRIVER_INFO_3A
*dbuf
= NULL
;
942 HMODULE winspool
= LoadLibraryA( "winspool.drv" );
943 BOOL (WINAPI
*pOpenPrinterA
)(LPSTR
, HANDLE
*, LPPRINTER_DEFAULTSA
);
944 BOOL (WINAPI
*pGetDefaultPrinterA
)(LPSTR
, LPDWORD
);
945 BOOL (WINAPI
*pGetPrinterA
)(HANDLE
, DWORD
, LPBYTE
, DWORD
, LPDWORD
);
946 BOOL (WINAPI
*pGetPrinterDriverA
)(HANDLE
, LPSTR
, DWORD
, LPBYTE
, DWORD
, LPDWORD
);
947 BOOL (WINAPI
*pClosePrinter
)(HANDLE
);
949 pGetDefaultPrinterA
= (void *)GetProcAddress( winspool
, "GetDefaultPrinterA" );
950 pOpenPrinterA
= (void *)GetProcAddress( winspool
, "OpenPrinterA" );
951 pGetPrinterA
= (void *)GetProcAddress( winspool
, "GetPrinterA" );
952 pGetPrinterDriverA
= (void *)GetProcAddress( winspool
, "GetPrinterDriverA" );
953 pClosePrinter
= (void *)GetProcAddress( winspool
, "ClosePrinter" );
955 if (!pGetDefaultPrinterA
|| !pOpenPrinterA
|| !pGetPrinterA
|| !pGetPrinterDriverA
|| !pClosePrinter
)
958 len
= sizeof(buffer
);
959 if (!pGetDefaultPrinterA( buffer
, &len
)) goto done
;
960 if (!pOpenPrinterA( buffer
, &hprn
, NULL
)) goto done
;
962 pGetPrinterA( hprn
, 2, NULL
, 0, &len
);
963 pbuf
= HeapAlloc( GetProcessHeap(), 0, len
);
964 if (!pGetPrinterA( hprn
, 2, (LPBYTE
)pbuf
, len
, &len
)) goto done
;
966 pGetPrinterDriverA( hprn
, NULL
, 3, NULL
, 0, &len
);
967 dbuf
= HeapAlloc( GetProcessHeap(), 0, len
);
968 if (!pGetPrinterDriverA( hprn
, NULL
, 3, (LPBYTE
)dbuf
, len
, &len
)) goto done
;
970 hdc
= CreateDCA( dbuf
->pDriverPath
, pbuf
->pPrinterName
, pbuf
->pPortName
, pbuf
->pDevMode
);
971 trace( "hdc %p for driver '%s' printer '%s' port '%s'\n", hdc
,
972 dbuf
->pDriverPath
, pbuf
->pPrinterName
, pbuf
->pPortName
);
974 HeapFree( GetProcessHeap(), 0, dbuf
);
975 HeapFree( GetProcessHeap(), 0, pbuf
);
976 if (hprn
) pClosePrinter( hprn
);
977 if (winspool
) FreeLibrary( winspool
);
978 if (!hdc
) skip( "could not create a DC for the default printer\n" );
982 static void test_printer_dc(void)
984 HDC memdc
, display_memdc
;
987 HDC hdc
= create_printer_dc();
991 memdc
= CreateCompatibleDC( hdc
);
992 display_memdc
= CreateCompatibleDC( 0 );
994 ok( memdc
!= NULL
, "CreateCompatibleDC failed for printer\n" );
995 ok( display_memdc
!= NULL
, "CreateCompatibleDC failed for screen\n" );
997 ret
= GetDeviceCaps( hdc
, TECHNOLOGY
);
998 ok( ret
== DT_RASPRINTER
, "wrong type %u\n", ret
);
1000 ret
= GetDeviceCaps( memdc
, TECHNOLOGY
);
1001 ok( ret
== DT_RASPRINTER
, "wrong type %u\n", ret
);
1003 ret
= GetDeviceCaps( display_memdc
, TECHNOLOGY
);
1004 ok( ret
== DT_RASDISPLAY
, "wrong type %u\n", ret
);
1006 test_device_caps( memdc
, hdc
, "printer dc" );
1008 bmp
= CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc
, BITSPIXEL
), NULL
);
1009 orig
= SelectObject( memdc
, bmp
);
1010 ok( orig
!= NULL
, "SelectObject failed\n" );
1011 ok( BitBlt( hdc
, 10, 10, 20, 20, memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1013 ok( !SelectObject( display_memdc
, bmp
), "SelectObject succeeded\n" );
1014 SelectObject( memdc
, orig
);
1015 DeleteObject( bmp
);
1017 bmp
= CreateBitmap( 100, 100, 1, 1, NULL
);
1018 orig
= SelectObject( display_memdc
, bmp
);
1019 ok( orig
!= NULL
, "SelectObject failed\n" );
1020 ok( !SelectObject( memdc
, bmp
), "SelectObject succeeded\n" );
1021 ok( BitBlt( hdc
, 10, 10, 20, 20, display_memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1022 ok( BitBlt( memdc
, 10, 10, 20, 20, display_memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1023 ok( BitBlt( display_memdc
, 10, 10, 20, 20, memdc
, 0, 0, SRCCOPY
), "BitBlt failed\n" );
1025 ret
= GetPixel( hdc
, 0, 0 );
1026 ok( ret
== CLR_INVALID
, "wrong pixel value %x\n", ret
);
1029 DeleteDC( display_memdc
);
1031 DeleteObject( bmp
);
1036 pSetLayout
= (void *)GetProcAddress( GetModuleHandle("gdi32.dll"), "SetLayout");
1040 test_GdiConvertToDevmodeW();
1041 test_CreateCompatibleDC();
1045 test_desktop_colorres();