[GDI32_WINETEST] Sync with Wine Staging 1.9.4. CORE-10912
[reactos.git] / rostests / winetests / gdi32 / dc.c
1 /*
2 * Unit tests for dc functions
3 *
4 * Copyright (c) 2005 Huw Davies
5 * Copyright (c) 2005 Dmitry Timoshkov
6 *
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.
11 *
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.
16 *
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
20 */
21
22
23 #define WINVER 0x0501 /* request latest DEVMODE */
24 #define NONAMELESSSTRUCT
25 #define NONAMELESSUNION
26
27 #include <assert.h>
28 #include <stdio.h>
29
30 #include "wine/test.h"
31 #include "winbase.h"
32 #include "wingdi.h"
33 #include "winuser.h"
34 #include "winspool.h"
35 #include "winerror.h"
36
37 #ifndef LAYOUT_LTR
38 #define LAYOUT_LTR 0
39 #endif
40
41 static DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
42
43 static void dump_region(HRGN hrgn)
44 {
45 DWORD i, size;
46 RGNDATA *data = NULL;
47 RECT *rect;
48
49 if (!hrgn)
50 {
51 printf( "(null) region\n" );
52 return;
53 }
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 );
60 printf( "\n" );
61 HeapFree( GetProcessHeap(), 0, data );
62 }
63
64 static void test_dc_values(void)
65 {
66 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
67 COLORREF color;
68 int extra;
69
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 );
83
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 );
96
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 );
108
109 DeleteDC( hdc );
110 }
111
112 static void test_savedc_2(void)
113 {
114 HWND hwnd;
115 HDC hdc;
116 HRGN hrgn;
117 RECT rc, rc_clip;
118 int ret;
119
120 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
121 0, 0, 0, NULL);
122 assert(hwnd != 0);
123 ShowWindow(hwnd, SW_SHOW);
124 UpdateWindow(hwnd);
125
126 hrgn = CreateRectRgn(0, 0, 0, 0);
127 assert(hrgn != 0);
128
129 hdc = GetDC(hwnd);
130 ok(hdc != NULL, "GetDC failed\n");
131
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);
145
146 ret = SaveDC(hdc);
147 ok(ret == 1, "ret = %d\n", ret);
148
149 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
150 if (ret == COMPLEXREGION)
151 {
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);
157 dump_region(hrgn);
158 }
159 else
160 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
161
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);
169
170 ret = RestoreDC(hdc, 1);
171 ok(ret, "ret = %d\n", ret);
172
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);
180
181 DeleteObject(hrgn);
182 ReleaseDC(hwnd, hdc);
183 DestroyWindow(hwnd);
184 }
185
186 static void test_savedc(void)
187 {
188 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
189 int ret;
190
191 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
192
193 ret = SaveDC(hdc);
194 ok(ret == 1, "ret = %d\n", ret);
195 ret = SaveDC(hdc);
196 ok(ret == 2, "ret = %d\n", ret);
197 ret = SaveDC(hdc);
198 ok(ret == 3, "ret = %d\n", ret);
199 ret = RestoreDC(hdc, -1);
200 ok(ret, "ret = %d\n", ret);
201 ret = SaveDC(hdc);
202 ok(ret == 3, "ret = %d\n", ret);
203 ret = RestoreDC(hdc, 1);
204 ok(ret, "ret = %d\n", ret);
205 ret = SaveDC(hdc);
206 ok(ret == 1, "ret = %d\n", ret);
207 ret = SaveDC(hdc);
208 ok(ret == 2, "ret = %d\n", ret);
209 ret = SaveDC(hdc);
210 ok(ret == 3, "ret = %d\n", ret);
211 ret = RestoreDC(hdc, -2);
212 ok(ret, "ret = %d\n", ret);
213 ret = SaveDC(hdc);
214 ok(ret == 2, "ret = %d\n", ret);
215 ret = RestoreDC(hdc, -2);
216 ok(ret, "ret = %d\n", ret);
217 ret = SaveDC(hdc);
218 ok(ret == 1, "ret = %d\n", ret);
219 ret = SaveDC(hdc);
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);
225
226 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
227 ret = RestoreDC(hdc, -3);
228 ok(!ret ||
229 broken(ret), /* Win9x */
230 "ret = %d\n", ret);
231
232 /* Trying to clear an empty save stack fails. */
233 ret = RestoreDC(hdc, -3);
234 ok(!ret, "ret = %d\n", ret);
235
236 ret = SaveDC(hdc);
237 ok(ret == 3 ||
238 broken(ret == 1), /* Win9x */
239 "ret = %d\n", ret);
240
241 /* Under Win9x the following RestoreDC call succeeds and clears the save stack. */
242 ret = RestoreDC(hdc, 0);
243 ok(!ret ||
244 broken(ret), /* Win9x */
245 "ret = %d\n", ret);
246
247 /* Trying to clear an empty save stack fails. */
248 ret = RestoreDC(hdc, 0);
249 ok(!ret, "ret = %d\n", ret);
250
251 ret = RestoreDC(hdc, 1);
252 ok(ret ||
253 broken(!ret), /* Win9x */
254 "ret = %d\n", ret);
255
256 DeleteDC(hdc);
257 }
258
259 static void test_GdiConvertToDevmodeW(void)
260 {
261 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
262 DEVMODEA dmA;
263 DEVMODEW *dmW;
264 BOOL ret;
265
266 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
267 if (!pGdiConvertToDevmodeW)
268 {
269 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
270 return;
271 }
272
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);
277
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);
282
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);
288
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);
297
298 dmA.dmSize = 1024;
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);
303
304 SetLastError(0xdeadbeef);
305 dmA.dmSize = 0;
306 dmW = pGdiConvertToDevmodeW(&dmA);
307 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
308 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
309
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);
316 }
317
318 static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale )
319 {
320 static const int caps[] =
321 {
322 DRIVERVERSION,
323 TECHNOLOGY,
324 HORZSIZE,
325 VERTSIZE,
326 HORZRES,
327 VERTRES,
328 BITSPIXEL,
329 PLANES,
330 NUMBRUSHES,
331 NUMPENS,
332 NUMMARKERS,
333 NUMFONTS,
334 NUMCOLORS,
335 PDEVICESIZE,
336 CURVECAPS,
337 LINECAPS,
338 POLYGONALCAPS,
339 /* TEXTCAPS broken on printer DC on winxp */
340 CLIPCAPS,
341 RASTERCAPS,
342 ASPECTX,
343 ASPECTY,
344 ASPECTXY,
345 LOGPIXELSX,
346 LOGPIXELSY,
347 SIZEPALETTE,
348 NUMRESERVED,
349 COLORRES,
350 PHYSICALWIDTH,
351 PHYSICALHEIGHT,
352 PHYSICALOFFSETX,
353 PHYSICALOFFSETY,
354 SCALINGFACTORX,
355 SCALINGFACTORY,
356 VREFRESH,
357 DESKTOPVERTRES,
358 DESKTOPHORZRES,
359 BLTALIGNMENT,
360 SHADEBLENDCAPS
361 };
362 unsigned int i;
363 WORD ramp[3][256];
364 BOOL ret;
365 RECT rect;
366 UINT type;
367
368 if (GetObjectType( hdc ) == OBJ_METADC)
369 {
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] ) );
374
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 );
382
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 );
390 }
391 else
392 {
393 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
394 {
395 INT precision = 0;
396 INT hdc_caps = GetDeviceCaps( hdc, caps[i] );
397
398 switch (caps[i])
399 {
400 case HORZSIZE:
401 case VERTSIZE:
402 hdc_caps /= scale;
403 precision = 1;
404 break;
405 case LOGPIXELSX:
406 case LOGPIXELSY:
407 hdc_caps *= scale;
408 break;
409 }
410
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 );
414 }
415
416 SetLastError( 0xdeadbeef );
417 ret = GetDeviceGammaRamp( hdc, &ramp );
418 if (GetObjectType( hdc ) != OBJ_DC || GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER)
419 {
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 );
423 }
424 else
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 todo_wine_if (GetObjectType( hdc ) == OBJ_ENHMETADC)
428 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
429
430 type = GetBoundsRect( hdc, &rect, 0 );
431 ok( type == DCB_RESET || broken(type == DCB_SET) /* XP */,
432 "GetBoundsRect returned type %x for %s\n", type, descr );
433 if (type == DCB_RESET)
434 ok( rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0,
435 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
436 rect.left, rect.top, rect.right, rect.bottom, type, descr );
437 type = SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
438 ok( type == (DCB_RESET | DCB_DISABLE) || broken(type == (DCB_SET | DCB_ENABLE)) /* XP */,
439 "SetBoundsRect returned %x for %s (hdc type %d)\n", type, descr, GetObjectType( hdc ) );
440
441 SetMapMode( hdc, MM_TEXT );
442 Rectangle( hdc, 2, 2, 4, 4 );
443 type = GetBoundsRect( hdc, &rect, DCB_RESET );
444 todo_wine_if (GetObjectType( hdc ) == OBJ_ENHMETADC || (GetObjectType( hdc ) == OBJ_DC && GetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER))
445 ok( rect.left == 2 && rect.top == 2 && rect.right == 4 && rect.bottom == 4 && type == DCB_SET,
446 "GetBoundsRect returned %d,%d,%d,%d type %x for %s\n",
447 rect.left, rect.top, rect.right, rect.bottom, type, descr );
448 }
449
450 type = GetClipBox( ref_dc, &rect );
451 if (type != COMPLEXREGION && type != ERROR) /* region can be complex on multi-monitor setups */
452 {
453 RECT ref_rect;
454
455 ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
456 if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY)
457 {
458 todo_wine_if (GetSystemMetrics( SM_CXSCREEN ) != GetSystemMetrics( SM_CXVIRTUALSCREEN ))
459 ok( GetDeviceCaps( ref_dc, DESKTOPHORZRES ) == GetSystemMetrics( SM_CXSCREEN ),
460 "Got DESKTOPHORZRES %d on %s, expected %d\n",
461 GetDeviceCaps( ref_dc, DESKTOPHORZRES ), descr, GetSystemMetrics( SM_CXSCREEN ) );
462
463 todo_wine_if (GetSystemMetrics( SM_CYSCREEN ) != GetSystemMetrics( SM_CYVIRTUALSCREEN ))
464 ok( GetDeviceCaps( ref_dc, DESKTOPVERTRES ) == GetSystemMetrics( SM_CYSCREEN ),
465 "Got DESKTOPVERTRES %d on %s, expected %d\n",
466 GetDeviceCaps( ref_dc, DESKTOPVERTRES ), descr, GetSystemMetrics( SM_CYSCREEN ) );
467
468 SetRect( &ref_rect, GetSystemMetrics( SM_XVIRTUALSCREEN ), GetSystemMetrics( SM_YVIRTUALSCREEN ),
469 GetSystemMetrics( SM_XVIRTUALSCREEN ) + GetSystemMetrics( SM_CXVIRTUALSCREEN ),
470 GetSystemMetrics( SM_YVIRTUALSCREEN ) + GetSystemMetrics( SM_CYVIRTUALSCREEN ) );
471 }
472 else
473 {
474 SetRect( &ref_rect, 0, 0, GetDeviceCaps( ref_dc, DESKTOPHORZRES ),
475 GetDeviceCaps( ref_dc, DESKTOPVERTRES ) );
476 }
477
478 todo_wine_if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY && GetObjectType( hdc ) != OBJ_ENHMETADC &&
479 (GetSystemMetrics( SM_XVIRTUALSCREEN ) || GetSystemMetrics( SM_YVIRTUALSCREEN )))
480 ok( EqualRect( &rect, &ref_rect ), "GetClipBox returned %d,%d,%d,%d on %s\n",
481 rect.left, rect.top, rect.right, rect.bottom, descr );
482 }
483
484 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_ACCUMULATE );
485 SetMapMode( ref_dc, MM_TEXT );
486 Rectangle( ref_dc, 3, 3, 5, 5 );
487 type = GetBoundsRect( ref_dc, &rect, DCB_RESET );
488 /* it may or may not work on non-memory DCs */
489 ok( (rect.left == 0 && rect.top == 0 && rect.right == 0 && rect.bottom == 0 && type == DCB_RESET) ||
490 (rect.left == 3 && rect.top == 3 && rect.right == 5 && rect.bottom == 5 && type == DCB_SET),
491 "GetBoundsRect returned %d,%d,%d,%d type %x on %s\n",
492 rect.left, rect.top, rect.right, rect.bottom, type, descr );
493
494 if (GetObjectType( hdc ) == OBJ_MEMDC)
495 {
496 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
497 BITMAPINFO *info = (BITMAPINFO *)buffer;
498 HBITMAP dib, old;
499
500 memset( buffer, 0, sizeof(buffer) );
501 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
502 info->bmiHeader.biWidth = 16;
503 info->bmiHeader.biHeight = 16;
504 info->bmiHeader.biPlanes = 1;
505 info->bmiHeader.biBitCount = 8;
506 info->bmiHeader.biCompression = BI_RGB;
507 dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
508 old = SelectObject( hdc, dib );
509
510 for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
511 ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
512 "mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
513 GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
514
515 SetLastError( 0xdeadbeef );
516 ret = GetDeviceGammaRamp( hdc, &ramp );
517 ok( !ret, "GetDeviceGammaRamp succeeded on %s\n", descr );
518 ok( GetLastError() == ERROR_INVALID_PARAMETER || broken(GetLastError() == 0xdeadbeef), /* nt4 */
519 "wrong error %u on %s\n", GetLastError(), descr );
520
521 type = GetClipBox( hdc, &rect );
522 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
523 ok( rect.left == 0 && rect.top == 0 && rect.right == 16 && rect.bottom == 16,
524 "GetClipBox returned %d,%d,%d,%d on memdc for %s\n",
525 rect.left, rect.top, rect.right, rect.bottom, descr );
526
527 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
528 SetMapMode( hdc, MM_TEXT );
529 Rectangle( hdc, 5, 5, 12, 14 );
530 type = GetBoundsRect( hdc, &rect, DCB_RESET );
531 ok( rect.left == 5 && rect.top == 5 && rect.right == 12 && rect.bottom == 14 && type == DCB_SET,
532 "GetBoundsRect returned %d,%d,%d,%d type %x on memdc for %s\n",
533 rect.left, rect.top, rect.right, rect.bottom, type, descr );
534
535 SelectObject( hdc, old );
536 DeleteObject( dib );
537 }
538
539 /* restore hdc state */
540 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_DISABLE );
541 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_DISABLE );
542 }
543
544 static void test_CreateCompatibleDC(void)
545 {
546 BOOL bRet;
547 HDC hdc, hNewDC, hdcMetafile, screen_dc;
548 HBITMAP bitmap;
549 INT caps;
550 DEVMODEA dm;
551
552 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
553
554 bRet = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dm);
555 ok(bRet, "EnumDisplaySettingsEx failed\n");
556 dm.u1.s1.dmScale = 200;
557 dm.dmFields |= DM_SCALE;
558 hdc = CreateDCA( "DISPLAY", NULL, NULL, &dm );
559
560 screen_dc = CreateDCA( "DISPLAY", NULL, NULL, NULL );
561 test_device_caps( hdc, screen_dc, "display dc", 1 );
562 ResetDCA( hdc, &dm );
563 test_device_caps( hdc, screen_dc, "display dc", 1 );
564 DeleteDC( hdc );
565
566 /* Create a DC compatible with the screen */
567 hdc = CreateCompatibleDC(NULL);
568 ok(hdc != NULL, "CreateCompatibleDC returned %p\n", hdc);
569 ok( SelectObject( hdc, bitmap ) != 0, "SelectObject failed\n" );
570 caps = GetDeviceCaps( hdc, TECHNOLOGY );
571 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
572
573 test_device_caps( hdc, screen_dc, "display dc", 1 );
574
575 /* Delete this DC, this should succeed */
576 bRet = DeleteDC(hdc);
577 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
578
579 /* Try to create a DC compatible to the deleted DC. This has to fail */
580 hNewDC = CreateCompatibleDC(hdc);
581 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
582
583 hdc = GetDC( 0 );
584 hdcMetafile = CreateEnhMetaFileA(hdc, NULL, NULL, NULL);
585 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
586 hNewDC = CreateCompatibleDC( hdcMetafile );
587 ok(hNewDC != NULL, "CreateCompatibleDC failed\n");
588 ok( SelectObject( hNewDC, bitmap ) != 0, "SelectObject failed\n" );
589 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
590 ok( caps == DT_RASDISPLAY, "wrong caps %u\n", caps );
591 test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
592 ResetDCA( hdcMetafile, &dm );
593 test_device_caps( hdcMetafile, hdc, "enhmetafile dc", 1 );
594 DeleteDC( hNewDC );
595 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
596 ReleaseDC( 0, hdc );
597
598 hdcMetafile = CreateMetaFileA(NULL);
599 ok(hdcMetafile != 0, "CreateEnhMetaFileA failed\n");
600 hNewDC = CreateCompatibleDC( hdcMetafile );
601 ok(hNewDC == NULL, "CreateCompatibleDC succeeded\n");
602 caps = GetDeviceCaps( hdcMetafile, TECHNOLOGY );
603 ok( caps == DT_METAFILE, "wrong caps %u\n", caps );
604 test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
605 ResetDCA( hdcMetafile, &dm );
606 test_device_caps( hdcMetafile, screen_dc, "metafile dc", 1 );
607 DeleteMetaFile( CloseMetaFile( hdcMetafile ));
608
609 DeleteObject( bitmap );
610 DeleteDC( screen_dc );
611 }
612
613 static void test_DC_bitmap(void)
614 {
615 PIXELFORMATDESCRIPTOR descr;
616 HDC hdc, hdcmem;
617 DWORD bits[64];
618 HBITMAP hbmp, oldhbmp;
619 COLORREF col;
620 int i, bitspixel;
621 int ret, ret2;
622
623 /* fill bitmap data with b&w pattern */
624 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
625
626 hdc = GetDC(0);
627 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
628 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
629 /* create a memory dc */
630 hdcmem = CreateCompatibleDC( hdc);
631 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
632
633 /* test DescribePixelFormat with descr == NULL */
634 ret2 = DescribePixelFormat(hdcmem, 0, sizeof(descr), NULL);
635 ok(ret2 > 0, "expected ret2 > 0, got %d\n", ret2);
636 ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), NULL);
637 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
638 ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), NULL);
639 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
640
641 /* test DescribePixelFormat with descr != NULL */
642 memset(&descr, 0, sizeof(descr));
643 ret = DescribePixelFormat(hdcmem, 0, sizeof(descr), &descr);
644 ok(ret == 0, "expected ret == 0, got %d\n", ret);
645 ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
646
647 memset(&descr, 0, sizeof(descr));
648 ret = DescribePixelFormat(hdcmem, 1, sizeof(descr), &descr);
649 ok(ret == ret2, "expected ret == %d, got %d\n", ret2, ret);
650 ok(descr.nSize == sizeof(descr), "expected desc.nSize == sizeof(descr), got %d\n", descr.nSize);
651
652 memset(&descr, 0, sizeof(descr));
653 ret = DescribePixelFormat(hdcmem, 0x10000, sizeof(descr), &descr);
654 ok(ret == 0, "expected ret == 0, got %d\n", ret);
655 ok(descr.nSize == 0, "expected descr.nSize == 0, got %d\n", descr.nSize);
656
657 /* test monochrome bitmap: should always work */
658 hbmp = CreateBitmap(32, 32, 1, 1, bits);
659 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
660 oldhbmp = SelectObject( hdcmem, hbmp);
661 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
662 col = GetPixel( hdcmem, 0, 0);
663 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
664 col = GetPixel( hdcmem, 1, 1);
665 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
666 col = GetPixel( hdcmem, 100, 1);
667 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
668 SelectObject( hdcmem, oldhbmp);
669 DeleteObject( hbmp);
670
671 /* test with 2 bits color depth, not likely to succeed */
672 hbmp = CreateBitmap(16, 16, 1, 2, bits);
673 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
674 oldhbmp = SelectObject( hdcmem, hbmp);
675 if( bitspixel != 2)
676 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
677 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
678 DeleteObject( hbmp);
679
680 /* test with 16 bits color depth, might succeed */
681 hbmp = CreateBitmap(6, 6, 1, 16, bits);
682 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
683 oldhbmp = SelectObject( hdcmem, hbmp);
684 if( bitspixel == 16) {
685 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
686 col = GetPixel( hdcmem, 0, 0);
687 ok( col == 0xffffff,
688 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
689 col = GetPixel( hdcmem, 1, 1);
690 ok( col == 0x000000,
691 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
692 }
693 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
694 DeleteObject( hbmp);
695
696 /* test with 32 bits color depth, probably succeed */
697 hbmp = CreateBitmap(4, 4, 1, 32, bits);
698 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
699 oldhbmp = SelectObject( hdcmem, hbmp);
700 if( bitspixel == 32) {
701 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
702 col = GetPixel( hdcmem, 0, 0);
703 ok( col == 0xffffff,
704 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
705 col = GetPixel( hdcmem, 1, 1);
706 ok( col == 0x000000,
707 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
708 }
709 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
710 DeleteObject( hbmp);
711 ReleaseDC( 0, hdc );
712 }
713
714 static void test_DeleteDC(void)
715 {
716 HWND hwnd;
717 HDC hdc, hdc_test;
718 WNDCLASSEXA cls;
719 int ret;
720
721 /* window DC */
722 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
723 0, 0, 0, NULL);
724 ok(hwnd != 0, "CreateWindowExA failed\n");
725
726 hdc = GetDC(hwnd);
727 ok(hdc != 0, "GetDC failed\n");
728 ret = GetObjectType(hdc);
729 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
730 ret = DeleteDC(hdc);
731 ok(ret, "DeleteDC failed\n");
732 ret = GetObjectType(hdc);
733 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
734
735 hdc = GetWindowDC(hwnd);
736 ok(hdc != 0, "GetDC failed\n");
737 ret = GetObjectType(hdc);
738 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
739 ret = DeleteDC(hdc);
740 ok(ret, "DeleteDC failed\n");
741 ret = GetObjectType(hdc);
742 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
743
744 DestroyWindow(hwnd);
745
746 /* desktop window DC */
747 hwnd = GetDesktopWindow();
748 ok(hwnd != 0, "GetDesktopWindow failed\n");
749
750 hdc = GetDC(hwnd);
751 ok(hdc != 0, "GetDC failed\n");
752 ret = GetObjectType(hdc);
753 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
754 ret = DeleteDC(hdc);
755 ok(ret, "DeleteDC failed\n");
756 ret = GetObjectType(hdc);
757 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
758
759 hdc = GetWindowDC(hwnd);
760 ok(hdc != 0, "GetDC failed\n");
761 ret = GetObjectType(hdc);
762 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
763 ret = DeleteDC(hdc);
764 ok(ret, "DeleteDC failed\n");
765 ret = GetObjectType(hdc);
766 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
767
768 /* CS_CLASSDC */
769 memset(&cls, 0, sizeof(cls));
770 cls.cbSize = sizeof(cls);
771 cls.style = CS_CLASSDC;
772 cls.hInstance = GetModuleHandleA(NULL);
773 cls.lpszClassName = "Wine class DC";
774 cls.lpfnWndProc = DefWindowProcA;
775 ret = RegisterClassExA(&cls);
776 ok(ret, "RegisterClassExA failed\n");
777
778 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
779 0, 0, 0, NULL);
780 ok(hwnd != 0, "CreateWindowExA failed\n");
781
782 hdc = GetDC(hwnd);
783 ok(hdc != 0, "GetDC failed\n");
784 ret = GetObjectType(hdc);
785 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
786 ret = DeleteDC(hdc);
787 ok(ret, "DeleteDC failed\n");
788 ret = GetObjectType(hdc);
789 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
790 ret = ReleaseDC(hwnd, hdc);
791 ok(ret, "ReleaseDC failed\n");
792 ret = GetObjectType(hdc);
793 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
794
795 hdc_test = hdc;
796
797 hdc = GetWindowDC(hwnd);
798 ok(hdc != 0, "GetDC failed\n");
799 ret = GetObjectType(hdc);
800 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
801 ret = DeleteDC(hdc);
802 ok(ret, "DeleteDC failed\n");
803 ret = GetObjectType(hdc);
804 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
805
806 DestroyWindow(hwnd);
807
808 ret = GetObjectType(hdc_test);
809 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
810
811 ret = UnregisterClassA("Wine class DC", GetModuleHandleA(NULL));
812 ok(ret, "UnregisterClassA failed\n");
813
814 ret = GetObjectType(hdc_test);
815 todo_wine
816 ok(!ret, "GetObjectType should fail for a deleted DC\n");
817
818 /* CS_OWNDC */
819 memset(&cls, 0, sizeof(cls));
820 cls.cbSize = sizeof(cls);
821 cls.style = CS_OWNDC;
822 cls.hInstance = GetModuleHandleA(NULL);
823 cls.lpszClassName = "Wine own DC";
824 cls.lpfnWndProc = DefWindowProcA;
825 ret = RegisterClassExA(&cls);
826 ok(ret, "RegisterClassExA failed\n");
827
828 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
829 0, 0, 0, NULL);
830 ok(hwnd != 0, "CreateWindowExA failed\n");
831
832 hdc = GetDC(hwnd);
833 ok(hdc != 0, "GetDC failed\n");
834 ret = GetObjectType(hdc);
835 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
836 ret = DeleteDC(hdc);
837 ok(ret, "DeleteDC failed\n");
838 ret = GetObjectType(hdc);
839 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
840 ret = ReleaseDC(hwnd, hdc);
841 ok(ret, "ReleaseDC failed\n");
842 ret = GetObjectType(hdc);
843 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
844
845 hdc = GetWindowDC(hwnd);
846 ok(hdc != 0, "GetDC failed\n");
847 ret = GetObjectType(hdc);
848 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
849 ret = DeleteDC(hdc);
850 ok(ret, "DeleteDC failed\n");
851 ret = GetObjectType(hdc);
852 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
853
854 DestroyWindow(hwnd);
855
856 ret = UnregisterClassA("Wine own DC", GetModuleHandleA(NULL));
857 ok(ret, "UnregisterClassA failed\n");
858 }
859
860 static void test_boundsrect(void)
861 {
862 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
863 BITMAPINFO *info = (BITMAPINFO *)buffer;
864 HDC hdc;
865 HBITMAP bitmap, dib, old;
866 RECT rect, expect, set_rect;
867 UINT ret;
868 int i, level;
869
870 hdc = CreateCompatibleDC(0);
871 ok(hdc != NULL, "CreateCompatibleDC failed\n");
872 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
873 old = SelectObject( hdc, bitmap );
874
875 ret = GetBoundsRect(hdc, NULL, 0);
876 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
877
878 ret = GetBoundsRect(hdc, NULL, ~0U);
879 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
880
881 /* Test parameter handling order. */
882 SetRect(&set_rect, 10, 20, 40, 50);
883 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
884 ok(ret & DCB_RESET,
885 "Expected return flag DCB_RESET to be set, got %u\n", ret);
886
887 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
888 ok(ret == 0,
889 "Expected GetBoundsRect to return 0, got %u\n", ret);
890
891 ret = GetBoundsRect(hdc, &rect, 0);
892 ok(ret == DCB_RESET,
893 "Expected GetBoundsRect to return DCB_RESET, got %u\n", ret);
894 SetRect(&expect, 0, 0, 0, 0);
895 ok(EqualRect(&rect, &expect) ||
896 broken(EqualRect(&rect, &set_rect)), /* nt4 sp1-5 */
897 "Expected output rectangle (0,0)-(0,0), got (%d,%d)-(%d,%d)\n",
898 rect.left, rect.top, rect.right, rect.bottom);
899
900 ret = GetBoundsRect(NULL, NULL, 0);
901 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
902
903 ret = GetBoundsRect(NULL, NULL, ~0U);
904 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
905
906 ret = SetBoundsRect(NULL, NULL, 0);
907 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
908
909 ret = SetBoundsRect(NULL, NULL, ~0U);
910 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
911
912 SetRect(&set_rect, 10, 20, 40, 50);
913 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
914 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
915
916 ret = GetBoundsRect(hdc, &rect, 0);
917 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
918 SetRect(&expect, 10, 20, 40, 50);
919 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
920 rect.left, rect.top, rect.right, rect.bottom);
921
922 SetMapMode( hdc, MM_ANISOTROPIC );
923 SetViewportExtEx( hdc, 2, 2, NULL );
924 ret = GetBoundsRect(hdc, &rect, 0);
925 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
926 SetRect(&expect, 5, 10, 20, 25);
927 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
928 rect.left, rect.top, rect.right, rect.bottom);
929
930 SetViewportOrgEx( hdc, 20, 30, NULL );
931 ret = GetBoundsRect(hdc, &rect, 0);
932 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
933 SetRect(&expect, -5, -5, 10, 10);
934 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
935 rect.left, rect.top, rect.right, rect.bottom);
936
937 SetRect(&set_rect, 10, 20, 40, 50);
938 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
939 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
940
941 ret = GetBoundsRect(hdc, &rect, 0);
942 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
943 SetRect(&expect, 10, 20, 40, 50);
944 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
945 rect.left, rect.top, rect.right, rect.bottom);
946
947 SetMapMode( hdc, MM_TEXT );
948 SetViewportOrgEx( hdc, 0, 0, NULL );
949 ret = GetBoundsRect(hdc, &rect, 0);
950 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
951 SetRect(&expect, 40, 70, 100, 130);
952 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
953 rect.left, rect.top, rect.right, rect.bottom);
954
955 if (pSetLayout)
956 {
957 pSetLayout( hdc, LAYOUT_RTL );
958 ret = GetBoundsRect(hdc, &rect, 0);
959 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
960 SetRect(&expect, 159, 70, 99, 130);
961 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
962 rect.left, rect.top, rect.right, rect.bottom);
963 SetRect(&set_rect, 50, 25, 30, 35);
964 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
965 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
966 ret = GetBoundsRect(hdc, &rect, 0);
967 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
968 SetRect(&expect, 50, 25, 30, 35);
969 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
970 rect.left, rect.top, rect.right, rect.bottom);
971
972 pSetLayout( hdc, LAYOUT_LTR );
973 ret = GetBoundsRect(hdc, &rect, 0);
974 ok(ret == DCB_SET, "GetBoundsRect returned %x\n", ret);
975 SetRect(&expect, 149, 25, 169, 35);
976 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
977 rect.left, rect.top, rect.right, rect.bottom);
978 }
979
980 /* empty rect resets, except on nt4 */
981 SetRect(&expect, 20, 20, 10, 10);
982 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
983 ok(ret == (DCB_SET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
984 ret = GetBoundsRect(hdc, &rect, 0);
985 ok(ret == DCB_RESET || broken(ret == DCB_SET) /* nt4 */,
986 "GetBoundsRect returned %x\n", ret);
987 if (ret == DCB_RESET)
988 {
989 SetRect(&expect, 0, 0, 0, 0);
990 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
991 rect.left, rect.top, rect.right, rect.bottom);
992
993 SetRect(&expect, 20, 20, 20, 20);
994 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
995 ok(ret == (DCB_RESET | DCB_DISABLE), "SetBoundsRect returned %x\n", ret);
996 ret = GetBoundsRect(hdc, &rect, 0);
997 ok(ret == DCB_RESET, "GetBoundsRect returned %x\n", ret);
998 SetRect(&expect, 0, 0, 0, 0);
999 ok(EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n",
1000 rect.left, rect.top, rect.right, rect.bottom);
1001 }
1002
1003 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_ENABLE );
1004 MoveToEx( hdc, 10, 10, NULL );
1005 LineTo( hdc, 20, 20 );
1006 ret = GetBoundsRect( hdc, &rect, 0 );
1007 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1008 SetRect( &expect, 10, 10, 21, 21 );
1009 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1010 SetRect( &rect, 8, 8, 23, 23 );
1011 expect = rect;
1012 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
1013 ret = GetBoundsRect( hdc, &rect, 0 );
1014 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1015 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1016
1017 level = SaveDC( hdc );
1018 LineTo( hdc, 30, 25 );
1019 ret = GetBoundsRect( hdc, &rect, 0 );
1020 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1021 SetRect( &expect, 8, 8, 31, 26 );
1022 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1023 SetBoundsRect( hdc, NULL, DCB_DISABLE );
1024 LineTo( hdc, 40, 40 );
1025 ret = GetBoundsRect( hdc, &rect, 0 );
1026 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1027 SetRect( &expect, 8, 8, 31, 26 );
1028 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1029 SetRect( &rect, 6, 6, 30, 30 );
1030 SetBoundsRect( hdc, &rect, DCB_ACCUMULATE );
1031 ret = GetBoundsRect( hdc, &rect, 0 );
1032 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1033 SetRect( &expect, 6, 6, 31, 30 );
1034 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1035
1036 RestoreDC( hdc, level );
1037 ret = GetBoundsRect( hdc, &rect, 0 );
1038 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1039 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1040 LineTo( hdc, 40, 40 );
1041 ret = GetBoundsRect( hdc, &rect, 0 );
1042 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1043 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1044
1045 SelectObject( hdc, old );
1046 ret = GetBoundsRect( hdc, &rect, 0 );
1047 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1048 SetRect( &expect, 6, 6, 1, 1 );
1049 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1050 SetBoundsRect( hdc, NULL, DCB_ENABLE );
1051 LineTo( hdc, 50, 40 );
1052
1053 SelectObject( hdc, bitmap );
1054 ret = GetBoundsRect( hdc, &rect, 0 );
1055 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1056 SetRect( &expect, 6, 6, 51, 41 );
1057 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1058 SelectObject( hdc, GetStockObject( NULL_PEN ));
1059 LineTo( hdc, 50, 50 );
1060 ret = GetBoundsRect( hdc, &rect, 0 );
1061 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1062 SetRect( &expect, 6, 6, 51, 51 );
1063 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1064
1065 memset( buffer, 0, sizeof(buffer) );
1066 info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
1067 info->bmiHeader.biWidth = 256;
1068 info->bmiHeader.biHeight = 256;
1069 info->bmiHeader.biPlanes = 1;
1070 info->bmiHeader.biBitCount = 8;
1071 info->bmiHeader.biCompression = BI_RGB;
1072 dib = CreateDIBSection( 0, info, DIB_RGB_COLORS, NULL, NULL, 0 );
1073 ok( dib != 0, "failed to create DIB\n" );
1074 SelectObject( hdc, dib );
1075 ret = GetBoundsRect( hdc, &rect, 0 );
1076 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1077 SetRect( &expect, 6, 6, 51, 51 );
1078 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1079 LineTo( hdc, 55, 30 );
1080 ret = GetBoundsRect( hdc, &rect, 0 );
1081 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1082 SetRect( &expect, 6, 6, 56, 51 );
1083 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1084 LineTo( hdc, 300, 30 );
1085 ret = GetBoundsRect( hdc, &rect, 0 );
1086 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1087 SetRect( &expect, 6, 6, 256, 51 );
1088 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1089 LineTo( hdc, -300, -300 );
1090 ret = GetBoundsRect( hdc, &rect, 0 );
1091 ok( ret == DCB_SET, "GetBoundsRect returned %x\n", ret );
1092 SetRect( &expect, 0, 0, 256, 51 );
1093 ok( EqualRect(&rect, &expect), "Got (%d,%d)-(%d,%d)\n", rect.left, rect.top, rect.right, rect.bottom );
1094
1095 /* test the wide pen heuristics */
1096 SetBoundsRect( hdc, NULL, DCB_ENABLE | DCB_RESET );
1097 for (i = 0; i < 1000; i++)
1098 {
1099 static const UINT endcaps[3] = { PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT };
1100 static const UINT joins[3] = { PS_JOIN_ROUND, PS_JOIN_BEVEL, PS_JOIN_MITER };
1101 LOGBRUSH brush = { BS_SOLID, RGB(0,0,0), 0 };
1102 UINT join = joins[i % 3];
1103 UINT endcap = endcaps[(i / 3) % 3];
1104 INT inflate, width = 1 + i / 9;
1105 HPEN pen = ExtCreatePen( PS_GEOMETRIC | join | endcap | PS_SOLID, width, &brush, 0, NULL );
1106 HPEN old = SelectObject( hdc, pen );
1107 MoveToEx( hdc, 100, 100, NULL );
1108 LineTo( hdc, 160, 100 );
1109 LineTo( hdc, 100, 160 );
1110 LineTo( hdc, 160, 160 );
1111 GetBoundsRect( hdc, &rect, DCB_RESET );
1112 SetRect( &expect, 100, 100, 161, 161 );
1113
1114 inflate = width + 2;
1115 if (join == PS_JOIN_MITER)
1116 {
1117 inflate *= 5;
1118 if (endcap == PS_ENDCAP_SQUARE)
1119 InflateRect( &expect, (inflate * 3 + 1) / 2, (inflate * 3 + 1) / 2 );
1120 else
1121 InflateRect( &expect, inflate, inflate );
1122 }
1123 else
1124 {
1125 if (endcap == PS_ENDCAP_SQUARE)
1126 InflateRect( &expect, inflate - inflate / 4, inflate - inflate / 4 );
1127 else
1128 InflateRect( &expect, (inflate + 1) / 2, (inflate + 1) / 2 );
1129 }
1130 expect.left = max( expect.left, 0 );
1131 expect.top = max( expect.top, 0 );
1132 expect.right = min( expect.right, 256 );
1133 expect.bottom = min( expect.bottom, 256 );
1134 ok( EqualRect(&rect, &expect),
1135 "Got %d,%d,%d,%d expected %d,%d,%d,%d %u/%x/%x\n",
1136 rect.left, rect.top, rect.right, rect.bottom,
1137 expect.left, expect.top, expect.right, expect.bottom, width, endcap, join );
1138 DeleteObject( SelectObject( hdc, old ));
1139 }
1140
1141 DeleteDC( hdc );
1142 DeleteObject( bitmap );
1143 DeleteObject( dib );
1144 }
1145
1146 static void test_desktop_colorres(void)
1147 {
1148 HDC hdc = GetDC(NULL);
1149 int bitspixel, colorres;
1150
1151 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
1152 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
1153
1154 colorres = GetDeviceCaps(hdc, COLORRES);
1155 ok(colorres != 0 ||
1156 broken(colorres == 0), /* Win9x */
1157 "Expected to get valid COLORRES capability value\n");
1158
1159 if (colorres)
1160 {
1161 switch (bitspixel)
1162 {
1163 case 8:
1164 ok(colorres == 18,
1165 "Expected COLORRES to be 18, got %d\n", colorres);
1166 break;
1167 case 16:
1168 ok(colorres == 16,
1169 "Expected COLORRES to be 16, got %d\n", colorres);
1170 break;
1171 case 24:
1172 case 32:
1173 ok(colorres == 24,
1174 "Expected COLORRES to be 24, got %d\n", bitspixel);
1175 break;
1176 default:
1177 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
1178 break;
1179 }
1180 }
1181
1182 ReleaseDC(NULL, hdc);
1183 }
1184
1185 static void test_gamma(void)
1186 {
1187 BOOL ret;
1188 HDC hdc = GetDC(NULL);
1189 WORD oldramp[3][256], ramp[3][256];
1190 INT i;
1191
1192 ret = GetDeviceGammaRamp(hdc, &oldramp);
1193 if (!ret)
1194 {
1195 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
1196 goto done;
1197 }
1198
1199 /* try to set back old ramp */
1200 ret = SetDeviceGammaRamp(hdc, &oldramp);
1201 if (!ret)
1202 {
1203 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
1204 goto done;
1205 }
1206
1207 memcpy(ramp, oldramp, sizeof(ramp));
1208
1209 /* set one color ramp to zeros */
1210 memset(ramp[0], 0, sizeof(ramp[0]));
1211 ret = SetDeviceGammaRamp(hdc, &ramp);
1212 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1213
1214 /* set one color ramp to a flat straight rising line */
1215 for (i = 0; i < 256; i++) ramp[0][i] = i;
1216 ret = SetDeviceGammaRamp(hdc, &ramp);
1217 todo_wine ok(!ret, "SetDeviceGammaRamp succeeded\n");
1218
1219 /* set one color ramp to a steep straight rising line */
1220 for (i = 0; i < 256; i++) ramp[0][i] = i * 256;
1221 ret = SetDeviceGammaRamp(hdc, &ramp);
1222 ok(ret, "SetDeviceGammaRamp failed\n");
1223
1224 /* try a bright gamma ramp */
1225 ramp[0][0] = 0;
1226 ramp[0][1] = 0x7FFF;
1227 for (i = 2; i < 256; i++) ramp[0][i] = 0xFFFF;
1228 ret = SetDeviceGammaRamp(hdc, &ramp);
1229 ok(!ret, "SetDeviceGammaRamp succeeded\n");
1230
1231 /* try ramps which are not uniform */
1232 ramp[0][0] = 0;
1233 for (i = 1; i < 256; i++) ramp[0][i] = ramp[0][i - 1] + 512;
1234 ret = SetDeviceGammaRamp(hdc, &ramp);
1235 ok(ret, "SetDeviceGammaRamp failed\n");
1236 ramp[0][0] = 0;
1237 for (i = 2; i < 256; i+=2)
1238 {
1239 ramp[0][i - 1] = ramp[0][i - 2];
1240 ramp[0][i] = ramp[0][i - 2] + 512;
1241 }
1242 ret = SetDeviceGammaRamp(hdc, &ramp);
1243 ok(ret, "SetDeviceGammaRamp failed\n");
1244
1245 /* cleanup: set old ramp again */
1246 ret = SetDeviceGammaRamp(hdc, &oldramp);
1247 ok(ret, "SetDeviceGammaRamp failed\n");
1248
1249 done:
1250 ReleaseDC(NULL, hdc);
1251 }
1252
1253 static BOOL is_postscript_printer(HDC hdc)
1254 {
1255 char tech[256];
1256
1257 if (ExtEscape(hdc, GETTECHNOLOGY, 0, NULL, sizeof(tech), tech) > 0)
1258 return strcmp(tech, "PostScript") == 0;
1259
1260 return FALSE;
1261 }
1262
1263 static HDC create_printer_dc(int scale, BOOL reset)
1264 {
1265 char buffer[260];
1266 DWORD len;
1267 PRINTER_INFO_2A *pbuf = NULL;
1268 DRIVER_INFO_3A *dbuf = NULL;
1269 HANDLE hprn = 0;
1270 HDC hdc = 0;
1271 HMODULE winspool = LoadLibraryA( "winspool.drv" );
1272 BOOL (WINAPI *pOpenPrinterA)(LPSTR, HANDLE *, LPPRINTER_DEFAULTSA);
1273 BOOL (WINAPI *pGetDefaultPrinterA)(LPSTR, LPDWORD);
1274 BOOL (WINAPI *pGetPrinterA)(HANDLE, DWORD, LPBYTE, DWORD, LPDWORD);
1275 BOOL (WINAPI *pGetPrinterDriverA)(HANDLE, LPSTR, DWORD, LPBYTE, DWORD, LPDWORD);
1276 BOOL (WINAPI *pClosePrinter)(HANDLE);
1277
1278 pGetDefaultPrinterA = (void *)GetProcAddress( winspool, "GetDefaultPrinterA" );
1279 pOpenPrinterA = (void *)GetProcAddress( winspool, "OpenPrinterA" );
1280 pGetPrinterA = (void *)GetProcAddress( winspool, "GetPrinterA" );
1281 pGetPrinterDriverA = (void *)GetProcAddress( winspool, "GetPrinterDriverA" );
1282 pClosePrinter = (void *)GetProcAddress( winspool, "ClosePrinter" );
1283
1284 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
1285 goto done;
1286
1287 len = sizeof(buffer);
1288 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
1289 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
1290
1291 pGetPrinterA( hprn, 2, NULL, 0, &len );
1292 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
1293 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
1294
1295 pGetPrinterDriverA( hprn, NULL, 3, NULL, 0, &len );
1296 dbuf = HeapAlloc( GetProcessHeap(), 0, len );
1297 if (!pGetPrinterDriverA( hprn, NULL, 3, (LPBYTE)dbuf, len, &len )) goto done;
1298
1299 pbuf->pDevMode->u1.s1.dmScale = scale;
1300 pbuf->pDevMode->dmFields |= DM_SCALE;
1301
1302 hdc = CreateDCA( dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName, pbuf->pDevMode );
1303 trace( "hdc %p for driver '%s' printer '%s' port '%s' is %sPostScript\n", hdc,
1304 dbuf->pDriverPath, pbuf->pPrinterName, pbuf->pPortName,
1305 is_postscript_printer(hdc) ? "" : "NOT " );
1306
1307 if (reset) ResetDCA( hdc, pbuf->pDevMode );
1308 done:
1309 HeapFree( GetProcessHeap(), 0, dbuf );
1310 HeapFree( GetProcessHeap(), 0, pbuf );
1311 if (hprn) pClosePrinter( hprn );
1312 if (winspool) FreeLibrary( winspool );
1313 if (!hdc) skip( "could not create a DC for the default printer\n" );
1314 return hdc;
1315 }
1316
1317 static void test_printer_dc(void)
1318 {
1319 HDC memdc, display_memdc, enhmf_dc;
1320 HBITMAP orig, bmp;
1321 DWORD ret;
1322 HDC hdc, hdc_200;
1323
1324 hdc = create_printer_dc(100, FALSE);
1325 hdc_200 = create_printer_dc(200, FALSE);
1326
1327 if (!hdc || !hdc_200) return;
1328
1329 test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 );
1330 DeleteDC( hdc_200 );
1331
1332 hdc_200 = create_printer_dc(200, TRUE);
1333 test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 );
1334 DeleteDC( hdc_200 );
1335
1336 memdc = CreateCompatibleDC( hdc );
1337 display_memdc = CreateCompatibleDC( 0 );
1338
1339 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
1340 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
1341
1342 ret = GetDeviceCaps( hdc, TECHNOLOGY );
1343 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1344
1345 ret = GetDeviceCaps( memdc, TECHNOLOGY );
1346 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1347
1348 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
1349 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
1350
1351 bmp = CreateBitmap( 100, 100, 1, GetDeviceCaps( hdc, BITSPIXEL ), NULL );
1352 orig = SelectObject( memdc, bmp );
1353 ok( orig != NULL, "SelectObject failed\n" );
1354 ok( BitBlt( hdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1355
1356 test_device_caps( memdc, hdc, "printer dc", 1 );
1357
1358 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
1359 SelectObject( memdc, orig );
1360 DeleteObject( bmp );
1361
1362 bmp = CreateBitmap( 100, 100, 1, 1, NULL );
1363 orig = SelectObject( display_memdc, bmp );
1364 ok( orig != NULL, "SelectObject failed\n" );
1365 ok( !SelectObject( memdc, bmp ), "SelectObject succeeded\n" );
1366 ok( BitBlt( hdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1367 ok( BitBlt( memdc, 10, 10, 20, 20, display_memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1368 ok( BitBlt( display_memdc, 10, 10, 20, 20, memdc, 0, 0, SRCCOPY ), "BitBlt failed\n" );
1369
1370 ret = GetPixel( hdc, 0, 0 );
1371 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
1372
1373 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1374 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1375 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 );
1376 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1377
1378 enhmf_dc = CreateEnhMetaFileA( hdc, NULL, NULL, NULL );
1379 ok(enhmf_dc != 0, "CreateEnhMetaFileA failed\n");
1380 test_device_caps( enhmf_dc, hdc, "enhmetafile printer dc", 1 );
1381 DeleteEnhMetaFile( CloseEnhMetaFile( enhmf_dc ));
1382
1383 DeleteDC( memdc );
1384 DeleteDC( display_memdc );
1385 DeleteDC( hdc );
1386 DeleteObject( bmp );
1387 }
1388
1389 START_TEST(dc)
1390 {
1391 pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
1392 test_dc_values();
1393 test_savedc();
1394 test_savedc_2();
1395 test_GdiConvertToDevmodeW();
1396 test_CreateCompatibleDC();
1397 test_DC_bitmap();
1398 test_DeleteDC();
1399 test_boundsrect();
1400 test_desktop_colorres();
1401 test_gamma();
1402 test_printer_dc();
1403 }