[BRANCHES]
[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 if (GetObjectType( hdc ) == OBJ_ENHMETADC)
428 todo_wine ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
429 else
430 ok( type == SIMPLEREGION, "GetClipBox returned %d on memdc for %s\n", type, descr );
431
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 ) );
442
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))
447 todo_wine
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 );
451 else
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 );
455 }
456
457 type = GetClipBox( ref_dc, &rect );
458 if (type != COMPLEXREGION && type != ERROR) /* region can be complex on multi-monitor setups */
459 {
460 RECT ref_rect;
461
462 ok( type == SIMPLEREGION, "GetClipBox returned %d on %s\n", type, descr );
463 if (GetDeviceCaps( ref_dc, TECHNOLOGY ) == DT_RASDISPLAY)
464 {
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 ) );
469 else
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 ) );
473
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 ) );
478 else
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 ) );
482
483 SetRect( &ref_rect, GetSystemMetrics( SM_XVIRTUALSCREEN ), GetSystemMetrics( SM_YVIRTUALSCREEN ),
484 GetSystemMetrics( SM_XVIRTUALSCREEN ) + GetSystemMetrics( SM_CXVIRTUALSCREEN ),
485 GetSystemMetrics( SM_YVIRTUALSCREEN ) + GetSystemMetrics( SM_CYVIRTUALSCREEN ) );
486 }
487 else
488 {
489 SetRect( &ref_rect, 0, 0, GetDeviceCaps( ref_dc, DESKTOPHORZRES ),
490 GetDeviceCaps( ref_dc, DESKTOPVERTRES ) );
491 }
492
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 );
497 else
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 );
500 }
501
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 );
511
512 if (GetObjectType( hdc ) == OBJ_MEMDC)
513 {
514 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
515 BITMAPINFO *info = (BITMAPINFO *)buffer;
516 HBITMAP dib, old;
517
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 );
527
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] ) );
532
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 );
538
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 );
544
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 );
552
553 SelectObject( hdc, old );
554 DeleteObject( dib );
555 }
556
557 /* restore hdc state */
558 SetBoundsRect( hdc, NULL, DCB_RESET | DCB_DISABLE );
559 SetBoundsRect( ref_dc, NULL, DCB_RESET | DCB_DISABLE );
560 }
561
562 static void test_CreateCompatibleDC(void)
563 {
564 BOOL bRet;
565 HDC hdc, hNewDC, hdcMetafile, screen_dc;
566 HBITMAP bitmap;
567 INT caps;
568 DEVMODEA dm;
569
570 bitmap = CreateBitmap( 10, 10, 1, 1, NULL );
571
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 );
577
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 );
582 DeleteDC( hdc );
583
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 );
590
591 test_device_caps( hdc, screen_dc, "display dc", 1 );
592
593 /* Delete this DC, this should succeed */
594 bRet = DeleteDC(hdc);
595 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
596
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);
600
601 hdc = GetDC( 0 );
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 );
612 DeleteDC( hNewDC );
613 DeleteEnhMetaFile( CloseEnhMetaFile( hdcMetafile ));
614 ReleaseDC( 0, hdc );
615
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 ));
626
627 DeleteObject( bitmap );
628 DeleteDC( screen_dc );
629 }
630
631 static void test_DC_bitmap(void)
632 {
633 HDC hdc, hdcmem;
634 DWORD bits[64];
635 HBITMAP hbmp, oldhbmp;
636 COLORREF col;
637 int i, bitspixel;
638
639 /* fill bitmap data with b&w pattern */
640 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
641
642 hdc = GetDC(0);
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);
648 /* tests */
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);
661 DeleteObject( hbmp);
662
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);
667 if( bitspixel != 2)
668 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
669 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
670 DeleteObject( hbmp);
671
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);
679 ok( col == 0xffffff,
680 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
681 col = GetPixel( hdcmem, 1, 1);
682 ok( col == 0x000000,
683 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
684 }
685 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
686 DeleteObject( hbmp);
687
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);
695 ok( col == 0xffffff,
696 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
697 col = GetPixel( hdcmem, 1, 1);
698 ok( col == 0x000000,
699 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
700 }
701 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
702 DeleteObject( hbmp);
703 ReleaseDC( 0, hdc );
704 }
705
706 static void test_DeleteDC(void)
707 {
708 HWND hwnd;
709 HDC hdc, hdc_test;
710 WNDCLASSEXA cls;
711 int ret;
712
713 /* window DC */
714 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
715 0, 0, 0, NULL);
716 ok(hwnd != 0, "CreateWindowExA failed\n");
717
718 hdc = GetDC(hwnd);
719 ok(hdc != 0, "GetDC failed\n");
720 ret = GetObjectType(hdc);
721 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
722 ret = DeleteDC(hdc);
723 ok(ret, "DeleteDC failed\n");
724 ret = GetObjectType(hdc);
725 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
726
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);
731 ret = DeleteDC(hdc);
732 ok(ret, "DeleteDC failed\n");
733 ret = GetObjectType(hdc);
734 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
735
736 DestroyWindow(hwnd);
737
738 /* desktop window DC */
739 hwnd = GetDesktopWindow();
740 ok(hwnd != 0, "GetDesktopWindow failed\n");
741
742 hdc = GetDC(hwnd);
743 ok(hdc != 0, "GetDC failed\n");
744 ret = GetObjectType(hdc);
745 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
746 ret = DeleteDC(hdc);
747 ok(ret, "DeleteDC failed\n");
748 ret = GetObjectType(hdc);
749 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
750
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);
755 ret = DeleteDC(hdc);
756 ok(ret, "DeleteDC failed\n");
757 ret = GetObjectType(hdc);
758 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
759
760 /* CS_CLASSDC */
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");
769
770 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
771 0, 0, 0, NULL);
772 ok(hwnd != 0, "CreateWindowExA failed\n");
773
774 hdc = GetDC(hwnd);
775 ok(hdc != 0, "GetDC failed\n");
776 ret = GetObjectType(hdc);
777 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
778 ret = DeleteDC(hdc);
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);
786
787 hdc_test = hdc;
788
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);
793 ret = DeleteDC(hdc);
794 ok(ret, "DeleteDC failed\n");
795 ret = GetObjectType(hdc);
796 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
797
798 DestroyWindow(hwnd);
799
800 ret = GetObjectType(hdc_test);
801 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
802
803 ret = UnregisterClassA("Wine class DC", GetModuleHandleA(NULL));
804 ok(ret, "UnregisterClassA failed\n");
805
806 ret = GetObjectType(hdc_test);
807 todo_wine
808 ok(!ret, "GetObjectType should fail for a deleted DC\n");
809
810 /* CS_OWNDC */
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");
819
820 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
821 0, 0, 0, NULL);
822 ok(hwnd != 0, "CreateWindowExA failed\n");
823
824 hdc = GetDC(hwnd);
825 ok(hdc != 0, "GetDC failed\n");
826 ret = GetObjectType(hdc);
827 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
828 ret = DeleteDC(hdc);
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);
836
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);
841 ret = DeleteDC(hdc);
842 ok(ret, "DeleteDC failed\n");
843 ret = GetObjectType(hdc);
844 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
845
846 DestroyWindow(hwnd);
847
848 ret = UnregisterClassA("Wine own DC", GetModuleHandleA(NULL));
849 ok(ret, "UnregisterClassA failed\n");
850 }
851
852 static void test_boundsrect(void)
853 {
854 char buffer[sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD)];
855 BITMAPINFO *info = (BITMAPINFO *)buffer;
856 HDC hdc;
857 HBITMAP bitmap, dib, old;
858 RECT rect, expect, set_rect;
859 UINT ret;
860 int i, level;
861
862 hdc = CreateCompatibleDC(0);
863 ok(hdc != NULL, "CreateCompatibleDC failed\n");
864 bitmap = CreateCompatibleBitmap( hdc, 200, 200 );
865 old = SelectObject( hdc, bitmap );
866
867 ret = GetBoundsRect(hdc, NULL, 0);
868 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
869
870 ret = GetBoundsRect(hdc, NULL, ~0U);
871 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
872
873 /* Test parameter handling order. */
874 SetRect(&set_rect, 10, 20, 40, 50);
875 ret = SetBoundsRect(hdc, &set_rect, DCB_SET);
876 ok(ret & DCB_RESET,
877 "Expected return flag DCB_RESET to be set, got %u\n", ret);
878
879 ret = GetBoundsRect(hdc, NULL, DCB_RESET);
880 ok(ret == 0,
881 "Expected GetBoundsRect to return 0, got %u\n", ret);
882
883 ret = GetBoundsRect(hdc, &rect, 0);
884 ok(ret == DCB_RESET,
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);
891
892 ret = GetBoundsRect(NULL, NULL, 0);
893 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
894
895 ret = GetBoundsRect(NULL, NULL, ~0U);
896 ok(ret == 0, "Expected GetBoundsRect to return 0, got %u\n", ret);
897
898 ret = SetBoundsRect(NULL, NULL, 0);
899 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
900
901 ret = SetBoundsRect(NULL, NULL, ~0U);
902 ok(ret == 0, "Expected SetBoundsRect to return 0, got %u\n", ret);
903
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);
907
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);
913
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);
921
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);
928
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);
932
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);
938
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);
946
947 if (pSetLayout)
948 {
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);
963
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);
970 }
971
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)
980 {
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);
984
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);
993 }
994
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 );
1003 expect = rect;
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 );
1008
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 );
1027
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 );
1036
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 );
1044
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 );
1056
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 );
1086
1087 /* test the wide pen heuristics */
1088 SetBoundsRect( hdc, NULL, DCB_ENABLE | DCB_RESET );
1089 for (i = 0; i < 1000; i++)
1090 {
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 );
1105
1106 inflate = width + 2;
1107 if (join == PS_JOIN_MITER)
1108 {
1109 inflate *= 5;
1110 if (endcap == PS_ENDCAP_SQUARE)
1111 InflateRect( &expect, (inflate * 3 + 1) / 2, (inflate * 3 + 1) / 2 );
1112 else
1113 InflateRect( &expect, inflate, inflate );
1114 }
1115 else
1116 {
1117 if (endcap == PS_ENDCAP_SQUARE)
1118 InflateRect( &expect, inflate - inflate / 4, inflate - inflate / 4 );
1119 else
1120 InflateRect( &expect, (inflate + 1) / 2, (inflate + 1) / 2 );
1121 }
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 ));
1131 }
1132
1133 DeleteDC( hdc );
1134 DeleteObject( bitmap );
1135 DeleteObject( dib );
1136 }
1137
1138 static void test_desktop_colorres(void)
1139 {
1140 HDC hdc = GetDC(NULL);
1141 int bitspixel, colorres;
1142
1143 bitspixel = GetDeviceCaps(hdc, BITSPIXEL);
1144 ok(bitspixel != 0, "Expected to get valid BITSPIXEL capability value\n");
1145
1146 colorres = GetDeviceCaps(hdc, COLORRES);
1147 ok(colorres != 0 ||
1148 broken(colorres == 0), /* Win9x */
1149 "Expected to get valid COLORRES capability value\n");
1150
1151 if (colorres)
1152 {
1153 switch (bitspixel)
1154 {
1155 case 8:
1156 ok(colorres == 18,
1157 "Expected COLORRES to be 18, got %d\n", colorres);
1158 break;
1159 case 16:
1160 ok(colorres == 16,
1161 "Expected COLORRES to be 16, got %d\n", colorres);
1162 break;
1163 case 24:
1164 case 32:
1165 ok(colorres == 24,
1166 "Expected COLORRES to be 24, got %d\n", bitspixel);
1167 break;
1168 default:
1169 ok(0, "Got unknown BITSPIXEL %d with COLORRES %d\n", bitspixel, colorres);
1170 break;
1171 }
1172 }
1173
1174 ReleaseDC(NULL, hdc);
1175 }
1176
1177 static void test_gamma(void)
1178 {
1179 BOOL ret;
1180 HDC hdc = GetDC(NULL);
1181 WORD oldramp[3][256], ramp[3][256];
1182 INT i;
1183
1184 ret = GetDeviceGammaRamp(hdc, &oldramp);
1185 if (!ret)
1186 {
1187 win_skip("GetDeviceGammaRamp failed, skipping tests\n");
1188 goto done;
1189 }
1190
1191 /* try to set back old ramp */
1192 ret = SetDeviceGammaRamp(hdc, &oldramp);
1193 if (!ret)
1194 {
1195 win_skip("SetDeviceGammaRamp failed, skipping tests\n");
1196 goto done;
1197 }
1198
1199 memcpy(ramp, oldramp, sizeof(ramp));
1200
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");
1205
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");
1210
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");
1215
1216 /* try a bright gamma ramp */
1217 ramp[0][0] = 0;
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");
1222
1223 /* try ramps which are not uniform */
1224 ramp[0][0] = 0;
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");
1228 ramp[0][0] = 0;
1229 for (i = 2; i < 256; i+=2)
1230 {
1231 ramp[0][i - 1] = ramp[0][i - 2];
1232 ramp[0][i] = ramp[0][i - 2] + 512;
1233 }
1234 ret = SetDeviceGammaRamp(hdc, &ramp);
1235 ok(ret, "SetDeviceGammaRamp failed\n");
1236
1237 /* cleanup: set old ramp again */
1238 ret = SetDeviceGammaRamp(hdc, &oldramp);
1239 ok(ret, "SetDeviceGammaRamp failed\n");
1240
1241 done:
1242 ReleaseDC(NULL, hdc);
1243 }
1244
1245 static BOOL is_postscript_printer(HDC hdc)
1246 {
1247 char tech[256];
1248
1249 if (ExtEscape(hdc, GETTECHNOLOGY, 0, NULL, sizeof(tech), tech) > 0)
1250 return strcmp(tech, "PostScript") == 0;
1251
1252 return FALSE;
1253 }
1254
1255 static HDC create_printer_dc(int scale, BOOL reset)
1256 {
1257 char buffer[260];
1258 DWORD len;
1259 PRINTER_INFO_2A *pbuf = NULL;
1260 DRIVER_INFO_3A *dbuf = NULL;
1261 HANDLE hprn = 0;
1262 HDC hdc = 0;
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);
1269
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" );
1275
1276 if (!pGetDefaultPrinterA || !pOpenPrinterA || !pGetPrinterA || !pGetPrinterDriverA || !pClosePrinter)
1277 goto done;
1278
1279 len = sizeof(buffer);
1280 if (!pGetDefaultPrinterA( buffer, &len )) goto done;
1281 if (!pOpenPrinterA( buffer, &hprn, NULL )) goto done;
1282
1283 pGetPrinterA( hprn, 2, NULL, 0, &len );
1284 pbuf = HeapAlloc( GetProcessHeap(), 0, len );
1285 if (!pGetPrinterA( hprn, 2, (LPBYTE)pbuf, len, &len )) goto done;
1286
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;
1290
1291 pbuf->pDevMode->u1.s1.dmScale = scale;
1292 pbuf->pDevMode->dmFields |= DM_SCALE;
1293
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 " );
1298
1299 if (reset) ResetDCA( hdc, pbuf->pDevMode );
1300 done:
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" );
1306 return hdc;
1307 }
1308
1309 static void test_printer_dc(void)
1310 {
1311 HDC memdc, display_memdc, enhmf_dc;
1312 HBITMAP orig, bmp;
1313 DWORD ret;
1314 HDC hdc, hdc_200;
1315
1316 hdc = create_printer_dc(100, FALSE);
1317 hdc_200 = create_printer_dc(200, FALSE);
1318
1319 if (!hdc || !hdc_200) return;
1320
1321 test_device_caps( hdc, hdc_200, "printer dc", is_postscript_printer(hdc) ? 2 : 1 );
1322 DeleteDC( hdc_200 );
1323
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 );
1327
1328 memdc = CreateCompatibleDC( hdc );
1329 display_memdc = CreateCompatibleDC( 0 );
1330
1331 ok( memdc != NULL, "CreateCompatibleDC failed for printer\n" );
1332 ok( display_memdc != NULL, "CreateCompatibleDC failed for screen\n" );
1333
1334 ret = GetDeviceCaps( hdc, TECHNOLOGY );
1335 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1336
1337 ret = GetDeviceCaps( memdc, TECHNOLOGY );
1338 ok( ret == DT_RASPRINTER, "wrong type %u\n", ret );
1339
1340 ret = GetDeviceCaps( display_memdc, TECHNOLOGY );
1341 ok( ret == DT_RASDISPLAY, "wrong type %u\n", ret );
1342
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" );
1347
1348 test_device_caps( memdc, hdc, "printer dc", 1 );
1349
1350 ok( !SelectObject( display_memdc, bmp ), "SelectObject succeeded\n" );
1351 SelectObject( memdc, orig );
1352 DeleteObject( bmp );
1353
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" );
1361
1362 ret = GetPixel( hdc, 0, 0 );
1363 ok( ret == CLR_INVALID, "wrong pixel value %x\n", ret );
1364
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 ));
1369
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 ));
1374
1375 DeleteDC( memdc );
1376 DeleteDC( display_memdc );
1377 DeleteDC( hdc );
1378 DeleteObject( bmp );
1379 }
1380
1381 START_TEST(dc)
1382 {
1383 pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
1384 test_dc_values();
1385 test_savedc();
1386 test_savedc_2();
1387 test_GdiConvertToDevmodeW();
1388 test_CreateCompatibleDC();
1389 test_DC_bitmap();
1390 test_DeleteDC();
1391 test_boundsrect();
1392 test_desktop_colorres();
1393 test_gamma();
1394 test_printer_dc();
1395 }