diff --git a/windows/dce.c b/windows/dce.c index 092026a4c2afa836fc78aa626211d7f4c3719f09..8124abd50a9914c1b682969f656b7f0453b6ff0a 100644 --- a/windows/dce.c +++ b/windows/dce.c @@ -645,7 +645,7 @@ HDC16 WINAPI GetDCEx16( HWND16 hwnd, HRGN16 hrgnClip, DWORD flags ) */ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) { - HRGN hrgnVisible = 0; + HRGN hCopyClipRgn=0,hrgnVisible = 0; HDC hdc = 0; DCE * dce; DC * dc; @@ -792,9 +792,32 @@ HDC WINAPI GetDCEx( HWND hwnd, HRGN hrgnClip, DWORD flags ) } bUpdateVisRgn = bUpdateVisRgn || (dc->w.flags & DC_DIRTY); - /* recompute visible region */ + /* + * The pSetDrawable function might change the coordinate system (DCOrgX,DCOrgY) + * values. When it moves the origin, other data like the current clipping + * region will not be moved to that new origin. In the case of DCs that are class + * or window DCs that clipping region might be a valid value from a previous use + * of the DC and changing the origin of the DC without moving the clip region + * results in a clip region that is not placed properly in the DC. + * This code will retrieve the current clipping region, let the pSetDrawable + * modify the origin and reset the clipping. When the clipping is set, it is moved + * according to the new DC origin. + */ + if ( (wndPtr->class->style & (CS_OWNDC | CS_CLASSDC)) && (dc->w.hClipRgn > 0)) + { + hCopyClipRgn=CreateRectRgn( 0, 0, 0, 0 ); + GetClipRgn(hdc,hCopyClipRgn); + } + /* recompute visible region */ wndPtr->pDriver->pSetDrawable( wndPtr, dc, flags, bUpdateClipOrigin ); + + if (hCopyClipRgn) + { + SelectClipRgn(hdc,hCopyClipRgn); + DeleteObject(hCopyClipRgn); + } + if( bUpdateVisRgn ) { TRACE("updating visrgn for %08x dce, hwnd [%04x]\n", (unsigned)dce, hwnd);