4 * Copyright 1993 Alexandre Julliard
8 * Note: Visible regions of CS_OWNDC/CS_CLASSDC window DCs
9 * have to be updated dynamically.
13 * DCX_DCEBUSY - dce structure is in use
14 * DCX_KEEPCLIPRGN - do not delete clipping region in ReleaseDC
15 * DCX_WINDOWPAINT - BeginPaint specific flag
23 #include "sysmetrics.h"
25 /* #define DEBUG_DC */
28 #define NB_DCE 5 /* Number of DCEs created at startup */
30 static DCE
*firstDCE
= 0;
31 static HDC32 defaultDCstate
= 0;
33 /***********************************************************************
38 DCE
*DCE_AllocDCE( HWND32 hWnd
, DCE_TYPE type
)
41 if (!(dce
= HeapAlloc( SystemHeap
, 0, sizeof(DCE
) ))) return NULL
;
42 if (!(dce
->hDC
= CreateDC16( "DISPLAY", NULL
, NULL
, NULL
)))
44 HeapFree( SystemHeap
, 0, dce
);
48 /* store DCE handle in DC hook data field */
50 SetDCHook( dce
->hDC
, (FARPROC16
)DCHook
, (DWORD
)dce
);
52 dce
->hwndCurrent
= hWnd
;
57 if( type
!= DCE_CACHE_DC
)
59 dce
->DCXflags
= DCX_DCEBUSY
;
62 WND
* wnd
= WIN_FindWndPtr(hWnd
);
64 if( wnd
->dwStyle
& WS_CLIPCHILDREN
) dce
->DCXflags
|= DCX_CLIPCHILDREN
;
65 if( wnd
->dwStyle
& WS_CLIPSIBLINGS
) dce
->DCXflags
|= DCX_CLIPSIBLINGS
;
67 SetHookFlags(dce
->hDC
,DCHF_INVALIDATEVISRGN
);
69 else dce
->DCXflags
= DCX_CACHE
;
75 /***********************************************************************
78 void DCE_FreeDCE( DCE
*dce
)
80 DCE
**ppDCE
= &firstDCE
;
83 while (*ppDCE
&& (*ppDCE
!= dce
)) ppDCE
= &(*ppDCE
)->next
;
84 if (*ppDCE
== dce
) *ppDCE
= dce
->next
;
86 SetDCHook(dce
->hDC
, NULL
, 0L);
88 DeleteDC32( dce
->hDC
);
89 if( dce
->hClipRgn
&& !(dce
->DCXflags
& DCX_KEEPCLIPRGN
) )
90 DeleteObject32(dce
->hClipRgn
);
91 HeapFree( SystemHeap
, 0, dce
);
95 /**********************************************************************
96 * WindowFromDC16 (USER32.580)
98 HWND16
WindowFromDC16( HDC16 hDC
)
100 return (HWND16
)WindowFromDC32( hDC
);
104 /**********************************************************************
105 * WindowFromDC32 (USER32.580)
107 HWND32
WindowFromDC32( HDC32 hDC
)
110 while (dce
&& (dce
->hDC
!= hDC
)) dce
= dce
->next
;
111 return dce
? dce
->hwndCurrent
: 0;
115 /***********************************************************************
118 * It is called from SetWindowPos - we have to invalidate all busy
119 * DCE's for windows whose client rect intersects with update rectangle
121 BOOL32
DCE_InvalidateDCE(WND
* wndScope
, RECT32
* pRectUpdate
)
126 if( !wndScope
) return 0;
128 dprintf_dc(stddeb
,"InvalidateDCE: scope hwnd = %04x, (%i,%i - %i,%i)\n",
129 wndScope
->hwndSelf
, pRectUpdate
->left
,pRectUpdate
->top
,
130 pRectUpdate
->right
,pRectUpdate
->bottom
);
133 for (dce
= firstDCE
; (dce
); dce
= dce
->next
)
135 if( dce
->DCXflags
& DCX_DCEBUSY
)
137 WND
* wndCurrent
, * wnd
;
139 wnd
= wndCurrent
= WIN_FindWndPtr(dce
->hwndCurrent
);
141 /* desktop is not critical (DC is not owned anyway) */
143 if( wnd
== WIN_GetDesktop() ) continue;
145 /* check if DCE window is within z-order scope */
147 for( ; wnd
; wnd
= wnd
->parent
)
148 if( wnd
== wndScope
)
150 RECT32 wndRect
= wndCurrent
->rectWindow
;
152 dprintf_dc(stddeb
,"\tgot hwnd %04x\n", wndCurrent
->hwndSelf
);
154 MapWindowPoints32( wndCurrent
->parent
->hwndSelf
,
156 (LPPOINT32
)&wndRect
, 2 );
157 if (IntersectRect32( &wndRect
, &wndRect
, pRectUpdate
))
159 SetHookFlags(dce
->hDC
, DCHF_INVALIDATEVISRGN
);
169 /***********************************************************************
177 for (i
= 0; i
< NB_DCE
; i
++)
179 if (!(dce
= DCE_AllocDCE( 0, DCE_CACHE_DC
))) return;
180 if (!defaultDCstate
) defaultDCstate
= GetDCState( dce
->hDC
);
185 /***********************************************************************
188 * Calc the visible rectangle of a window, i.e. the client or
189 * window area clipped by the client area of all ancestors.
190 * Return FALSE if the visible region is empty.
192 static BOOL32
DCE_GetVisRect( WND
*wndPtr
, BOOL32 clientArea
, RECT32
*lprect
)
194 int xoffset
, yoffset
;
196 *lprect
= clientArea
? wndPtr
->rectClient
: wndPtr
->rectWindow
;
197 xoffset
= lprect
->left
;
198 yoffset
= lprect
->top
;
200 if (!(wndPtr
->dwStyle
& WS_VISIBLE
) || (wndPtr
->flags
& WIN_NO_REDRAW
))
202 SetRectEmpty32( lprect
); /* Clip everything */
206 while (wndPtr
->parent
)
208 wndPtr
= wndPtr
->parent
;
209 if (!(wndPtr
->dwStyle
& WS_VISIBLE
) ||
210 (wndPtr
->flags
& WIN_NO_REDRAW
) ||
211 (wndPtr
->dwStyle
& WS_ICONIC
))
213 SetRectEmpty32( lprect
); /* Clip everything */
216 xoffset
+= wndPtr
->rectClient
.left
;
217 yoffset
+= wndPtr
->rectClient
.top
;
218 OffsetRect32( lprect
, wndPtr
->rectClient
.left
,
219 wndPtr
->rectClient
.top
);
221 /* Warning!! we assume that IntersectRect() handles the case */
222 /* where the destination is the same as one of the sources. */
223 if (!IntersectRect32( lprect
, lprect
, &wndPtr
->rectClient
))
224 return FALSE
; /* Visible rectangle is empty */
226 OffsetRect32( lprect
, -xoffset
, -yoffset
);
231 /***********************************************************************
234 * Go through the linked list of windows from hwndStart to hwndEnd,
235 * removing from the given region the rectangle of each window offset
236 * by a given amount. The new region is returned, and the original one
237 * is destroyed. Used to implement DCX_CLIPSIBLINGS and
238 * DCX_CLIPCHILDREN styles. Now it skips managed windows
239 * because we have no idea about decoration size anyway.
241 static HRGN32
DCE_ClipWindows( WND
*pWndStart
, WND
*pWndEnd
,
242 HRGN32 hrgn
, int xoffset
, int yoffset
)
246 if ( pWndStart
== NULL
) return hrgn
;
247 if ( (hrgnNew
= CreateRectRgn32( 0, 0, 0, 0 )) )
249 for (; pWndStart
!= pWndEnd
; pWndStart
= pWndStart
->next
)
251 if ( !(pWndStart
->dwStyle
& WS_VISIBLE
) ||
252 (pWndStart
->flags
& WIN_MANAGED
) ) continue;
254 SetRectRgn32( hrgnNew
, pWndStart
->rectWindow
.left
+ xoffset
,
255 pWndStart
->rectWindow
.top
+ yoffset
,
256 pWndStart
->rectWindow
.right
+ xoffset
,
257 pWndStart
->rectWindow
.bottom
+ yoffset
);
258 if (!CombineRgn32( hrgn
, hrgn
, hrgnNew
, RGN_DIFF
)) break;
260 DeleteObject32( hrgnNew
);
261 } else pWndEnd
= NULL
;
263 if (pWndStart
!= pWndEnd
) /* something went wrong */
265 DeleteObject32( hrgn
);
272 /***********************************************************************
275 * Return the visible region of a window, i.e. the client or window area
276 * clipped by the client area of all ancestors, and then optionally
277 * by siblings and children.
279 HRGN32
DCE_GetVisRgn( HWND32 hwnd
, WORD flags
)
283 int xoffset
, yoffset
;
284 WND
*wndPtr
= WIN_FindWndPtr( hwnd
);
286 /* Get visible rectangle and create a region with it.
289 if (!wndPtr
|| !DCE_GetVisRect( wndPtr
, !(flags
& DCX_WINDOW
), &rect
))
291 return CreateRectRgn32( 0, 0, 0, 0 ); /* Visible region is empty */
293 if (!(hrgn
= CreateRectRgnIndirect32( &rect
))) return 0;
295 /* Clip all children from the visible region */
297 if (flags
& DCX_CLIPCHILDREN
)
299 if (flags
& DCX_WINDOW
)
301 xoffset
= wndPtr
->rectClient
.left
- wndPtr
->rectWindow
.left
;
302 yoffset
= wndPtr
->rectClient
.top
- wndPtr
->rectWindow
.top
;
304 else xoffset
= yoffset
= 0;
305 hrgn
= DCE_ClipWindows( wndPtr
->child
, NULL
, hrgn
, xoffset
, yoffset
);
309 /* Clip siblings placed above this window */
311 if (flags
& DCX_WINDOW
)
313 xoffset
= -wndPtr
->rectWindow
.left
;
314 yoffset
= -wndPtr
->rectWindow
.top
;
318 xoffset
= -wndPtr
->rectClient
.left
;
319 yoffset
= -wndPtr
->rectClient
.top
;
321 if (flags
& DCX_CLIPSIBLINGS
)
323 hrgn
= DCE_ClipWindows( wndPtr
->parent
? wndPtr
->parent
->child
: NULL
,
324 wndPtr
, hrgn
, xoffset
, yoffset
);
328 /* Clip siblings of all ancestors that have the WS_CLIPSIBLINGS style */
330 while (wndPtr
->dwStyle
& WS_CHILD
)
332 wndPtr
= wndPtr
->parent
;
333 xoffset
-= wndPtr
->rectClient
.left
;
334 yoffset
-= wndPtr
->rectClient
.top
;
335 hrgn
= DCE_ClipWindows( wndPtr
->parent
? wndPtr
->parent
->child
: NULL
,
336 wndPtr
, hrgn
, xoffset
, yoffset
);
343 /***********************************************************************
346 * Set the drawable, origin and dimensions for the DC associated to
349 static void DCE_SetDrawable( WND
*wndPtr
, DC
*dc
, WORD flags
)
351 if (!wndPtr
) /* Get a DC for the whole screen */
355 dc
->u
.x
.drawable
= rootWindow
;
356 XSetSubwindowMode( display
, dc
->u
.x
.gc
, IncludeInferiors
);
360 if (flags
& DCX_WINDOW
)
362 dc
->w
.DCOrgX
= wndPtr
->rectWindow
.left
;
363 dc
->w
.DCOrgY
= wndPtr
->rectWindow
.top
;
367 dc
->w
.DCOrgX
= wndPtr
->rectClient
.left
;
368 dc
->w
.DCOrgY
= wndPtr
->rectClient
.top
;
370 while (!wndPtr
->window
)
372 wndPtr
= wndPtr
->parent
;
373 dc
->w
.DCOrgX
+= wndPtr
->rectClient
.left
;
374 dc
->w
.DCOrgY
+= wndPtr
->rectClient
.top
;
376 dc
->w
.DCOrgX
-= wndPtr
->rectWindow
.left
;
377 dc
->w
.DCOrgY
-= wndPtr
->rectWindow
.top
;
378 dc
->u
.x
.drawable
= wndPtr
->window
;
381 /***********************************************************************
384 * Translate given region from the wnd client to the DC coordinates
385 * and add it to the clipping region.
387 INT16
DCE_ExcludeRgn( HDC32 hDC
, WND
* wnd
, HRGN32 hRgn
)
391 HRGN32 hRgnClip
= GetClipRgn16( hDC
);
394 while (dce
&& (dce
->hDC
!= hDC
)) dce
= dce
->next
;
397 MapWindowPoints32( wnd
->hwndSelf
, dce
->hwndCurrent
, &pt
, 1);
398 if( dce
->DCXflags
& DCX_WINDOW
)
400 wnd
= WIN_FindWndPtr(dce
->hwndCurrent
);
401 pt
.x
+= wnd
->rectClient
.left
- wnd
->rectWindow
.left
;
402 pt
.y
+= wnd
->rectClient
.top
- wnd
->rectWindow
.top
;
406 OffsetRgn32(hRgn
, pt
.x
, pt
.y
);
407 if( hRgnClip
) ret
= CombineRgn32( hRgnClip
, hRgnClip
, hRgn
, RGN_DIFF
);
410 hRgnClip
= InquireVisRgn( hDC
);
411 ret
= CombineRgn32( hRgn
, hRgnClip
, hRgn
, RGN_DIFF
);
412 SelectClipRgn32( hDC
, hRgn
);
417 /***********************************************************************
418 * GetDCEx16 (USER.359)
420 HDC16
GetDCEx16( HWND16 hwnd
, HRGN16 hrgnClip
, DWORD flags
)
422 return (HDC16
)GetDCEx32( hwnd
, hrgnClip
, flags
);
426 /***********************************************************************
427 * GetDCEx32 (USER32.230)
429 * Unimplemented flags: DCX_LOCKWINDOWUPDATE
431 HDC32
GetDCEx32( HWND32 hwnd
, HRGN32 hrgnClip
, DWORD flags
)
439 BOOL32 need_update
= TRUE
;
441 dprintf_dc(stddeb
,"GetDCEx: hwnd %04x, hrgnClip %04x, flags %08x\n", hwnd
, hrgnClip
, (unsigned)flags
);
443 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
445 if (!(wndPtr
->class->style
& (CS_OWNDC
| CS_CLASSDC
))) flags
|= DCX_CACHE
;
447 if (flags
& DCX_USESTYLE
)
449 flags
&= ~( DCX_CLIPCHILDREN
| DCX_CLIPSIBLINGS
| DCX_PARENTCLIP
);
451 if( wndPtr
->dwStyle
& WS_CLIPSIBLINGS
)
452 flags
|= DCX_CLIPSIBLINGS
;
454 if ( !(flags
& DCX_WINDOW
) )
456 if (wndPtr
->class->style
& CS_PARENTDC
) flags
|= DCX_PARENTCLIP
;
458 if (wndPtr
->dwStyle
& WS_CLIPCHILDREN
&&
459 !(wndPtr
->dwStyle
& WS_MINIMIZE
) ) flags
|= DCX_CLIPCHILDREN
;
461 else flags
|= DCX_CACHE
;
464 if( flags
& DCX_NOCLIPCHILDREN
)
467 flags
&= ~(DCX_PARENTCLIP
| DCX_CLIPCHILDREN
);
470 if (flags
& DCX_WINDOW
) flags
= (flags
& ~DCX_CLIPCHILDREN
) | DCX_CACHE
;
472 if (!(wndPtr
->dwStyle
& WS_CHILD
) || !wndPtr
->parent
) flags
&= ~DCX_PARENTCLIP
;
473 else if( flags
& DCX_PARENTCLIP
)
476 if( !(flags
& (DCX_CLIPSIBLINGS
| DCX_CLIPCHILDREN
)) )
477 if( (wndPtr
->dwStyle
& WS_VISIBLE
) && (wndPtr
->parent
->dwStyle
& WS_VISIBLE
) )
479 flags
&= ~DCX_CLIPCHILDREN
;
480 if( wndPtr
->parent
->dwStyle
& WS_CLIPSIBLINGS
)
481 flags
|= DCX_CLIPSIBLINGS
;
485 if (flags
& DCX_CACHE
)
487 for (dce
= firstDCE
; (dce
); dce
= dce
->next
)
489 if ((dce
->DCXflags
& DCX_CACHE
) && !(dce
->DCXflags
& DCX_DCEBUSY
)) break;
494 dce
= (wndPtr
->class->style
& CS_OWNDC
)?wndPtr
->dce
:wndPtr
->class->dce
;
495 if( dce
->hwndCurrent
== hwnd
)
497 dprintf_dc(stddeb
,"\tskipping hVisRgn update\n");
501 if( hrgnClip
&& dce
->hClipRgn
&& !(dce
->DCXflags
& DCX_KEEPCLIPRGN
))
503 fprintf(stdnimp
,"GetDCEx: hClipRgn collision!\n");
504 DeleteObject32( dce
->hClipRgn
);
509 dcx_flags
= flags
& ( DCX_CLIPSIBLINGS
| DCX_CLIPCHILDREN
| DCX_CACHE
| DCX_WINDOW
| DCX_WINDOWPAINT
);
512 dce
->hwndCurrent
= hwnd
;
514 dce
->DCXflags
= dcx_flags
| DCX_DCEBUSY
;
517 if (!(dc
= (DC
*) GDI_GetObjPtr( hdc
, DC_MAGIC
))) return 0;
519 DCE_SetDrawable( wndPtr
, dc
, flags
);
520 if( need_update
|| dc
->w
.flags
& DC_DIRTY
)
522 dprintf_dc(stddeb
,"updating hDC anyway\n");
524 if (flags
& DCX_PARENTCLIP
)
526 WND
*parentPtr
= wndPtr
->parent
;
527 dcx_flags
= flags
& ~(DCX_CLIPSIBLINGS
| DCX_CLIPCHILDREN
|
529 if (parentPtr
->dwStyle
& WS_CLIPSIBLINGS
)
530 dcx_flags
|= DCX_CLIPSIBLINGS
;
531 hrgnVisible
= DCE_GetVisRgn( parentPtr
->hwndSelf
, dcx_flags
);
532 if (flags
& DCX_WINDOW
)
533 OffsetRgn32( hrgnVisible
, -wndPtr
->rectWindow
.left
,
534 -wndPtr
->rectWindow
.top
);
535 else OffsetRgn32( hrgnVisible
, -wndPtr
->rectClient
.left
,
536 -wndPtr
->rectClient
.top
);
538 /* optimize away GetVisRgn for desktop if it isn't there */
540 else if ((hwnd
== GetDesktopWindow32()) &&
541 (rootWindow
== DefaultRootWindow(display
)))
542 hrgnVisible
= CreateRectRgn32( 0, 0, SYSMETRICS_CXSCREEN
,
543 SYSMETRICS_CYSCREEN
);
544 else hrgnVisible
= DCE_GetVisRgn( hwnd
, flags
);
546 if( wndPtr
->parent
&& wndPtr
->window
)
548 WND
* wnd
= wndPtr
->parent
->child
;
551 for( ; wnd
!= wndPtr
; wnd
= wnd
->next
)
552 if( wnd
->class->style
& CS_SAVEBITS
&&
553 wnd
->dwStyle
& WS_VISIBLE
&&
554 IntersectRect32(&rect
, &wndPtr
->rectClient
, &wnd
->rectClient
) )
555 wnd
->flags
|= WIN_SAVEUNDER_OVERRIDE
;
558 dc
->w
.flags
&= ~DC_DIRTY
;
559 SelectVisRgn( hdc
, hrgnVisible
);
561 else hrgnVisible
= CreateRectRgn32( 0, 0, 0, 0 );
563 if( flags
& (DCX_EXCLUDERGN
| DCX_INTERSECTRGN
) )
565 dce
->DCXflags
|= flags
& (DCX_KEEPCLIPRGN
| DCX_INTERSECTRGN
| DCX_EXCLUDERGN
);
566 dce
->hClipRgn
= hrgnClip
;
568 dprintf_dc(stddeb
, "\tsaved VisRgn, clipRgn = %04x\n", hrgnClip
);
571 CombineRgn32( hrgnVisible
, InquireVisRgn( hdc
), hrgnClip
,
572 (flags
& DCX_INTERSECTRGN
) ? RGN_AND
: RGN_DIFF
);
573 SelectVisRgn( hdc
, hrgnVisible
);
575 DeleteObject32( hrgnVisible
);
577 dprintf_dc(stddeb
, "GetDCEx(%04x,%04x,0x%lx): returning %04x\n",
578 hwnd
, hrgnClip
, flags
, hdc
);
583 /***********************************************************************
586 HDC16
GetDC16( HWND16 hwnd
)
588 return (HDC16
)GetDC32( hwnd
);
592 /***********************************************************************
593 * GetDC32 (USER32.229)
595 HDC32
GetDC32( HWND32 hwnd
)
598 return GetDCEx32( GetDesktopWindow32(), 0, DCX_CACHE
| DCX_WINDOW
);
599 return GetDCEx32( hwnd
, 0, DCX_USESTYLE
);
603 /***********************************************************************
604 * GetWindowDC16 (USER.67)
606 HDC16
GetWindowDC16( HWND16 hwnd
)
608 if (!hwnd
) hwnd
= GetDesktopWindow16();
609 return GetDCEx16( hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
);
613 /***********************************************************************
614 * GetWindowDC32 (USER32.)
616 HDC32
GetWindowDC32( HWND32 hwnd
)
618 if (!hwnd
) hwnd
= GetDesktopWindow32();
619 return GetDCEx32( hwnd
, 0, DCX_USESTYLE
| DCX_WINDOW
);
623 /***********************************************************************
624 * ReleaseDC16 (USER.68)
626 INT16
ReleaseDC16( HWND16 hwnd
, HDC16 hdc
)
628 return (INT32
)ReleaseDC32( hwnd
, hdc
);
632 /***********************************************************************
633 * ReleaseDC32 (USER32.439)
635 INT32
ReleaseDC32( HWND32 hwnd
, HDC32 hdc
)
637 DCE
* dce
= firstDCE
;
639 dprintf_dc(stddeb
, "ReleaseDC: %04x %04x\n", hwnd
, hdc
);
641 while (dce
&& (dce
->hDC
!= hdc
)) dce
= dce
->next
;
643 if (!(dce
->DCXflags
& DCX_DCEBUSY
) ) return 0;
645 /* restore previous visible region */
647 if ( dce
->DCXflags
& (DCX_INTERSECTRGN
| DCX_EXCLUDERGN
) &&
648 (dce
->DCXflags
& DCX_CACHE
|| dce
->DCXflags
& DCX_WINDOWPAINT
) )
650 dprintf_dc(stddeb
,"\tcleaning up visrgn...\n");
651 dce
->DCXflags
&= ~(DCX_EXCLUDERGN
| DCX_INTERSECTRGN
| DCX_WINDOWPAINT
);
653 if( dce
->DCXflags
& DCX_KEEPCLIPRGN
)
654 dce
->DCXflags
&= ~DCX_KEEPCLIPRGN
;
656 if( dce
->hClipRgn
> 1 )
657 DeleteObject32( dce
->hClipRgn
);
660 RestoreVisRgn(dce
->hDC
);
663 if (dce
->DCXflags
& DCX_CACHE
)
665 SetDCState( dce
->hDC
, defaultDCstate
);
666 dce
->DCXflags
= DCX_CACHE
;
667 dce
->hwndCurrent
= 0;
672 /***********************************************************************
675 * See "Undoc. Windows" for hints (DC, SetDCHook, SetHookFlags)..
677 BOOL16
DCHook( HDC16 hDC
, WORD code
, DWORD data
, LPARAM lParam
)
680 DCE
*dce
= firstDCE
;;
682 dprintf_dc(stddeb
,"DCHook: hDC = %04x, %i\n", hDC
, code
);
684 while (dce
&& (dce
->hDC
!= hDC
)) dce
= dce
->next
;
689 case DCHC_INVALIDVISRGN
:
691 if( dce
->DCXflags
& DCX_DCEBUSY
)
693 SetHookFlags(hDC
, DCHF_VALIDATEVISRGN
);
694 hVisRgn
= DCE_GetVisRgn(dce
->hwndCurrent
, dce
->DCXflags
);
696 dprintf_dc(stddeb
,"\tapplying saved clipRgn\n");
698 /* clip this region with saved clipping region */
700 if ( (dce
->DCXflags
& DCX_INTERSECTRGN
&& dce
->hClipRgn
!= 1) ||
701 ( dce
->DCXflags
& DCX_EXCLUDERGN
&& dce
->hClipRgn
) )
704 if( (!dce
->hClipRgn
&& dce
->DCXflags
& DCX_INTERSECTRGN
) ||
705 (dce
->hClipRgn
== 1 && dce
->DCXflags
& DCX_EXCLUDERGN
) )
706 SetRectRgn32(hVisRgn
,0,0,0,0);
708 CombineRgn32(hVisRgn
, hVisRgn
, dce
->hClipRgn
,
709 (dce
->DCXflags
& DCX_EXCLUDERGN
)? RGN_DIFF
:RGN_AND
);
711 SelectVisRgn(hDC
, hVisRgn
);
712 DeleteObject32( hVisRgn
);
715 dprintf_dc(stddeb
,"DCHook: DC is not in use!\n");
719 case DCHC_DELETEDC
: /* FIXME: ?? */
723 fprintf(stdnimp
,"DCHook: unknown code\n");
729 /***********************************************************************
730 * LockWindowUpdate16 (USER.294)
732 BOOL16
LockWindowUpdate16( HWND16 hwnd
)
734 return LockWindowUpdate32( hwnd
);
738 /***********************************************************************
739 * LockWindowUpdate32 (USER32.377)
741 BOOL32
LockWindowUpdate32( HWND32 hwnd
)
743 /* FIXME? DCX_LOCKWINDOWUPDATE is unimplemented */