user32: Fix the Dutch translation.
[wine] / dlls / user32 / tests / dce.c
1 /*
2  * Unit tests for DCE support
3  *
4  * Copyright 2005 Alexandre Julliard
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <assert.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24 #include <stdio.h>
25
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30
31 #include "wine/test.h"
32
33 #ifndef DCX_USESTYLE
34 #define DCX_USESTYLE         0x00010000
35 #endif
36
37 static HWND hwnd_cache, hwnd_owndc, hwnd_classdc, hwnd_classdc2;
38
39 /* test behavior of DC attributes with various GetDC/ReleaseDC combinations */
40 static void test_dc_attributes(void)
41 {
42     HDC hdc, old_hdc;
43     HDC hdcs[20];
44     INT i, rop, def_rop, found_dc;
45
46     /* test cache DC */
47
48     hdc = GetDC( hwnd_cache );
49     def_rop = GetROP2( hdc );
50
51     SetROP2( hdc, R2_WHITE );
52     rop = GetROP2( hdc );
53     ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop );
54
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;
62
63     found_dc = 0;
64     for (i = 0; i < 20; i++)
65     {
66         hdc = hdcs[i] = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS );
67         if (!hdc) break;
68         rop = GetROP2( hdc );
69         if (hdc == old_hdc)
70             todo_wine ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
71         else
72             ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
73         if (hdc == old_hdc)
74         {
75             found_dc = 1;
76             SetROP2( hdc, R2_WHITE );
77         }
78     }
79     if (!found_dc)
80     {
81         trace( "hdc %p not found in cache using %p\n", old_hdc, hdcs[0] );
82         old_hdc = hdcs[0];
83         SetROP2( old_hdc, R2_WHITE );
84     }
85     while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] );
86
87     for (i = 0; i < 20; i++)
88     {
89         hdc = hdcs[i] = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS );
90         if (!hdc) break;
91         rop = GetROP2( hdc );
92         if (hdc == old_hdc)
93             ok( rop == R2_WHITE || broken( rop == def_rop),  /* win9x doesn't support DCX_NORESETATTRS */
94                 "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
95         else
96             ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
97     }
98     while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] );
99
100     for (i = 0; i < 20; i++)
101     {
102         hdc = hdcs[i] = GetDCEx( hwnd_cache, 0, DCX_USESTYLE );
103         if (!hdc) break;
104         rop = GetROP2( hdc );
105         if (hdc == old_hdc)
106         {
107             todo_wine ok( rop == R2_WHITE || broken( rop == def_rop),
108                           "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
109             SetROP2( old_hdc, def_rop );
110         }
111         else
112             ok( rop == def_rop, "wrong ROP2 %d after release %p/%p\n", rop, old_hdc, hdc );
113     }
114     while (i >= 0) ReleaseDC( hwnd_cache, hdcs[--i] );
115
116     /* test own DC */
117
118     hdc = GetDC( hwnd_owndc );
119     SetROP2( hdc, R2_WHITE );
120     rop = GetROP2( hdc );
121     ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop );
122
123     old_hdc = hdc;
124     ReleaseDC( hwnd_owndc, hdc );
125     hdc = GetDC( hwnd_owndc );
126     ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc );
127     rop = GetROP2( hdc );
128     ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop );
129     ReleaseDC( hwnd_owndc, hdc );
130     rop = GetROP2( hdc );
131     ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop );
132
133     /* test class DC */
134
135     hdc = GetDC( hwnd_classdc );
136     SetROP2( hdc, R2_WHITE );
137     rop = GetROP2( hdc );
138     ok( rop == R2_WHITE, "wrong ROP2 %d\n", rop );
139
140     old_hdc = hdc;
141     ReleaseDC( hwnd_classdc, hdc );
142     hdc = GetDC( hwnd_classdc );
143     ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc );
144     rop = GetROP2( hdc );
145     ok( rop == R2_WHITE, "wrong ROP2 %d after release\n", rop );
146     ReleaseDC( hwnd_classdc, hdc );
147     rop = GetROP2( hdc );
148     ok( rop == R2_WHITE, "wrong ROP2 %d after second release\n", rop );
149
150     /* test class DC with 2 windows */
151
152     old_hdc = GetDC( hwnd_classdc );
153     SetROP2( old_hdc, R2_BLACK );
154     hdc = GetDC( hwnd_classdc2 );
155     ok( old_hdc == hdc, "didn't get same DC %p/%p\n", old_hdc, hdc );
156     rop = GetROP2( hdc );
157     ok( rop == R2_BLACK, "wrong ROP2 %d for other window\n", rop );
158     ReleaseDC( hwnd_classdc, old_hdc );
159     ReleaseDC( hwnd_classdc, hdc );
160     rop = GetROP2( hdc );
161     ok( rop == R2_BLACK, "wrong ROP2 %d after release\n", rop );
162 }
163
164
165 /* test behavior with various invalid parameters */
166 static void test_parameters(void)
167 {
168     HDC hdc;
169
170     hdc = GetDC( hwnd_cache );
171     ok( ReleaseDC( hwnd_owndc, hdc ), "ReleaseDC with wrong window should succeed\n" );
172
173     hdc = GetDC( hwnd_cache );
174     ok( !ReleaseDC( hwnd_cache, 0 ), "ReleaseDC with wrong HDC should fail\n" );
175     ok( ReleaseDC( hwnd_cache, hdc ), "correct ReleaseDC should succeed\n" );
176     ok( !ReleaseDC( hwnd_cache, hdc ), "second ReleaseDC should fail\n" );
177
178     hdc = GetDC( hwnd_owndc );
179     ok( ReleaseDC( hwnd_cache, hdc ), "ReleaseDC with wrong window should succeed\n" );
180     hdc = GetDC( hwnd_owndc );
181     ok( ReleaseDC( hwnd_owndc, hdc ), "correct ReleaseDC should succeed\n" );
182     ok( ReleaseDC( hwnd_owndc, hdc ), "second ReleaseDC should succeed\n" );
183
184     hdc = GetDC( hwnd_classdc );
185     ok( ReleaseDC( hwnd_cache, hdc ), "ReleaseDC with wrong window should succeed\n" );
186     hdc = GetDC( hwnd_classdc );
187     ok( ReleaseDC( hwnd_classdc, hdc ), "correct ReleaseDC should succeed\n" );
188     ok( ReleaseDC( hwnd_classdc, hdc ), "second ReleaseDC should succeed\n" );
189 }
190
191
192 static void test_dc_visrgn(void)
193 {
194     HDC old_hdc, hdc;
195     HRGN hrgn, hrgn2;
196     RECT rect;
197
198     /* cache DC */
199
200     SetRect( &rect, 10, 10, 20, 20 );
201     MapWindowPoints( hwnd_cache, 0, (POINT *)&rect, 2 );
202     hrgn = CreateRectRgnIndirect( &rect );
203     hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
204     SetRectEmpty( &rect );
205     GetClipBox( hdc, &rect );
206     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
207         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
208     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
209     ReleaseDC( hwnd_cache, hdc );
210     ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
211
212     /* cache DC with NORESETATTRS */
213
214     SetRect( &rect, 10, 10, 20, 20 );
215     MapWindowPoints( hwnd_cache, 0, (POINT *)&rect, 2 );
216     hrgn = CreateRectRgnIndirect( &rect );
217     hdc = GetDCEx( hwnd_cache, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE | DCX_NORESETATTRS );
218     SetRectEmpty( &rect );
219     GetClipBox( hdc, &rect );
220     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
221         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
222     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
223     ReleaseDC( hwnd_cache, hdc );
224     ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
225     hdc = GetDCEx( hwnd_cache, 0, DCX_USESTYLE | DCX_NORESETATTRS );
226     SetRectEmpty( &rect );
227     GetClipBox( hdc, &rect );
228     ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
229         "clip box sould have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
230     ReleaseDC( hwnd_cache, hdc );
231
232     /* window DC */
233
234     SetRect( &rect, 10, 10, 20, 20 );
235     MapWindowPoints( hwnd_owndc, 0, (POINT *)&rect, 2 );
236     hrgn = CreateRectRgnIndirect( &rect );
237     hdc = GetDCEx( hwnd_owndc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
238     SetRectEmpty( &rect );
239     GetClipBox( hdc, &rect );
240     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
241         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
242     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
243     ReleaseDC( hwnd_owndc, hdc );
244     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
245     SetRectEmpty( &rect );
246     GetClipBox( hdc, &rect );
247     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
248         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
249     hdc = GetDCEx( hwnd_owndc, 0, DCX_USESTYLE );
250     SetRectEmpty( &rect );
251     GetClipBox( hdc, &rect );
252     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
253         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
254     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
255     ReleaseDC( hwnd_owndc, hdc );
256     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
257
258     SetRect( &rect, 20, 20, 30, 30 );
259     MapWindowPoints( hwnd_owndc, 0, (POINT *)&rect, 2 );
260     hrgn2 = CreateRectRgnIndirect( &rect );
261     hdc = GetDCEx( hwnd_owndc, hrgn2, DCX_INTERSECTRGN | DCX_USESTYLE );
262     ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
263     SetRectEmpty( &rect );
264     GetClipBox( hdc, &rect );
265     ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30,
266         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
267     ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
268     ReleaseDC( hwnd_owndc, hdc );
269     ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
270     hdc = GetDCEx( hwnd_owndc, 0, DCX_EXCLUDERGN | DCX_USESTYLE );
271     ok( GetRgnBox( hrgn2, &rect ) == ERROR, "region must no longer be valid\n" );
272     SetRectEmpty( &rect );
273     GetClipBox( hdc, &rect );
274     ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30),
275         "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
276     ReleaseDC( hwnd_owndc, hdc );
277
278     /* class DC */
279
280     SetRect( &rect, 10, 10, 20, 20 );
281     MapWindowPoints( hwnd_classdc, 0, (POINT *)&rect, 2 );
282     hrgn = CreateRectRgnIndirect( &rect );
283     hdc = GetDCEx( hwnd_classdc, hrgn, DCX_INTERSECTRGN | DCX_USESTYLE );
284     SetRectEmpty( &rect );
285     GetClipBox( hdc, &rect );
286     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
287         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
288     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
289     ReleaseDC( hwnd_classdc, hdc );
290     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
291     SetRectEmpty( &rect );
292     GetClipBox( hdc, &rect );
293     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
294         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
295
296     hdc = GetDCEx( hwnd_classdc, 0, DCX_USESTYLE );
297     SetRectEmpty( &rect );
298     GetClipBox( hdc, &rect );
299     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
300         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
301     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
302     ReleaseDC( hwnd_classdc, hdc );
303     ok( GetRgnBox( hrgn, &rect ) != ERROR, "region must still be valid\n" );
304
305     SetRect( &rect, 20, 20, 30, 30 );
306     MapWindowPoints( hwnd_classdc, 0, (POINT *)&rect, 2 );
307     hrgn2 = CreateRectRgnIndirect( &rect );
308     hdc = GetDCEx( hwnd_classdc, hrgn2, DCX_INTERSECTRGN | DCX_USESTYLE );
309     ok( GetRgnBox( hrgn, &rect ) == ERROR, "region must no longer be valid\n" );
310     SetRectEmpty( &rect );
311     GetClipBox( hdc, &rect );
312     ok( rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30,
313         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
314     ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
315
316     old_hdc = hdc;
317     hdc = GetDCEx( hwnd_classdc2, 0, DCX_USESTYLE );
318     ok( old_hdc == hdc, "did not get the same hdc %p/%p\n", old_hdc, hdc );
319     ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
320     SetRectEmpty( &rect );
321     GetClipBox( hdc, &rect );
322     ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30),
323         "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
324     ReleaseDC( hwnd_classdc2, hdc );
325     ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
326     hdc = GetDCEx( hwnd_classdc2, 0, DCX_EXCLUDERGN | DCX_USESTYLE );
327     ok( GetRgnBox( hrgn2, &rect ) != ERROR, "region2 must still be valid\n" );
328     ok( !(rect.left >= 20 && rect.top >= 20 && rect.right <= 30 && rect.bottom <= 30),
329         "clip box must have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
330     ReleaseDC( hwnd_classdc2, hdc );
331 }
332
333
334 /* test various BeginPaint/EndPaint behaviors */
335 static void test_begin_paint(void)
336 {
337     HDC old_hdc, hdc;
338     RECT rect;
339     PAINTSTRUCT ps;
340
341     /* cache DC */
342
343     /* clear update region */
344     RedrawWindow( hwnd_cache, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
345     SetRect( &rect, 10, 10, 20, 20 );
346     RedrawWindow( hwnd_cache, &rect, 0, RDW_INVALIDATE );
347     hdc = BeginPaint( hwnd_cache, &ps );
348     SetRectEmpty( &rect );
349     GetClipBox( hdc, &rect );
350     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
351         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
352     EndPaint( hwnd_cache, &ps );
353
354     /* window DC */
355
356     RedrawWindow( hwnd_owndc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
357     SetRect( &rect, 10, 10, 20, 20 );
358     RedrawWindow( hwnd_owndc, &rect, 0, RDW_INVALIDATE );
359     hdc = BeginPaint( hwnd_owndc, &ps );
360     SetRectEmpty( &rect );
361     GetClipBox( hdc, &rect );
362     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
363         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
364     ReleaseDC( hwnd_owndc, hdc );
365     SetRectEmpty( &rect );
366     GetClipBox( hdc, &rect );
367     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
368         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
369     ok( GetDC( hwnd_owndc ) == hdc, "got different hdc\n" );
370     SetRectEmpty( &rect );
371     GetClipBox( hdc, &rect );
372     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
373         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
374     EndPaint( hwnd_owndc, &ps );
375     SetRectEmpty( &rect );
376     GetClipBox( hdc, &rect );
377     ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
378         "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
379     RedrawWindow( hwnd_owndc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
380     SetRect( &rect, 10, 10, 20, 20 );
381     RedrawWindow( hwnd_owndc, &rect, 0, RDW_INVALIDATE|RDW_ERASE );
382     ok( GetDC( hwnd_owndc ) == hdc, "got different hdc\n" );
383     SetRectEmpty( &rect );
384     GetClipBox( hdc, &rect );
385     ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
386         "clip box should be the whole window %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
387     RedrawWindow( hwnd_owndc, NULL, 0, RDW_ERASENOW );
388     SetRectEmpty( &rect );
389     GetClipBox( hdc, &rect );
390     ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
391         "clip box should still be the whole window %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
392
393     /* class DC */
394
395     RedrawWindow( hwnd_classdc, NULL, 0, RDW_VALIDATE|RDW_NOFRAME|RDW_NOERASE );
396     SetRect( &rect, 10, 10, 20, 20 );
397     RedrawWindow( hwnd_classdc, &rect, 0, RDW_INVALIDATE );
398     hdc = BeginPaint( hwnd_classdc, &ps );
399     SetRectEmpty( &rect );
400     GetClipBox( hdc, &rect );
401     ok( rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20,
402         "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
403
404     old_hdc = hdc;
405     hdc = GetDC( hwnd_classdc2 );
406     ok( old_hdc == hdc, "did not get the same hdc %p/%p\n", old_hdc, hdc );
407     SetRectEmpty( &rect );
408     GetClipBox( hdc, &rect );
409     ok( !(rect.left >= 10 && rect.top >= 10 && rect.right <= 20 && rect.bottom <= 20),
410         "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom );
411 }
412
413 static void test_invisible_create(void)
414 {
415     HWND hwnd_owndc = CreateWindowA("owndc_class", NULL, WS_OVERLAPPED,
416                                     0, 200, 100, 100,
417                                     0, 0, GetModuleHandleA(0), NULL );
418     HDC dc1, dc2;
419
420     dc1 = GetDC(hwnd_owndc);
421     dc2 = GetDC(hwnd_owndc);
422
423     ok(dc1 == dc2, "expected owndc dcs to match\n");
424
425     ReleaseDC(hwnd_owndc, dc2);
426     ReleaseDC(hwnd_owndc, dc1);
427     DestroyWindow(hwnd_owndc);
428 }
429
430 static void test_destroyed_window(void)
431 {
432     HDC dc;
433
434     dc = GetDCEx(hwnd_cache, 0, DCX_USESTYLE);
435     ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
436
437     dc = GetDCEx(hwnd_owndc, 0, DCX_USESTYLE);
438     ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
439
440     dc = GetDCEx(hwnd_classdc, 0, DCX_USESTYLE);
441     ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
442
443     dc = GetDCEx(hwnd_classdc2, 0, DCX_USESTYLE);
444     ok(!dc, "Got a non-NULL DC (%p) for a destroyed window.\n", dc);
445 }
446
447 START_TEST(dce)
448 {
449     WNDCLASSA cls;
450
451     cls.style = CS_DBLCLKS;
452     cls.lpfnWndProc = DefWindowProcA;
453     cls.cbClsExtra = 0;
454     cls.cbWndExtra = 0;
455     cls.hInstance = GetModuleHandleA(0);
456     cls.hIcon = 0;
457     cls.hCursor = LoadCursorA(0, IDC_ARROW);
458     cls.hbrBackground = GetStockObject(WHITE_BRUSH);
459     cls.lpszMenuName = NULL;
460     cls.lpszClassName = "cache_class";
461     RegisterClassA(&cls);
462     cls.style = CS_DBLCLKS | CS_OWNDC;
463     cls.lpszClassName = "owndc_class";
464     RegisterClassA(&cls);
465     cls.style = CS_DBLCLKS | CS_CLASSDC;
466     cls.lpszClassName = "classdc_class";
467     RegisterClassA(&cls);
468
469     hwnd_cache = CreateWindowA("cache_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
470                                0, 0, 100, 100,
471                                0, 0, GetModuleHandleA(0), NULL );
472     hwnd_owndc = CreateWindowA("owndc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
473                                0, 200, 100, 100,
474                                0, 0, GetModuleHandleA(0), NULL );
475     hwnd_classdc = CreateWindowA("classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
476                                  200, 0, 100, 100,
477                                  0, 0, GetModuleHandleA(0), NULL );
478     hwnd_classdc2 = CreateWindowA("classdc_class", NULL, WS_OVERLAPPED | WS_VISIBLE,
479                                   200, 200, 100, 100,
480                                   0, 0, GetModuleHandleA(0), NULL );
481     test_dc_attributes();
482     test_parameters();
483     test_dc_visrgn();
484     test_begin_paint();
485     test_invisible_create();
486
487     DestroyWindow(hwnd_classdc2);
488     DestroyWindow(hwnd_classdc);
489     DestroyWindow(hwnd_owndc);
490     DestroyWindow(hwnd_cache);
491
492     test_destroyed_window();
493 }