user32/tests: Ignore paint messages in hotkey tests.
[wine/multimedia.git] / dlls / user32 / tests / dce.c
blobf077fcb886dc7a1eb3a4ffb50bb069e983d97877
1 /*
2 * Unit tests for DCE support
4 * Copyright 2005 Alexandre Julliard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <assert.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <stdio.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
31 #include "wine/test.h"
33 #ifndef DCX_USESTYLE
34 #define DCX_USESTYLE 0x00010000
35 #endif
37 static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2;
39 /* test behavior of DC attributes with various GetDC/ReleaseDC combinations */
40 static void test_dc_attributes(void)
42 HDC hdc, old_hdc;
43 HDC hdcs[20];
44 INT i, rop, def_rop, found_dc;
46 /* test cache DC */
48 hdc = GetDC( hwnd_cache );
49 def_rop = GetROP2( hdc );
51 SetROP2( hdc, R2_WHITE );
52 rop = GetROP2( hdc );
53 ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop );
55 ReleaseDC( hwnd_cache, hdc );
56 hdc = GetDC( hwnd_cache );
57 rop = GetROP2( hdc );
58 ok( rop == def_rop, "wrong ROP2 %d after release\n", rop );
59 SetROP2( hdc, R2_WHITE );
60 ReleaseDC( hwnd_cache, hdc );
61 old_hdc = hdc;
63 found_dc = 0;
64 for (i = 0; i < 20; i++)
66 hdc = hdcs[i] = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS );
67 if (!hdc) break;
68 rop = GetROP2( hdc );
69 ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
70 if (hdc == old_hdc)
72 found_dc = 1;
73 SetROP2( hdc, R2_WHITE );
76 if (!found_dc)
78 trace( "hdc %p not found in cache using %p\n", old_hdc, hdcs[0] );
79 old_hdc = hdcs[0];
80 SetROP2( old_hdc, R2_WHITE );
82 while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] );
84 for (i = 0; i < 20; i++)
86 hdc = hdcs[i] = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS );
87 if (!hdc) break;
88 rop = GetROP2( hdc );
89 if (hdc == old_hdc)
90 ok( rop == R2_WHITE || broken( rop == def_rop), /* win9x doesn't support DCX_NORESETATTRS */
91 "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
92 else
93 ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
95 while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] );
97 for (i = 0; i < 20; i++)
99 hdc = hdcs[i] = GetDCEx( hwnd_cache, 0, DCX_USESTYLE );
100 if (!hdc) break;
101 rop = GetROP2( hdc );
102 if (hdc == old_hdc)
104 ok( rop == R2_WHITE || broken( rop == def_rop),
105 "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
106 SetROP2( old_hdc, def_rop );
108 else
109 ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
111 while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] );
113 /* test own DC */
115 hdc = GetDC( hwnd_owndc );
116 SetROP2( hdc, R2_WHITE );
117 rop = GetROP2( hdc );
118 ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop );
120 old_hdc = hdc;
121 ReleaseDC( hwnd_owndc, hdc );
122 hdc = GetDC( hwnd_owndc );
123 ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc );
124 rop = GetROP2( hdc );
125 ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop );
126 ReleaseDC( hwnd_owndc, hdc );
127 rop = GetROP2( hdc );
128 ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop );
130 /* test class DC */
132 hdc = GetDC( hwnd_classdc );
133 SetROP2( hdc, R2_WHITE );
134 rop = GetROP2( hdc );
135 ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop );
137 old_hdc = hdc;
138 ReleaseDC( hwnd_classdc, hdc );
139 hdc = GetDC( hwnd_classdc );
140 ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc );
141 rop = GetROP2( hdc );
142 ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop );
143 ReleaseDC( hwnd_classdc, hdc );
144 rop = GetROP2( hdc );
145 ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop );
147 /* test class DC with 2 windows */
149 old_hdc = GetDC( hwnd_classdc );
150 SetROP2( old_hdc, R2_BLACK );
151 hdc = GetDC( hwnd_classdc2 );
152 ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc );
153 rop = GetROP2( hdc );
154 ok( rop == R2_BLACK, "wrong ROP2 %d for other window\n", rop );
155 ReleaseDC( hwnd_classdc, old_hdc );
156 ReleaseDC( hwnd_classdc, hdc );
157 rop = GetROP2( hdc );
158 ok( rop == R2_BLACK, "wrong ROP2 %d after release\n", rop );
162 /* test behavior with various invalid parameters */
163 static void test_parameters(void)
165 HDC hdc;
167 hdc = GetDC( hwnd_cache );
168 ok( ReleaseDC( hwnd_owndc, hdc ), "ReleaseDC with wrong window should succeed\n" );
170 hdc = GetDC( hwnd_cache );
171 ok( !ReleaseDC( hwnd_cache, 0 ), "ReleaseDC with wrong HDC should fail\n" );
172 ok( ReleaseDC( hwnd_cache, hdc ), "correct ReleaseDC should succeed\n" );
173 ok( !ReleaseDC( hwnd_cache, hdc ), "second ReleaseDC should fail\n" );
175 hdc = GetDC( hwnd_owndc );
176 ok( ReleaseDC( hwnd_cache, hdc ), "ReleaseDC with wrong window should succeed\n" );
177 hdc = GetDC( hwnd_owndc );
178 ok( ReleaseDC( hwnd_owndc, hdc ), "correct ReleaseDC should succeed\n" );
179 ok( ReleaseDC( hwnd_owndc, hdc ), "second ReleaseDC should succeed\n" );
181 hdc = GetDC( hwnd_classdc );
182 ok( ReleaseDC( hwnd_cache, hdc ), "ReleaseDC with wrong window should succeed\n" );
183 hdc = GetDC( hwnd_classdc );
184 ok( ReleaseDC( hwnd_classdc, hdc ), "correct ReleaseDC should succeed\n" );
185 ok( ReleaseDC( hwnd_classdc, hdc ), "second ReleaseDC should succeed\n" );
189 static void test_dc_visrgn(void)
191 HDC old_hdc, hdc;
192 HRGN hrgn, hrgn2;
193 RECT rect;
195 /* cache DC */
197 SetRect( &rect, 10, 10, 20, 20 );
198 MapWindowPoints( hwnd_cache, 0, (POINT *)&rect, 2 );
199 hrgn = CreateRectRgnIndirect( &rect );
200 hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
201 SetRectEmpty( &rect );
202 GetClipBox( hdc, &rect );
203 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
204 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
205 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
206 ReleaseDC( hwnd_cache, hdc );
207 ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
209 /* cache DC with NORESETATTRS */
211 SetRect( &rect, 10, 10, 20, 20 );
212 MapWindowPoints( hwnd_cache, 0, (POINT *)&rect, 2 );
213 hrgn = CreateRectRgnIndirect( &rect );
214 hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE | DCX_NORESETATTRS );
215 SetRectEmpty( &rect );
216 GetClipBox( hdc, &rect );
217 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
218 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
219 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
220 ReleaseDC( hwnd_cache, hdc );
221 ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
222 hdc = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS );
223 SetRectEmpty( &rect );
224 GetClipBox( hdc, &rect );
225 ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
226 "clip box sould have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
227 ReleaseDC( hwnd_cache, hdc );
229 /* window DC */
231 SetRect( &rect, 10, 10, 20, 20 );
232 MapWindowPoints( hwnd_owndc, 0, (POINT *)&rect, 2 );
233 hrgn = CreateRectRgnIndirect( &rect );
234 hdc = GetDCEx( hwnd_owndc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
235 SetRectEmpty( &rect );
236 GetClipBox( hdc, &rect );
237 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
238 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
239 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
240 ReleaseDC( hwnd_owndc, hdc );
241 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
242 SetRectEmpty( &rect );
243 GetClipBox( hdc, &rect );
244 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
245 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
246 hdc = GetDCEx( hwnd_owndc, 0, DCX_USESTYLE );
247 SetRectEmpty( &rect );
248 GetClipBox( hdc, &rect );
249 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
250 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
251 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
252 ReleaseDC( hwnd_owndc, hdc );
253 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
255 SetRect( &rect, 20, 20, 30, 30 );
256 MapWindowPoints( hwnd_owndc, 0, (POINT *)&rect, 2 );
257 hrgn2 = CreateRectRgnIndirect( &rect );
258 hdc = GetDCEx( hwnd_owndc, hrgn2, DCX_INTERSECTRGN | DCX_USESTYLE );
259 ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
260 SetRectEmpty( &rect );
261 GetClipBox( hdc, &rect );
262 ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30,
263 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
264 ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
265 ReleaseDC( hwnd_owndc, hdc );
266 ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
267 hdc = GetDCEx( hwnd_owndc, 0, DCX_EXCLUDERGN | DCX_USESTYLE );
268 ok( GetRgnBox( hrgn2, &rect ) == ERROR, "region must no longer be valid\n" );
269 SetRectEmpty( &rect );
270 GetClipBox( hdc, &rect );
271 ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30),
272 "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
273 ReleaseDC( hwnd_owndc, hdc );
275 /* class DC */
277 SetRect( &rect, 10, 10, 20, 20 );
278 MapWindowPoints( hwnd_classdc, 0, (POINT *)&rect, 2 );
279 hrgn = CreateRectRgnIndirect( &rect );
280 hdc = GetDCEx( hwnd_classdc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
281 SetRectEmpty( &rect );
282 GetClipBox( hdc, &rect );
283 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
284 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
285 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
286 ReleaseDC( hwnd_classdc, hdc );
287 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
288 SetRectEmpty( &rect );
289 GetClipBox( hdc, &rect );
290 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
291 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
293 hdc = GetDCEx( hwnd_classdc, 0, DCX_USESTYLE );
294 SetRectEmpty( &rect );
295 GetClipBox( hdc, &rect );
296 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
297 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
298 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
299 ReleaseDC( hwnd_classdc, hdc );
300 ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
302 SetRect( &rect, 20, 20, 30, 30 );
303 MapWindowPoints( hwnd_classdc, 0, (POINT *)&rect, 2 );
304 hrgn2 = CreateRectRgnIndirect( &rect );
305 hdc = GetDCEx( hwnd_classdc, hrgn2, DCX_INTERSECTRGN | DCX_USESTYLE );
306 ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
307 SetRectEmpty( &rect );
308 GetClipBox( hdc, &rect );
309 ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30,
310 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
311 ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
313 old_hdc = hdc;
314 hdc = GetDCEx( hwnd_classdc2, 0, DCX_USESTYLE );
315 ok( old_hdc == hdc, "did not get the same hdc %p/%p\n", old_hdc, hdc );
316 ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
317 SetRectEmpty( &rect );
318 GetClipBox( hdc, &rect );
319 ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30),
320 "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
321 ReleaseDC( hwnd_classdc2, hdc );
322 ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
323 hdc = GetDCEx( hwnd_classdc2, 0, DCX_EXCLUDERGN | DCX_USESTYLE );
324 ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
325 ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30),
326 "clip box must have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
327 ReleaseDC( hwnd_classdc2, hdc );
331 /* test various BeginPaint/EndPaint behaviors */
332 static void test_begin_paint(void)
334 HDC old_hdc, hdc;
335 RECT rect;
336 PAINTSTRUCT ps;
338 /* cache DC */
340 /* clear update region */
341 RedrawWindow( hwnd_cache, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
342 SetRect( &rect, 10, 10, 20, 20 );
343 RedrawWindow( hwnd_cache, &rect, 0, RDW_INVALIDATE );
344 hdc = BeginPaint( hwnd_cache, &ps );
345 SetRectEmpty( &rect );
346 GetClipBox( hdc, &rect );
347 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
348 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
349 EndPaint( hwnd_cache, &ps );
351 /* window DC */
353 RedrawWindow( hwnd_owndc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
354 SetRect( &rect, 10, 10, 20, 20 );
355 RedrawWindow( hwnd_owndc, &rect, 0, RDW_INVALIDATE );
356 hdc = BeginPaint( hwnd_owndc, &ps );
357 SetRectEmpty( &rect );
358 GetClipBox( hdc, &rect );
359 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
360 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
361 ReleaseDC( hwnd_owndc, hdc );
362 SetRectEmpty( &rect );
363 GetClipBox( hdc, &rect );
364 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
365 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
366 ok( GetDC( hwnd_owndc ) == hdc, "got different hdc\n" );
367 SetRectEmpty( &rect );
368 GetClipBox( hdc, &rect );
369 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
370 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
371 EndPaint( hwnd_owndc, &ps );
372 SetRectEmpty( &rect );
373 GetClipBox( hdc, &rect );
374 ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
375 "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
376 RedrawWindow( hwnd_owndc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
377 SetRect( &rect, 10, 10, 20, 20 );
378 RedrawWindow( hwnd_owndc, &rect, 0, RDW_INVALIDATE|RDW_ERASE );
379 ok( GetDC( hwnd_owndc ) == hdc, "got different hdc\n" );
380 SetRectEmpty( &rect );
381 GetClipBox( hdc, &rect );
382 ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
383 "clip box should be the whole window %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
384 RedrawWindow( hwnd_owndc, NULL, 0, RDW_ERASENOW );
385 SetRectEmpty( &rect );
386 GetClipBox( hdc, &rect );
387 ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
388 "clip box should still be the whole window %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
390 /* class DC */
392 RedrawWindow( hwnd_classdc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
393 SetRect( &rect, 10, 10, 20, 20 );
394 RedrawWindow( hwnd_classdc, &rect, 0, RDW_INVALIDATE );
395 hdc = BeginPaint( hwnd_classdc, &ps );
396 SetRectEmpty( &rect );
397 GetClipBox( hdc, &rect );
398 ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
399 "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
401 old_hdc = hdc;
402 hdc = GetDC( hwnd_classdc2 );
403 ok( old_hdc == hdc, "did not get the same hdc %p/%p\n", old_hdc, hdc );
404 SetRectEmpty( &rect );
405 GetClipBox( hdc, &rect );
406 ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
407 "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
410 static void test_invisible_create(void)
412 HWND hwnd_owndc = CreateWindowA("owndc_class", NULL, WS_OVERLAPPED,
413 0, 200, 100, 100,
414 0, 0, GetModuleHandleA(0), NULL );
415 HDC dc1, dc2;
417 dc1 = GetDC(hwnd_owndc);
418 dc2 = GetDC(hwnd_owndc);
420 ok(dc1 == dc2, "expected owndc dcs to match\n");
422 ReleaseDC(hwnd_owndc, dc2);
423 ReleaseDC(hwnd_owndc, dc1);
424 DestroyWindow(hwnd_owndc);
427 static void test_dc_layout(void)
429 DWORD (WINAPI *pSetLayout)(HDC hdc, DWORD layout);
430 DWORD (WINAPI *pGetLayout)(HDC hdc);
431 HWND hwnd_cache_rtl, hwnd_owndc_rtl, hwnd_classdc_rtl, hwnd_classdc2_rtl;
432 HDC hdc;
433 DWORD layout;
434 HMODULE mod = GetModuleHandleA("gdi32.dll");
436 pGetLayout = (void *)GetProcAddress( mod, "GetLayout" );
437 pSetLayout = (void *)GetProcAddress( mod, "SetLayout" );
438 if (!pGetLayout || !pSetLayout)
440 win_skip( "Don't have SetLayout\n" );
441 return;
444 hdc = GetDC( hwnd_cache );
445 pSetLayout( hdc, LAYOUT_RTL );
446 layout = pGetLayout( hdc );
447 ReleaseDC( hwnd_cache, hdc );
448 if (!layout)
450 win_skip( "SetLayout not supported\n" );
451 return;
454 hwnd_cache_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "cache_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
455 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
456 hwnd_owndc_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "owndc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
457 0, 200, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
458 hwnd_classdc_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
459 200, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
460 hwnd_classdc2_rtl = CreateWindowExA(WS_EX_LAYOUTRTL, "classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
461 200, 200, 100, 100, 0, 0, GetModuleHandleA(0), NULL );
462 hdc = GetDC( hwnd_cache_rtl );
463 layout = pGetLayout( hdc );
465 ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
466 pSetLayout( hdc, 0 );
467 ReleaseDC( hwnd_cache_rtl, hdc );
468 hdc = GetDC( hwnd_owndc_rtl );
469 layout = pGetLayout( hdc );
470 ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
471 ReleaseDC( hwnd_cache_rtl, hdc );
473 hdc = GetDC( hwnd_cache );
474 layout = pGetLayout( hdc );
475 ok( layout == 0, "wrong layout %x\n", layout );
476 ReleaseDC( hwnd_cache, hdc );
478 hdc = GetDC( hwnd_owndc_rtl );
479 layout = pGetLayout( hdc );
480 ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
481 pSetLayout( hdc, 0 );
482 ReleaseDC( hwnd_owndc_rtl, hdc );
483 hdc = GetDC( hwnd_owndc_rtl );
484 layout = pGetLayout( hdc );
485 ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
486 ReleaseDC( hwnd_owndc_rtl, hdc );
488 hdc = GetDC( hwnd_classdc_rtl );
489 layout = pGetLayout( hdc );
490 ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
491 pSetLayout( hdc, 0 );
492 ReleaseDC( hwnd_classdc_rtl, hdc );
493 hdc = GetDC( hwnd_classdc2_rtl );
494 layout = pGetLayout( hdc );
495 ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
496 ReleaseDC( hwnd_classdc2_rtl, hdc );
497 hdc = GetDC( hwnd_classdc );
498 layout = pGetLayout( hdc );
499 ok( layout == LAYOUT_RTL, "wrong layout %x\n", layout );
500 ReleaseDC( hwnd_classdc_rtl, hdc );
502 DestroyWindow(hwnd_classdc2_rtl);
503 DestroyWindow(hwnd_classdc_rtl);
504 DestroyWindow(hwnd_owndc_rtl);
505 DestroyWindow(hwnd_cache_rtl);
508 static void test_destroyed_window(void)
510 HDC dc;
512 dc = GetDCEx(hwnd_cache, 0, DCX_USESTYLE);
513 ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
515 dc = GetDCEx(hwnd_owndc, 0, DCX_USESTYLE);
516 ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
518 dc = GetDCEx(hwnd_classdc, 0, DCX_USESTYLE);
519 ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
521 dc = GetDCEx(hwnd_classdc2, 0, DCX_USESTYLE);
522 ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
525 START_TEST(dce)
527 WNDCLASSA cls;
529 cls.style = CS_DBLCLKS;
530 cls.lpfnWndProc = DefWindowProcA;
531 cls.cbClsExtra = 0;
532 cls.cbWndExtra = 0;
533 cls.hInstance = GetModuleHandleA(0);
534 cls.hIcon = 0;
535 cls.hCursor = LoadCursorA(0, IDC_ARROW);
536 cls.hbrBackground = GetStockObject(WHITE_BRUSH);
537 cls.lpszMenuName = NULL;
538 cls.lpszClassName = "cache_class";
539 RegisterClassA(&cls);
540 cls.style = CS_DBLCLKS | CS_OWNDC;
541 cls.lpszClassName = "owndc_class";
542 RegisterClassA(&cls);
543 cls.style = CS_DBLCLKS | CS_CLASSDC;
544 cls.lpszClassName = "classdc_class";
545 RegisterClassA(&cls);
547 hwnd_cache = CreateWindowA("cache_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
548 0, 0, 100, 100,
549 0, 0, GetModuleHandleA(0), NULL );
550 hwnd_owndc = CreateWindowA("owndc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
551 0, 200, 100, 100,
552 0, 0, GetModuleHandleA(0), NULL );
553 hwnd_classdc = CreateWindowA("classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
554 200, 0, 100, 100,
555 0, 0, GetModuleHandleA(0), NULL );
556 hwnd_classdc2 = CreateWindowA("classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
557 200, 200, 100, 100,
558 0, 0, GetModuleHandleA(0), NULL );
559 test_dc_attributes();
560 test_parameters();
561 test_dc_visrgn();
562 test_begin_paint();
563 test_invisible_create();
564 test_dc_layout();
566 DestroyWindow(hwnd_classdc2);
567 DestroyWindow(hwnd_classdc);
568 DestroyWindow(hwnd_owndc);
569 DestroyWindow(hwnd_cache);
571 test_destroyed_window();