2 * Unit tests for dc functions
4 * Copyright (c) 2005 Huw Davies
5 * Copyright (c) 2005 Dmitry Timoshkov
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define WINVER 0x0501 /* request latest DEVMODE */
27 #include "wine/test.h"
33 static void dump_region(HRGN hrgn)
41 printf( "(null) region\n" );
44 if (!(size = GetRegionData( hrgn, 0, NULL ))) return;
45 if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
46 GetRegionData( hrgn, size, data );
47 printf( "%d rects:", data->rdh.nCount );
48 for (i = 0, rect = (RECT *)data->Buffer; i < data->rdh.nCount; i++, rect++)
49 printf( " (%d,%d)-(%d,%d)", rect->left, rect->top, rect->right, rect->bottom );
51 HeapFree( GetProcessHeap(), 0, data );
54 static void test_savedc_2(void)
62 hwnd = CreateWindowExA(0, "static", "", WS_POPUP, 0,0,100,100,
65 ShowWindow(hwnd, SW_SHOW);
68 hrgn = CreateRectRgn(0, 0, 0, 0);
72 ok(hdc != NULL, "GetDC failed\n");
74 ret = GetClipBox(hdc, &rc_clip);
75 ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
76 ret = GetClipRgn(hdc, hrgn);
77 ok(ret == 0, "GetClipRgn returned %d instead of 0\n", ret);
78 ret = GetRgnBox(hrgn, &rc);
79 ok(ret == NULLREGION, "GetRgnBox returned %d (%d,%d-%d,%d) instead of NULLREGION\n",
80 ret, rc.left, rc.top, rc.right, rc.bottom);
81 /*dump_region(hrgn);*/
82 SetRect(&rc, 0, 0, 100, 100);
83 ok(EqualRect(&rc, &rc_clip),
84 "rects are not equal: (%d,%d-%d,%d) - (%d,%d-%d,%d)\n",
85 rc.left, rc.top, rc.right, rc.bottom,
86 rc_clip.left, rc_clip.top, rc_clip.right, rc_clip.bottom);
91 ok(ret == 1, "ret = %d\n", ret);
94 ret = IntersectClipRect(hdc, 0, 0, 50, 50);
95 if (ret == COMPLEXREGION)
97 /* XP returns COMPLEXREGION although dump_region reports only 1 rect */
98 trace("Windows BUG: IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
99 /* let's make sure that it's a simple region */
100 ret = GetClipRgn(hdc, hrgn);
101 ok(ret == 1, "GetClipRgn returned %d instead of 1\n", ret);
105 ok(ret == SIMPLEREGION, "IntersectClipRect returned %d instead of SIMPLEREGION\n", ret);
107 ret = GetClipBox(hdc, &rc_clip);
108 ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
109 SetRect(&rc, 0, 0, 50, 50);
110 ok(EqualRect(&rc, &rc_clip), "rects are not equal\n");
112 ret = RestoreDC(hdc, 1);
113 ok(ret, "ret = %d\n", ret);
115 ret = GetClipBox(hdc, &rc_clip);
116 ok(ret == SIMPLEREGION, "GetClipBox returned %d instead of SIMPLEREGION\n", ret);
117 SetRect(&rc, 0, 0, 100, 100);
118 ok(EqualRect(&rc, &rc_clip), "rects are not equal\n");
121 ReleaseDC(hwnd, hdc);
125 static void test_savedc(void)
127 HDC hdc = CreateDCA("DISPLAY", NULL, NULL, NULL);
130 ok(hdc != NULL, "CreateDC rets %p\n", hdc);
133 ok(ret == 1, "ret = %d\n", ret);
135 ok(ret == 2, "ret = %d\n", ret);
137 ok(ret == 3, "ret = %d\n", ret);
138 ret = RestoreDC(hdc, -1);
139 ok(ret, "ret = %d\n", ret);
141 ok(ret == 3, "ret = %d\n", ret);
142 ret = RestoreDC(hdc, 1);
143 ok(ret, "ret = %d\n", ret);
145 ok(ret == 1, "ret = %d\n", ret);
147 ok(ret == 2, "ret = %d\n", ret);
149 ok(ret == 3, "ret = %d\n", ret);
150 ret = RestoreDC(hdc, -2);
151 ok(ret, "ret = %d\n", ret);
153 ok(ret == 2, "ret = %d\n", ret);
154 ret = RestoreDC(hdc, -2);
155 ok(ret, "ret = %d\n", ret);
157 ok(ret == 1, "ret = %d\n", ret);
159 ok(ret == 2, "ret = %d\n", ret);
160 ret = RestoreDC(hdc, -4);
161 ok(!ret, "ret = %d\n", ret);
162 ret = RestoreDC(hdc, 3);
163 ok(!ret, "ret = %d\n", ret);
165 /* Under win98 the following two succeed and both clear the save stack
166 ret = RestoreDC(hdc, -3);
167 ok(!ret, "ret = %d\n", ret);
168 ret = RestoreDC(hdc, 0);
169 ok(!ret, "ret = %d\n", ret);
172 ret = RestoreDC(hdc, 1);
173 ok(ret, "ret = %d\n", ret);
178 static void test_GdiConvertToDevmodeW(void)
180 DEVMODEW * (WINAPI *pGdiConvertToDevmodeW)(const DEVMODEA *);
185 pGdiConvertToDevmodeW = (void *)GetProcAddress(GetModuleHandleA("gdi32.dll"), "GdiConvertToDevmodeW");
186 if (!pGdiConvertToDevmodeW)
188 win_skip("GdiConvertToDevmodeW is not available on this platform\n");
192 ret = EnumDisplaySettingsA(NULL, ENUM_CURRENT_SETTINGS, &dmA);
193 ok(ret, "EnumDisplaySettingsExA error %u\n", GetLastError());
194 ok(dmA.dmSize >= FIELD_OFFSET(DEVMODEA, dmICMMethod), "dmSize is too small: %04x\n", dmA.dmSize);
195 ok(dmA.dmSize <= sizeof(DEVMODEA), "dmSize is too large: %04x\n", dmA.dmSize);
197 dmW = pGdiConvertToDevmodeW(&dmA);
198 ok(dmW->dmSize >= FIELD_OFFSET(DEVMODEW, dmICMMethod), "dmSize is too small: %04x\n", dmW->dmSize);
199 ok(dmW->dmSize <= sizeof(DEVMODEW), "dmSize is too large: %04x\n", dmW->dmSize);
200 HeapFree(GetProcessHeap(), 0, dmW);
202 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields) + sizeof(dmA.dmFields);
203 dmW = pGdiConvertToDevmodeW(&dmA);
204 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields) + sizeof(dmW->dmFields),
205 "wrong size %u\n", dmW->dmSize);
206 HeapFree(GetProcessHeap(), 0, dmW);
208 dmA.dmICMMethod = DMICMMETHOD_NONE;
209 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmICMMethod) + sizeof(dmA.dmICMMethod);
210 dmW = pGdiConvertToDevmodeW(&dmA);
211 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmICMMethod) + sizeof(dmW->dmICMMethod),
212 "wrong size %u\n", dmW->dmSize);
213 ok(dmW->dmICMMethod == DMICMMETHOD_NONE,
214 "expected DMICMMETHOD_NONE, got %u\n", dmW->dmICMMethod);
215 HeapFree(GetProcessHeap(), 0, dmW);
218 dmW = pGdiConvertToDevmodeW(&dmA);
219 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmPanningHeight) + sizeof(dmW->dmPanningHeight),
220 "wrong size %u\n", dmW->dmSize);
221 HeapFree(GetProcessHeap(), 0, dmW);
223 SetLastError(0xdeadbeef);
225 dmW = pGdiConvertToDevmodeW(&dmA);
226 ok(!dmW, "GdiConvertToDevmodeW should fail\n");
227 ok(GetLastError() == 0xdeadbeef, "expected 0xdeadbeef, got %u\n", GetLastError());
229 /* this is the minimal dmSize that XP accepts */
230 dmA.dmSize = FIELD_OFFSET(DEVMODEA, dmFields);
231 dmW = pGdiConvertToDevmodeW(&dmA);
232 ok(dmW->dmSize == FIELD_OFFSET(DEVMODEW, dmFields),
233 "expected %04x, got %04x\n", FIELD_OFFSET(DEVMODEW, dmFields), dmW->dmSize);
234 HeapFree(GetProcessHeap(), 0, dmW);
237 static void test_CreateCompatibleDC(void)
243 /* Create a DC compatible with the screen */
244 hDC = CreateCompatibleDC(NULL);
245 ok(hDC != NULL, "CreateCompatibleDC returned %p\n", hDC);
247 /* Delete this DC, this should succeed */
248 bRet = DeleteDC(hDC);
249 ok(bRet == TRUE, "DeleteDC returned %u\n", bRet);
251 /* Try to create a DC compatible to the deleted DC. This has to fail */
252 hNewDC = CreateCompatibleDC(hDC);
253 ok(hNewDC == NULL, "CreateCompatibleDC returned %p\n", hNewDC);
256 static void test_DC_bitmap(void)
260 HBITMAP hbmp, oldhbmp;
264 /* fill bitmap data with b&w pattern */
265 for( i = 0; i < 64; i++) bits[i] = i & 1 ? 0 : 0xffffff;
268 ok( hdc != NULL, "CreateDC rets %p\n", hdc);
269 bitspixel = GetDeviceCaps( hdc, BITSPIXEL);
270 /* create a memory dc */
271 hdcmem = CreateCompatibleDC( hdc);
272 ok( hdcmem != NULL, "CreateCompatibleDC rets %p\n", hdcmem);
274 /* test monochrome bitmap: should always work */
275 hbmp = CreateBitmap(32, 32, 1, 1, bits);
276 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
277 oldhbmp = SelectObject( hdcmem, hbmp);
278 ok( oldhbmp != NULL, "SelectObject returned NULL\n" ); /* a memdc always has a bitmap selected */
279 col = GetPixel( hdcmem, 0, 0);
280 ok( col == 0xffffff, "GetPixel returned %08x, expected 00ffffff\n", col);
281 col = GetPixel( hdcmem, 1, 1);
282 ok( col == 0x000000, "GetPixel returned %08x, expected 00000000\n", col);
283 col = GetPixel( hdcmem, 100, 1);
284 ok( col == CLR_INVALID, "GetPixel returned %08x, expected ffffffff\n", col);
285 SelectObject( hdcmem, oldhbmp);
288 /* test with 2 bits color depth, not likely to succeed */
289 hbmp = CreateBitmap(16, 16, 1, 2, bits);
290 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
291 oldhbmp = SelectObject( hdcmem, hbmp);
293 ok( !oldhbmp, "SelectObject of a bitmap with 2 bits/pixel should return NULL\n");
294 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
297 /* test with 16 bits color depth, might succeed */
298 hbmp = CreateBitmap(6, 6, 1, 16, bits);
299 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
300 oldhbmp = SelectObject( hdcmem, hbmp);
301 if( bitspixel == 16) {
302 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
303 col = GetPixel( hdcmem, 0, 0);
305 "GetPixel of a bitmap with 16 bits/pixel returned %08x, expected 00ffffff\n", col);
306 col = GetPixel( hdcmem, 1, 1);
308 "GetPixel of a bitmap with 16 bits/pixel returned returned %08x, expected 00000000\n", col);
310 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
313 /* test with 32 bits color depth, probably succeed */
314 hbmp = CreateBitmap(4, 4, 1, 32, bits);
315 ok( hbmp != NULL, "CreateBitmap returns %p\n", hbmp);
316 oldhbmp = SelectObject( hdcmem, hbmp);
317 if( bitspixel == 32) {
318 ok( oldhbmp != NULL, "SelectObject returned NULL\n" );
319 col = GetPixel( hdcmem, 0, 0);
321 "GetPixel of a bitmap with 32 bits/pixel returned %08x, expected 00ffffff\n", col);
322 col = GetPixel( hdcmem, 1, 1);
324 "GetPixel of a bitmap with 32 bits/pixel returned returned %08x, expected 00000000\n", col);
326 if( oldhbmp) SelectObject( hdcmem, oldhbmp);
331 static void test_DeleteDC(void)
339 hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
341 ok(hwnd != 0, "CreateWindowExA failed\n");
344 ok(hdc != 0, "GetDC failed\n");
345 ret = GetObjectType(hdc);
346 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
348 ok(ret, "DeleteDC failed\n");
349 ret = GetObjectType(hdc);
350 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
352 hdc = GetWindowDC(hwnd);
353 ok(hdc != 0, "GetDC failed\n");
354 ret = GetObjectType(hdc);
355 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
357 ok(ret, "DeleteDC failed\n");
358 ret = GetObjectType(hdc);
359 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
363 /* desktop window DC */
364 hwnd = GetDesktopWindow();
365 ok(hwnd != 0, "GetDesktopWindow failed\n");
368 ok(hdc != 0, "GetDC failed\n");
369 ret = GetObjectType(hdc);
370 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
372 ok(ret, "DeleteDC failed\n");
373 ret = GetObjectType(hdc);
374 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
376 hdc = GetWindowDC(hwnd);
377 ok(hdc != 0, "GetDC failed\n");
378 ret = GetObjectType(hdc);
379 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
381 ok(ret, "DeleteDC failed\n");
382 ret = GetObjectType(hdc);
383 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
386 memset(&cls, 0, sizeof(cls));
387 cls.cbSize = sizeof(cls);
388 cls.style = CS_CLASSDC;
389 cls.hInstance = GetModuleHandle(0);
390 cls.lpszClassName = "Wine class DC";
391 cls.lpfnWndProc = DefWindowProcA;
392 ret = RegisterClassExA(&cls);
393 ok(ret, "RegisterClassExA failed\n");
395 hwnd = CreateWindowExA(0, "Wine class DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
397 ok(hwnd != 0, "CreateWindowExA failed\n");
400 ok(hdc != 0, "GetDC failed\n");
401 ret = GetObjectType(hdc);
402 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
404 ok(ret, "DeleteDC failed\n");
405 ret = GetObjectType(hdc);
406 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
407 ret = ReleaseDC(hwnd, hdc);
408 ok(ret, "ReleaseDC failed\n");
409 ret = GetObjectType(hdc);
410 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
414 hdc = GetWindowDC(hwnd);
415 ok(hdc != 0, "GetDC failed\n");
416 ret = GetObjectType(hdc);
417 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
419 ok(ret, "DeleteDC failed\n");
420 ret = GetObjectType(hdc);
421 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
425 ret = GetObjectType(hdc_test);
426 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
428 ret = UnregisterClassA("Wine class DC", GetModuleHandle(NULL));
429 ok(ret, "UnregisterClassA failed\n");
431 ret = GetObjectType(hdc_test);
433 ok(!ret, "GetObjectType should fail for a deleted DC\n");
436 memset(&cls, 0, sizeof(cls));
437 cls.cbSize = sizeof(cls);
438 cls.style = CS_OWNDC;
439 cls.hInstance = GetModuleHandle(0);
440 cls.lpszClassName = "Wine own DC";
441 cls.lpfnWndProc = DefWindowProcA;
442 ret = RegisterClassExA(&cls);
443 ok(ret, "RegisterClassExA failed\n");
445 hwnd = CreateWindowExA(0, "Wine own DC", NULL, WS_POPUP|WS_VISIBLE, 0,0,100,100,
447 ok(hwnd != 0, "CreateWindowExA failed\n");
450 ok(hdc != 0, "GetDC failed\n");
451 ret = GetObjectType(hdc);
452 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
454 ok(ret, "DeleteDC failed\n");
455 ret = GetObjectType(hdc);
456 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
457 ret = ReleaseDC(hwnd, hdc);
458 ok(ret, "ReleaseDC failed\n");
459 ret = GetObjectType(hdc);
460 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
462 hdc = GetWindowDC(hwnd);
463 ok(hdc != 0, "GetDC failed\n");
464 ret = GetObjectType(hdc);
465 ok(ret == OBJ_DC, "expected OBJ_DC, got %d\n", ret);
467 ok(ret, "DeleteDC failed\n");
468 ret = GetObjectType(hdc);
469 ok(!ret || broken(ret) /* win9x */, "GetObjectType should fail for a deleted DC\n");
473 ret = UnregisterClassA("Wine own DC", GetModuleHandle(NULL));
474 ok(ret, "UnregisterClassA failed\n");
481 test_GdiConvertToDevmodeW();
482 test_CreateCompatibleDC();