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
30 #include "wine/test.h"
33 #define DCX_USESTYLE 0x00010000
36 static HWND hwnd_cache
, hwnd_owndc
, hwnd_classdc
, hwnd_classdc2
, hwnd_parent
, hwnd_parentdc
;
38 /* test behavior of DC attributes with various GetDC/ReleaseDC combinations */
39 static void test_dc_attributes(void)
48 hdc
= GetDC( hwnd_cache
);
49 def_rop
= GetROP2( hdc
);
51 SetROP2( hdc
, R2_WHITE
);
53 ok( rop
== R2_WHITE
, "wrong ROP2 %d\n", rop
);
55 ReleaseDC( hwnd_cache
, hdc
);
56 hdc
= GetDC( hwnd_cache
);
58 ok( rop
== def_rop
, "wrong ROP2 %d after release\n", rop
);
59 SetROP2( hdc
, R2_WHITE
);
60 ReleaseDC( hwnd_cache
, hdc
);
64 for (i
= 0; i
< 20; i
++)
66 hdc
= hdcs
[i
] = GetDCEx( hwnd_cache
, 0, DCX_USESTYLE
| DCX_NORESETATTRS
);
69 ok( rop
== def_rop
, "wrong ROP2 %d after release %p/%p\n", rop
, old_hdc
, hdc
);
73 SetROP2( hdc
, R2_WHITE
);
78 trace( "hdc %p not found in cache using %p\n", 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
);
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
);
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
);
101 rop
= GetROP2( 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
);
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 /* Released cache DCs are 'disabled' */
114 rop
= SetROP2( old_hdc
, R2_BLACK
);
115 ok( rop
== 0, "got %d\n", rop
);
116 rop
= GetROP2( old_hdc
);
117 ok( rop
== 0, "got %d\n", rop
);
121 hdc
= GetDC( hwnd_owndc
);
122 SetROP2( hdc
, R2_WHITE
);
123 rop
= GetROP2( hdc
);
124 ok( rop
== R2_WHITE
, "wrong ROP2 %d\n", rop
);
127 ReleaseDC( hwnd_owndc
, hdc
);
128 hdc
= GetDC( hwnd_owndc
);
129 ok( old_hdc
== hdc
, "didn't get same DC %p/%p\n", old_hdc
, hdc
);
130 rop
= GetROP2( hdc
);
131 ok( rop
== R2_WHITE
, "wrong ROP2 %d after release\n", rop
);
132 ReleaseDC( hwnd_owndc
, hdc
);
133 rop
= GetROP2( hdc
);
134 ok( rop
== R2_WHITE
, "wrong ROP2 %d after second release\n", rop
);
138 hdc
= GetDC( hwnd_classdc
);
139 SetROP2( hdc
, R2_WHITE
);
140 rop
= GetROP2( hdc
);
141 ok( rop
== R2_WHITE
, "wrong ROP2 %d\n", rop
);
144 ReleaseDC( hwnd_classdc
, hdc
);
145 hdc
= GetDC( hwnd_classdc
);
146 ok( old_hdc
== hdc
, "didn't get same DC %p/%p\n", old_hdc
, hdc
);
147 rop
= GetROP2( hdc
);
148 ok( rop
== R2_WHITE
, "wrong ROP2 %d after release\n", rop
);
149 ReleaseDC( hwnd_classdc
, hdc
);
150 rop
= GetROP2( hdc
);
151 ok( rop
== R2_WHITE
, "wrong ROP2 %d after second release\n", rop
);
153 /* test class DC with 2 windows */
155 old_hdc
= GetDC( hwnd_classdc
);
156 SetROP2( old_hdc
, R2_BLACK
);
157 hdc
= GetDC( hwnd_classdc2
);
158 ok( old_hdc
== hdc
, "didn't get same DC %p/%p\n", old_hdc
, hdc
);
159 rop
= GetROP2( hdc
);
160 ok( rop
== R2_BLACK
, "wrong ROP2 %d for other window\n", rop
);
161 ReleaseDC( hwnd_classdc
, old_hdc
);
162 ReleaseDC( hwnd_classdc
, hdc
);
163 rop
= GetROP2( hdc
);
164 ok( rop
== R2_BLACK
, "wrong ROP2 %d after release\n", rop
);
168 /* test behavior with various invalid parameters */
169 static void test_parameters(void)
173 hdc
= GetDC( hwnd_cache
);
174 ok( ReleaseDC( hwnd_owndc
, hdc
), "ReleaseDC with wrong window should succeed\n" );
176 hdc
= GetDC( hwnd_cache
);
177 ok( !ReleaseDC( hwnd_cache
, 0 ), "ReleaseDC with wrong HDC should fail\n" );
178 ok( ReleaseDC( hwnd_cache
, hdc
), "correct ReleaseDC should succeed\n" );
179 ok( !ReleaseDC( hwnd_cache
, hdc
), "second ReleaseDC should fail\n" );
181 hdc
= GetDC( hwnd_owndc
);
182 ok( ReleaseDC( hwnd_cache
, hdc
), "ReleaseDC with wrong window should succeed\n" );
183 hdc
= GetDC( hwnd_owndc
);
184 ok( ReleaseDC( hwnd_owndc
, hdc
), "correct ReleaseDC should succeed\n" );
185 ok( ReleaseDC( hwnd_owndc
, hdc
), "second ReleaseDC should succeed\n" );
187 hdc
= GetDC( hwnd_classdc
);
188 ok( ReleaseDC( hwnd_cache
, hdc
), "ReleaseDC with wrong window should succeed\n" );
189 hdc
= GetDC( hwnd_classdc
);
190 ok( ReleaseDC( hwnd_classdc
, hdc
), "correct ReleaseDC should succeed\n" );
191 ok( ReleaseDC( hwnd_classdc
, hdc
), "second ReleaseDC should succeed\n" );
195 static void test_dc_visrgn(void)
199 RECT rect
, parent_rect
;
203 SetRect( &rect
, 10, 10, 20, 20 );
204 MapWindowPoints( hwnd_cache
, 0, (POINT
*)&rect
, 2 );
205 hrgn
= CreateRectRgnIndirect( &rect
);
206 hdc
= GetDCEx( hwnd_cache
, hrgn
, DCX_INTERSECTRGN
| DCX_USESTYLE
);
207 SetRectEmpty( &rect
);
208 GetClipBox( hdc
, &rect
);
209 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
210 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
211 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
212 ReleaseDC( hwnd_cache
, hdc
);
213 ok( GetRgnBox( hrgn
, &rect
) == ERROR
, "region must no longer be valid\n" );
215 /* cache DC with NORESETATTRS */
217 SetRect( &rect
, 10, 10, 20, 20 );
218 MapWindowPoints( hwnd_cache
, 0, (POINT
*)&rect
, 2 );
219 hrgn
= CreateRectRgnIndirect( &rect
);
220 hdc
= GetDCEx( hwnd_cache
, hrgn
, DCX_INTERSECTRGN
| DCX_USESTYLE
| DCX_NORESETATTRS
);
221 SetRectEmpty( &rect
);
222 GetClipBox( hdc
, &rect
);
223 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
224 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
225 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
226 ReleaseDC( hwnd_cache
, hdc
);
227 ok( GetRgnBox( hrgn
, &rect
) == ERROR
, "region must no longer be valid\n" );
228 hdc
= GetDCEx( hwnd_cache
, 0, DCX_USESTYLE
| DCX_NORESETATTRS
);
229 SetRectEmpty( &rect
);
230 GetClipBox( hdc
, &rect
);
231 ok( !(rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20),
232 "clip box should have been reset %s\n", wine_dbgstr_rect( &rect
));
233 ReleaseDC( hwnd_cache
, hdc
);
237 SetRect( &rect
, 10, 10, 20, 20 );
238 MapWindowPoints( hwnd_owndc
, 0, (POINT
*)&rect
, 2 );
239 hrgn
= CreateRectRgnIndirect( &rect
);
240 hdc
= GetDCEx( hwnd_owndc
, hrgn
, DCX_INTERSECTRGN
| DCX_USESTYLE
);
241 SetRectEmpty( &rect
);
242 GetClipBox( hdc
, &rect
);
243 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
244 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
245 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
246 ReleaseDC( hwnd_owndc
, hdc
);
247 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
248 SetRectEmpty( &rect
);
249 GetClipBox( hdc
, &rect
);
250 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
251 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
252 hdc
= GetDCEx( hwnd_owndc
, 0, DCX_USESTYLE
);
253 SetRectEmpty( &rect
);
254 GetClipBox( hdc
, &rect
);
255 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
256 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
257 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
258 ReleaseDC( hwnd_owndc
, hdc
);
259 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
261 SetRect( &rect
, 20, 20, 30, 30 );
262 MapWindowPoints( hwnd_owndc
, 0, (POINT
*)&rect
, 2 );
263 hrgn2
= CreateRectRgnIndirect( &rect
);
264 hdc
= GetDCEx( hwnd_owndc
, hrgn2
, DCX_INTERSECTRGN
| DCX_USESTYLE
);
265 ok( GetRgnBox( hrgn
, &rect
) == ERROR
, "region must no longer be valid\n" );
266 SetRectEmpty( &rect
);
267 GetClipBox( hdc
, &rect
);
268 ok( rect
.left
>= 20 && rect
.top
>= 20 && rect
.right
<= 30 && rect
.bottom
<= 30,
269 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
270 ok( GetRgnBox( hrgn2
, &rect
) != ERROR
, "region2 must still be valid\n" );
271 ReleaseDC( hwnd_owndc
, hdc
);
272 ok( GetRgnBox( hrgn2
, &rect
) != ERROR
, "region2 must still be valid\n" );
273 hdc
= GetDCEx( hwnd_owndc
, 0, DCX_EXCLUDERGN
| DCX_USESTYLE
);
274 ok( GetRgnBox( hrgn2
, &rect
) == ERROR
, "region must no longer be valid\n" );
275 SetRectEmpty( &rect
);
276 GetClipBox( hdc
, &rect
);
277 ok( !(rect
.left
>= 20 && rect
.top
>= 20 && rect
.right
<= 30 && rect
.bottom
<= 30),
278 "clip box should have been reset %s\n", wine_dbgstr_rect( &rect
));
279 ReleaseDC( hwnd_owndc
, hdc
);
283 SetRect( &rect
, 10, 10, 20, 20 );
284 MapWindowPoints( hwnd_classdc
, 0, (POINT
*)&rect
, 2 );
285 hrgn
= CreateRectRgnIndirect( &rect
);
286 hdc
= GetDCEx( hwnd_classdc
, hrgn
, DCX_INTERSECTRGN
| DCX_USESTYLE
);
287 SetRectEmpty( &rect
);
288 GetClipBox( hdc
, &rect
);
289 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
290 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
291 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
292 ReleaseDC( hwnd_classdc
, hdc
);
293 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
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 %s\n", wine_dbgstr_rect( &rect
));
299 hdc
= GetDCEx( hwnd_classdc
, 0, DCX_USESTYLE
);
300 SetRectEmpty( &rect
);
301 GetClipBox( hdc
, &rect
);
302 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
303 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
304 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
305 ReleaseDC( hwnd_classdc
, hdc
);
306 ok( GetRgnBox( hrgn
, &rect
) != ERROR
, "region must still be valid\n" );
308 SetRect( &rect
, 20, 20, 30, 30 );
309 MapWindowPoints( hwnd_classdc
, 0, (POINT
*)&rect
, 2 );
310 hrgn2
= CreateRectRgnIndirect( &rect
);
311 hdc
= GetDCEx( hwnd_classdc
, hrgn2
, DCX_INTERSECTRGN
| DCX_USESTYLE
);
312 ok( GetRgnBox( hrgn
, &rect
) == ERROR
, "region must no longer be valid\n" );
313 SetRectEmpty( &rect
);
314 GetClipBox( hdc
, &rect
);
315 ok( rect
.left
>= 20 && rect
.top
>= 20 && rect
.right
<= 30 && rect
.bottom
<= 30,
316 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
317 ok( GetRgnBox( hrgn2
, &rect
) != ERROR
, "region2 must still be valid\n" );
320 hdc
= GetDCEx( hwnd_classdc2
, 0, DCX_USESTYLE
);
321 ok( old_hdc
== hdc
, "did not get the same hdc %p/%p\n", old_hdc
, hdc
);
322 ok( GetRgnBox( hrgn2
, &rect
) != ERROR
, "region2 must still be valid\n" );
323 SetRectEmpty( &rect
);
324 GetClipBox( hdc
, &rect
);
325 ok( !(rect
.left
>= 20 && rect
.top
>= 20 && rect
.right
<= 30 && rect
.bottom
<= 30),
326 "clip box should have been reset %s\n", wine_dbgstr_rect( &rect
));
327 ReleaseDC( hwnd_classdc2
, hdc
);
328 ok( GetRgnBox( hrgn2
, &rect
) != ERROR
, "region2 must still be valid\n" );
329 hdc
= GetDCEx( hwnd_classdc2
, 0, DCX_EXCLUDERGN
| DCX_USESTYLE
);
330 ok( GetRgnBox( hrgn2
, &rect
) != ERROR
, "region2 must still be valid\n" );
331 ok( !(rect
.left
>= 20 && rect
.top
>= 20 && rect
.right
<= 30 && rect
.bottom
<= 30),
332 "clip box must have been reset %s\n", wine_dbgstr_rect( &rect
));
333 ReleaseDC( hwnd_classdc2
, hdc
);
336 hdc
= GetDC( hwnd_parentdc
);
337 GetClipBox( hdc
, &rect
);
338 ReleaseDC( hwnd_parentdc
, hdc
);
340 hdc
= GetDC( hwnd_parent
);
341 GetClipBox( hdc
, &parent_rect
);
342 ReleaseDC( hwnd_parent
, hdc
);
344 ok( EqualRect( &rect
, &parent_rect
), "rect = %s, expected %s\n", wine_dbgstr_rect( &rect
),
345 wine_dbgstr_rect( &parent_rect
));
349 /* test various BeginPaint/EndPaint behaviors */
350 static void test_begin_paint(void)
353 RECT rect
, parent_rect
;
359 /* clear update region */
360 RedrawWindow( hwnd_cache
, NULL
, 0, RDW_VALIDATE
|RDW_NOFRAME
|RDW_NOERASE
);
361 SetRect( &rect
, 10, 10, 20, 20 );
362 RedrawWindow( hwnd_cache
, &rect
, 0, RDW_INVALIDATE
);
363 hdc
= BeginPaint( hwnd_cache
, &ps
);
364 SetRectEmpty( &rect
);
365 GetClipBox( hdc
, &rect
);
366 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
367 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
368 EndPaint( hwnd_cache
, &ps
);
372 RedrawWindow( hwnd_owndc
, NULL
, 0, RDW_VALIDATE
|RDW_NOFRAME
|RDW_NOERASE
);
373 SetRect( &rect
, 10, 10, 20, 20 );
374 RedrawWindow( hwnd_owndc
, &rect
, 0, RDW_INVALIDATE
);
375 hdc
= BeginPaint( hwnd_owndc
, &ps
);
376 SetRectEmpty( &rect
);
377 GetClipBox( hdc
, &rect
);
378 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
379 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
380 ReleaseDC( hwnd_owndc
, hdc
);
381 SetRectEmpty( &rect
);
382 GetClipBox( hdc
, &rect
);
383 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
384 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
385 ok( GetDC( hwnd_owndc
) == hdc
, "got different hdc\n" );
386 SetRectEmpty( &rect
);
387 GetClipBox( hdc
, &rect
);
388 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
389 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
390 EndPaint( hwnd_owndc
, &ps
);
391 SetRectEmpty( &rect
);
392 GetClipBox( hdc
, &rect
);
393 ok( !(rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20),
394 "clip box should have been reset %s\n", wine_dbgstr_rect( &rect
));
395 RedrawWindow( hwnd_owndc
, NULL
, 0, RDW_VALIDATE
|RDW_NOFRAME
|RDW_NOERASE
);
396 SetRect( &rect
, 10, 10, 20, 20 );
397 RedrawWindow( hwnd_owndc
, &rect
, 0, RDW_INVALIDATE
|RDW_ERASE
);
398 ok( GetDC( hwnd_owndc
) == hdc
, "got different hdc\n" );
399 SetRectEmpty( &rect
);
400 GetClipBox( hdc
, &rect
);
401 ok( !(rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20),
402 "clip box should be the whole window %s\n", wine_dbgstr_rect( &rect
));
403 RedrawWindow( hwnd_owndc
, NULL
, 0, RDW_ERASENOW
);
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 still be the whole window %s\n", wine_dbgstr_rect( &rect
));
411 RedrawWindow( hwnd_classdc
, NULL
, 0, RDW_VALIDATE
|RDW_NOFRAME
|RDW_NOERASE
);
412 SetRect( &rect
, 10, 10, 20, 20 );
413 RedrawWindow( hwnd_classdc
, &rect
, 0, RDW_INVALIDATE
);
414 hdc
= BeginPaint( hwnd_classdc
, &ps
);
415 SetRectEmpty( &rect
);
416 GetClipBox( hdc
, &rect
);
417 ok( rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20,
418 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
421 hdc
= GetDC( hwnd_classdc2
);
422 ok( old_hdc
== hdc
, "did not get the same hdc %p/%p\n", old_hdc
, hdc
);
423 SetRectEmpty( &rect
);
424 GetClipBox( hdc
, &rect
);
425 ok( !(rect
.left
>= 10 && rect
.top
>= 10 && rect
.right
<= 20 && rect
.bottom
<= 20),
426 "clip box should have been reset %s\n", wine_dbgstr_rect( &rect
));
427 ReleaseDC( hwnd_classdc2
, hdc
);
428 EndPaint( hwnd_classdc
, &ps
);
431 RedrawWindow( hwnd_parent
, NULL
, 0, RDW_VALIDATE
|RDW_NOFRAME
|RDW_NOERASE
);
432 RedrawWindow( hwnd_parentdc
, NULL
, 0, RDW_INVALIDATE
);
433 hdc
= BeginPaint( hwnd_parentdc
, &ps
);
434 GetClipBox( hdc
, &rect
);
435 cr
= SetPixel( hdc
, 10, 10, RGB(255, 0, 0) );
436 ok( cr
!= -1, "error drawing outside of window client area\n" );
437 EndPaint( hwnd_parentdc
, &ps
);
438 GetClientRect( hwnd_parent
, &parent_rect
);
440 ok( rect
.left
== parent_rect
.left
, "rect.left = %d, expected %d\n", rect
.left
, parent_rect
.left
);
441 ok( rect
.top
== parent_rect
.top
, "rect.top = %d, expected %d\n", rect
.top
, parent_rect
.top
);
442 todo_wine
ok( rect
.right
== parent_rect
.right
, "rect.right = %d, expected %d\n", rect
.right
, parent_rect
.right
);
443 todo_wine
ok( rect
.bottom
== parent_rect
.bottom
, "rect.bottom = %d, expected %d\n", rect
.bottom
, parent_rect
.bottom
);
445 hdc
= GetDC( hwnd_parent
);
446 todo_wine
ok( GetPixel( hdc
, 10, 10 ) == cr
, "error drawing outside of window client area\n" );
447 ReleaseDC( hwnd_parent
, hdc
);
450 /* test ScrollWindow with window DCs */
451 static void test_scroll_window(void)
457 /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */
459 UpdateWindow( hwnd_owndc
);
460 SetRect( &clip
, 25, 25, 50, 50 );
461 ScrollWindow( hwnd_owndc
, -5, -10, NULL
, &clip
);
462 hdc
= BeginPaint( hwnd_owndc
, &ps
);
463 SetRectEmpty( &rect
);
464 GetClipBox( hdc
, &rect
);
465 ok( rect
.left
>= 25 && rect
.top
>= 25 && rect
.right
<= 50 && rect
.bottom
<= 50,
466 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
467 EndPaint( hwnd_owndc
, &ps
);
469 SetViewportExtEx( hdc
, 2, 3, NULL
);
470 SetViewportOrgEx( hdc
, 30, 20, NULL
);
472 ScrollWindow( hwnd_owndc
, -5, -10, NULL
, &clip
);
473 hdc
= BeginPaint( hwnd_owndc
, &ps
);
474 SetRectEmpty( &rect
);
475 GetClipBox( hdc
, &rect
);
476 ok( rect
.left
>= 25 && rect
.top
>= 25 && rect
.right
<= 50 && rect
.bottom
<= 50,
477 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
478 EndPaint( hwnd_owndc
, &ps
);
480 ScrollWindowEx( hwnd_owndc
, -5, -10, NULL
, &clip
, 0, NULL
, SW_INVALIDATE
| SW_ERASE
);
481 hdc
= BeginPaint( hwnd_owndc
, &ps
);
482 SetRectEmpty( &rect
);
483 GetClipBox( hdc
, &rect
);
484 ok( rect
.left
>= -5 && rect
.top
>= 5 && rect
.right
<= 20 && rect
.bottom
<= 30,
485 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
486 EndPaint( hwnd_owndc
, &ps
);
488 SetViewportExtEx( hdc
, 1, 1, NULL
);
489 SetViewportOrgEx( hdc
, 0, 0, NULL
);
491 ScrollWindowEx( hwnd_owndc
, -5, -10, NULL
, &clip
, 0, NULL
, SW_INVALIDATE
| SW_ERASE
);
492 hdc
= BeginPaint( hwnd_owndc
, &ps
);
493 SetRectEmpty( &rect
);
494 GetClipBox( hdc
, &rect
);
495 ok( rect
.left
>= 25 && rect
.top
>= 25 && rect
.right
<= 50 && rect
.bottom
<= 50,
496 "invalid clip box %s\n", wine_dbgstr_rect( &rect
));
497 EndPaint( hwnd_owndc
, &ps
);
500 static void test_invisible_create(void)
502 HWND hwnd_owndc
= CreateWindowA("owndc_class", NULL
, WS_OVERLAPPED
,
504 0, 0, GetModuleHandleA(0), NULL
);
507 dc1
= GetDC(hwnd_owndc
);
508 dc2
= GetDC(hwnd_owndc
);
510 ok(dc1
== dc2
, "expected owndc dcs to match\n");
512 ReleaseDC(hwnd_owndc
, dc2
);
513 ReleaseDC(hwnd_owndc
, dc1
);
514 DestroyWindow(hwnd_owndc
);
517 static void test_dc_layout(void)
519 DWORD (WINAPI
*pSetLayout
)(HDC hdc
, DWORD layout
);
520 DWORD (WINAPI
*pGetLayout
)(HDC hdc
);
521 HWND hwnd_cache_rtl
, hwnd_owndc_rtl
, hwnd_classdc_rtl
, hwnd_classdc2_rtl
;
524 HMODULE mod
= GetModuleHandleA("gdi32.dll");
526 pGetLayout
= (void *)GetProcAddress( mod
, "GetLayout" );
527 pSetLayout
= (void *)GetProcAddress( mod
, "SetLayout" );
528 if (!pGetLayout
|| !pSetLayout
)
530 win_skip( "Don't have SetLayout\n" );
534 hdc
= GetDC( hwnd_cache
);
535 pSetLayout( hdc
, LAYOUT_RTL
);
536 layout
= pGetLayout( hdc
);
537 ReleaseDC( hwnd_cache
, hdc
);
540 win_skip( "SetLayout not supported\n" );
544 hwnd_cache_rtl
= CreateWindowExA(WS_EX_LAYOUTRTL
, "cache_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
545 0, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL
);
546 hwnd_owndc_rtl
= CreateWindowExA(WS_EX_LAYOUTRTL
, "owndc_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
547 0, 200, 100, 100, 0, 0, GetModuleHandleA(0), NULL
);
548 hwnd_classdc_rtl
= CreateWindowExA(WS_EX_LAYOUTRTL
, "classdc_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
549 200, 0, 100, 100, 0, 0, GetModuleHandleA(0), NULL
);
550 hwnd_classdc2_rtl
= CreateWindowExA(WS_EX_LAYOUTRTL
, "classdc_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
551 200, 200, 100, 100, 0, 0, GetModuleHandleA(0), NULL
);
552 hdc
= GetDC( hwnd_cache_rtl
);
553 layout
= pGetLayout( hdc
);
555 ok( layout
== LAYOUT_RTL
, "wrong layout %x\n", layout
);
556 pSetLayout( hdc
, 0 );
557 ReleaseDC( hwnd_cache_rtl
, hdc
);
558 hdc
= GetDC( hwnd_owndc_rtl
);
559 layout
= pGetLayout( hdc
);
560 ok( layout
== LAYOUT_RTL
, "wrong layout %x\n", layout
);
561 ReleaseDC( hwnd_cache_rtl
, hdc
);
563 hdc
= GetDC( hwnd_cache
);
564 layout
= pGetLayout( hdc
);
565 ok( layout
== 0, "wrong layout %x\n", layout
);
566 ReleaseDC( hwnd_cache
, hdc
);
568 hdc
= GetDC( hwnd_owndc_rtl
);
569 layout
= pGetLayout( hdc
);
570 ok( layout
== LAYOUT_RTL
, "wrong layout %x\n", layout
);
571 pSetLayout( hdc
, 0 );
572 ReleaseDC( hwnd_owndc_rtl
, hdc
);
573 hdc
= GetDC( hwnd_owndc_rtl
);
574 layout
= pGetLayout( hdc
);
575 ok( layout
== LAYOUT_RTL
, "wrong layout %x\n", layout
);
576 ReleaseDC( hwnd_owndc_rtl
, hdc
);
578 hdc
= GetDC( hwnd_classdc_rtl
);
579 layout
= pGetLayout( hdc
);
580 ok( layout
== LAYOUT_RTL
, "wrong layout %x\n", layout
);
581 pSetLayout( hdc
, 0 );
582 ReleaseDC( hwnd_classdc_rtl
, hdc
);
583 hdc
= GetDC( hwnd_classdc2_rtl
);
584 layout
= pGetLayout( hdc
);
585 ok( layout
== LAYOUT_RTL
, "wrong layout %x\n", layout
);
586 ReleaseDC( hwnd_classdc2_rtl
, hdc
);
587 hdc
= GetDC( hwnd_classdc
);
588 layout
= pGetLayout( hdc
);
589 ok( layout
== LAYOUT_RTL
, "wrong layout %x\n", layout
);
590 ReleaseDC( hwnd_classdc_rtl
, hdc
);
592 DestroyWindow(hwnd_classdc2_rtl
);
593 DestroyWindow(hwnd_classdc_rtl
);
594 DestroyWindow(hwnd_owndc_rtl
);
595 DestroyWindow(hwnd_cache_rtl
);
598 static void test_destroyed_window(void)
602 dc
= GetDCEx(hwnd_cache
, 0, DCX_USESTYLE
);
603 ok(!dc
, "Got a non-NULL DC (%p) for a destroyed window.\n", dc
);
605 dc
= GetDCEx(hwnd_owndc
, 0, DCX_USESTYLE
);
606 ok(!dc
, "Got a non-NULL DC (%p) for a destroyed window.\n", dc
);
608 dc
= GetDCEx(hwnd_classdc
, 0, DCX_USESTYLE
);
609 ok(!dc
, "Got a non-NULL DC (%p) for a destroyed window.\n", dc
);
611 dc
= GetDCEx(hwnd_classdc2
, 0, DCX_USESTYLE
);
612 ok(!dc
, "Got a non-NULL DC (%p) for a destroyed window.\n", dc
);
619 cls
.style
= CS_DBLCLKS
;
620 cls
.lpfnWndProc
= DefWindowProcA
;
623 cls
.hInstance
= GetModuleHandleA(0);
625 cls
.hCursor
= LoadCursorA(0, (LPCSTR
)IDC_ARROW
);
626 cls
.hbrBackground
= GetStockObject(WHITE_BRUSH
);
627 cls
.lpszMenuName
= NULL
;
628 cls
.lpszClassName
= "cache_class";
629 RegisterClassA(&cls
);
630 cls
.style
= CS_DBLCLKS
| CS_OWNDC
;
631 cls
.lpszClassName
= "owndc_class";
632 RegisterClassA(&cls
);
633 cls
.style
= CS_DBLCLKS
| CS_CLASSDC
;
634 cls
.lpszClassName
= "classdc_class";
635 RegisterClassA(&cls
);
636 cls
.style
= CS_PARENTDC
;
637 cls
.lpszClassName
= "parentdc_class";
638 RegisterClassA(&cls
);
640 hwnd_cache
= CreateWindowA("cache_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
642 0, 0, GetModuleHandleA(0), NULL
);
643 hwnd_owndc
= CreateWindowA("owndc_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
645 0, 0, GetModuleHandleA(0), NULL
);
646 hwnd_classdc
= CreateWindowA("classdc_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
648 0, 0, GetModuleHandleA(0), NULL
);
649 hwnd_classdc2
= CreateWindowA("classdc_class", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
651 0, 0, GetModuleHandleA(0), NULL
);
652 hwnd_parent
= CreateWindowA("static", NULL
, WS_OVERLAPPED
| WS_VISIBLE
,
653 400, 0, 100, 100, 0, 0, 0, NULL
);
654 hwnd_parentdc
= CreateWindowA("parentdc_class", NULL
, WS_CHILD
| WS_VISIBLE
,
655 0, 0, 1, 1, hwnd_parent
, 0, 0, NULL
);
657 test_dc_attributes();
661 test_scroll_window();
662 test_invisible_create();
665 DestroyWindow(hwnd_parent
);
666 DestroyWindow(hwnd_classdc2
);
667 DestroyWindow(hwnd_classdc
);
668 DestroyWindow(hwnd_owndc
);
669 DestroyWindow(hwnd_cache
);
671 test_destroyed_window();