ScrollDC fixes.
Rein Klazes
wijn at wanadoo.nl
Fri Mar 4 10:10:20 CST 2005
Hi,
This solves a number of scroll defects: areas that are not properly
repainted and flickering's.
The observation here is that the DC's visible region should be included
in the calculations. The changelog should explain.
Changelog:
dlls/x11drv : scroll.c, init.c
windows : scroll.c
dlls/user/tests : win.c, msg.c
ScrollDC and X11DRV_SCROLLDC should scroll only pixels coming from
within the visible region. Add the destination of pixels coming from the
outside of the visible region to the update region. With a test that
depends on this.
Rein.
-------------- next part --------------
--- wine/dlls/x11drv/scroll.c 2005-01-17 20:17:47.000000000 +0100
+++ mywine/dlls/x11drv/scroll.c 2005-03-04 10:34:38.000000000 +0100
@@ -35,96 +35,157 @@
WINE_DEFAULT_DEBUG_CHANNEL(scroll);
+void dump_region( char *p, HRGN hrgn)
+{
+ DWORD i, size;
+ RGNDATA *data = NULL;
+ RECT *rect;
+
+ if (!hrgn) {
+ TRACE( "%s null region\n", p );
+ return;
+ }
+ if (!(size = GetRegionData( hrgn, 0, NULL ))) {
+ return;
+ }
+ if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
+ GetRegionData( hrgn, size, data );
+ TRACE("%s %ld rects:", p, data->rdh.nCount );
+ for (i = 0, rect = (RECT *)data->Buffer; i<20 && i < data->rdh.nCount; i++, rect++)
+ TRACE( " %s", wine_dbgstr_rect( rect));
+ TRACE("\n");
+ HeapFree( GetProcessHeap(), 0, data );
+}
/*************************************************************************
* ScrollDC (X11DRV.@)
*/
BOOL X11DRV_ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
- const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
-
+ const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
{
- RECT rSrc, rClipped_src, rClip, rDst, offset;
+ RECT rcSrc, rcClip, offset;
+ INT dxdev, dydev, res;
+ HRGN SrcRgn, visrgn;
INT code = X11DRV_START_EXPOSURES;
+ TRACE("dx,dy %d,%d lprcScroll %p lprcClip %p hrgnUpdate %p lprcUpdate %p\n",
+ dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate);
+ /* enable X-exposure events */
if (hrgnUpdate || lprcUpdate)
ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, 0, NULL );
-
- /* compute device clipping region (in device coordinates) */
-
- if (lprcScroll) rSrc = *lprcScroll;
- else GetClipBox( hdc, &rSrc );
- LPtoDP(hdc, (LPPOINT)&rSrc, 2);
-
- if (lprcClip) rClip = *lprcClip;
- else GetClipBox( hdc, &rClip );
- LPtoDP(hdc, (LPPOINT)&rClip, 2);
-
- IntersectRect( &rClipped_src, &rSrc, &rClip );
- TRACE("rSrc %s rClip %s clipped rSrc %s\n", wine_dbgstr_rect(&rSrc),
- wine_dbgstr_rect(&rClip), wine_dbgstr_rect(&rClipped_src));
-
- rDst = rClipped_src;
+ /* get the visible region */
+ visrgn=CreateRectRgn( 0, 0, 0, 0);
+ GetRandomRgn( hdc, visrgn, SYSRGN);
+ if( !(GetVersion() & 0x80000000)) {
+ /* Window NT/2k/XP */
+ POINT org;
+ GetDCOrgEx(hdc, &org);
+ OffsetRgn( visrgn, -org.x, -org.y);
+ }
+ /* only those pixels in the scroll rectangle that remain in the clipping
+ * rect are scrolled. So first combine Scroll and Clipping rectangles,
+ * if available */
+ if( lprcScroll)
+ if( lprcClip)
+ IntersectRect( &rcClip, lprcClip, lprcScroll);
+ else
+ rcClip = *lprcScroll;
+ else
+ if( lprcClip)
+ rcClip = *lprcClip;
+ else
+ GetClipBox( hdc, &rcClip);
+ /* Then clip again to get the source rectangle that will remain in the
+ * clipping rect */
+ rcSrc = rcClip;
+ OffsetRect( &rcSrc, -dx, -dy);
+ IntersectRect( &rcSrc, &rcSrc, &rcClip);
+ /* now convert to device coordinates */
+ LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
+ /* also dx and dy */
SetRect(&offset, 0, 0, dx, dy);
LPtoDP(hdc, (LPPOINT)&offset, 2);
- OffsetRect( &rDst, offset.right - offset.left, offset.bottom - offset.top );
- TRACE("rDst before clipping %s\n", wine_dbgstr_rect(&rDst));
- IntersectRect( &rDst, &rDst, &rClip );
- TRACE("rDst after clipping %s\n", wine_dbgstr_rect(&rDst));
-
- if (!IsRectEmpty(&rDst))
- {
- /* copy bits */
- RECT rDst_lp = rDst, rSrc_lp = rDst;
-
- OffsetRect( &rSrc_lp, offset.left - offset.right, offset.top - offset.bottom );
- DPtoLP(hdc, (LPPOINT)&rDst_lp, 2);
- DPtoLP(hdc, (LPPOINT)&rSrc_lp, 2);
-
- if (!BitBlt( hdc, rDst_lp.left, rDst_lp.top,
- rDst_lp.right - rDst_lp.left, rDst_lp.bottom - rDst_lp.top,
- hdc, rSrc_lp.left, rSrc_lp.top, SRCCOPY))
- return FALSE;
+ dxdev = offset.right - offset.left;
+ dydev= offset.bottom - offset.top;
+ /* now intersect with the visible region to get the pixels that will
+ * actually scroll */
+ SrcRgn = CreateRectRgnIndirect( &rcSrc);
+ res = CombineRgn( SrcRgn, SrcRgn, visrgn, RGN_AND);
+ if( TRACE_ON( scroll)) dump_region( "Source scroll region: ", SrcRgn);
+ /* if there are any, do it */
+ if( res > NULLREGION) {
+ DWORD i, size;
+ int step;
+ RECT *rect;
+ RGNDATA *rdata = NULL;
+ if(( size = GetRegionData( SrcRgn, 0, NULL )) &&
+ (rdata = HeapAlloc( GetProcessHeap(), 0, size ))) {
+ GetRegionData( SrcRgn, size, rdata );
+ /* the rectangles in the region data are ordered top-to-bottom
+ * So if the scrolling is downward, traverse the array backwards
+ * to avoid touching pixels that have yet to be scrolled */
+ /* FIXME: implement something similar for left-to-right
+ * scrolling. */
+ if( dydev < 0 ) {
+ step = 1;
+ rect = (RECT *)rdata->Buffer;
+ } else {
+ step = -1;
+ rect = ((RECT *)rdata->Buffer) + rdata->rdh.nCount - 1;
+ }
+ for( i = 0; i < rdata->rdh.nCount; i++, rect += step) {
+ DPtoLP(hdc, (LPPOINT)rect, 2);
+ TRACE("Bit blitting %s to %ld,%ld\n", wine_dbgstr_rect(rect),
+ rect->left + dx, rect->top + dy);
+ BitBlt( hdc, rect->left + dx, rect->top + dy,
+ rect->right - rect->left, rect->bottom -rect->top,
+ hdc, rect->left, rect->top, SRCCOPY);
+ }
+ HeapFree( GetProcessHeap(), 0, rdata );
+ } else
+ ERR("Out of memory\n");
}
-
- /* compute update areas. This is the clipped source or'ed with the unclipped source translated minus the
- clipped src translated (rDst) all clipped to rClip */
-
+ /* compute the update areas. This is the combined clip rectangle
+ * minus the scrolled region, and intersected with the visible
+ * region. */
if (hrgnUpdate || lprcUpdate)
{
- HRGN hrgn = hrgnUpdate, hrgn2, hrgn3 = 0;
+ HRGN hrgn = hrgnUpdate;
+ HRGN ExpRgn = 0;
+ HRGN DstRgn;
+ /* collect all the exposures */
code = X11DRV_END_EXPOSURES;
- ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code, sizeof(hrgn3), (LPSTR)&hrgn3 );
-
- if (hrgn) SetRectRgn( hrgn, rClipped_src.left, rClipped_src.top, rClipped_src.right, rClipped_src.bottom );
- else hrgn = CreateRectRgn( rClipped_src.left, rClipped_src.top, rClipped_src.right, rClipped_src.bottom );
-
- hrgn2 = CreateRectRgnIndirect( &rSrc );
- OffsetRgn(hrgn2, offset.right - offset.left, offset.bottom - offset.top );
- CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
-
- SetRectRgn( hrgn2, rDst.left, rDst.top, rDst.right, rDst.bottom );
- CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );
-
- SetRectRgn( hrgn2, rClip.left, rClip.top, rClip.right, rClip.bottom );
- CombineRgn( hrgn, hrgn, hrgn2, RGN_AND );
-
- if (hrgn3)
- {
- CombineRgn( hrgn, hrgn, hrgn3, RGN_OR );
- DeleteObject( hrgn3 );
+ ExtEscape( hdc, X11DRV_ESCAPE, sizeof(code), (LPSTR)&code,
+ sizeof(ExpRgn), (LPSTR)&ExpRgn );
+ /* still needs to be converted to device coordinates */
+ LPtoDP(hdc, (LPPOINT)&rcClip, 2);
+ if( hrgn )
+ SetRectRgn( hrgn, rcClip.left, rcClip.top, rcClip.right,
+ rcClip.bottom);
+ else
+ hrgn = CreateRectRgnIndirect( &rcClip);
+ DstRgn = SrcRgn; /* change the name */
+ OffsetRgn( DstRgn, dxdev, dydev);
+ CombineRgn( hrgn, hrgn, visrgn, RGN_AND);
+ CombineRgn( hrgn, hrgn, DstRgn, RGN_DIFF);
+ /* add the exposures to this */
+ if( ExpRgn) {
+ if( TRACE_ON( scroll)) dump_region( "Expose region: ", ExpRgn);
+ CombineRgn( hrgn, hrgn, ExpRgn, RGN_OR );
+ DeleteObject( ExpRgn );
}
-
- if( lprcUpdate )
- {
+ if( TRACE_ON( scroll)) dump_region( "Update region: ", hrgn);
+ if( lprcUpdate ) {
GetRgnBox( hrgn, lprcUpdate );
-
/* Put the lprcUpdate in logical coordinate */
DPtoLP( hdc, (LPPOINT)lprcUpdate, 2 );
TRACE("returning lprcUpdate %s\n", wine_dbgstr_rect(lprcUpdate));
}
- if (!hrgnUpdate) DeleteObject( hrgn );
- DeleteObject( hrgn2 );
+ if( !hrgnUpdate)
+ DeleteObject( hrgn);
}
+ DeleteObject( visrgn );
+ DeleteObject( SrcRgn );
return TRUE;
}
--- wine/dlls/x11drv/init.c 2004-11-30 22:38:58.000000000 +0100
+++ mywine/dlls/x11drv/init.c 2005-03-03 21:19:21.000000000 +0100
@@ -353,6 +353,7 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *ph
HRGN hrgn = 0, tmp = 0;
wine_tsx11_lock();
+ XFlush( gdi_display);
XSetGraphicsExposures( gdi_display, physDev->gc, False );
if (physDev->exposures)
{
@@ -360,8 +361,9 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *ph
{
XEvent event;
- XWindowEvent( gdi_display, physDev->drawable, ~0, &event );
- if (event.type == NoExpose) break;
+ if( !XCheckWindowEvent( gdi_display, physDev->drawable, ~0, &event ))
+ break;
+ if (event.type == NoExpose) continue;
if (event.type == GraphicsExpose)
{
int x = event.xgraphicsexpose.x - physDev->org.x;
@@ -382,7 +384,6 @@ INT X11DRV_ExtEscape( X11DRV_PDEVICE *ph
hrgn = tmp;
tmp = 0;
}
- if (!event.xgraphicsexpose.count) break;
}
else
{
--- wine/windows/scroll.c 2005-02-08 15:27:39.000000000 +0100
+++ mywine/windows/scroll.c 2005-03-04 12:52:04.000000000 +0100
@@ -185,17 +185,42 @@ BOOL WINAPI ScrollWindow( HWND hwnd, INT
SW_INVALIDATE ));
}
+static void dump_region( char *p, HRGN hrgn)
+{
+ DWORD i, size;
+ RGNDATA *data = NULL;
+ RECT *rect;
+
+ if (!hrgn) {
+ TRACE( "%s null region\n", p );
+ return;
+ }
+ if (!(size = GetRegionData( hrgn, 0, NULL ))) {
+ return;
+ }
+ if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return;
+ GetRegionData( hrgn, size, data );
+ TRACE("%s %ld rects:", p, data->rdh.nCount );
+ for (i = 0, rect = (RECT *)data->Buffer; i<20 && i < data->rdh.nCount; i++, rect++)
+ TRACE( " %s", wine_dbgstr_rect( rect));
+ TRACE("\n");
+ HeapFree( GetProcessHeap(), 0, data );
+}
+
/*************************************************************************
* ScrollDC (USER32.@)
*
- * dx, dy, lprcScroll and lprcClip are all in logical coordinates (msdn is wrong)
- * hrgnUpdate is returned in device coordinates with rcUpdate in logical coordinates.
+ * dx, dy, lprcScroll and lprcClip are all in logical coordinates (msdn is
+ * wrong) hrgnUpdate is returned in device coordinates with rcUpdate in
+ * logical coordinates.
*/
BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
- const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
+ const RECT *lprcClip, HRGN hrgnUpdate, LPRECT lprcUpdate )
{
- RECT rSrc, rClipped_src, rClip, rDst, offset;
+ RECT rcSrc, rcClip, offset;
+ INT dxdev, dydev, res;
+ HRGN SrcRgn, visrgn;
TRACE( "%p %d,%d hrgnUpdate=%p lprcUpdate = %p\n", hdc, dx, dy, hrgnUpdate, lprcUpdate );
if (lprcClip) TRACE( "lprcClip = %s\n", wine_dbgstr_rect(lprcClip));
@@ -204,72 +229,109 @@ BOOL WINAPI ScrollDC( HDC hdc, INT dx, I
if (USER_Driver.pScrollDC)
return USER_Driver.pScrollDC( hdc, dx, dy, lprcScroll, lprcClip, hrgnUpdate, lprcUpdate );
- /* compute device clipping region (in device coordinates) */
- if (lprcScroll) rSrc = *lprcScroll;
- else GetClipBox( hdc, &rSrc );
- LPtoDP(hdc, (LPPOINT)&rSrc, 2);
-
- if (lprcClip) rClip = *lprcClip;
- else GetClipBox( hdc, &rClip );
- LPtoDP(hdc, (LPPOINT)&rClip, 2);
-
- IntersectRect( &rClipped_src, &rSrc, &rClip );
- TRACE("rSrc %s rClip %s clipped rSrc %s\n", wine_dbgstr_rect(&rSrc),
- wine_dbgstr_rect(&rClip), wine_dbgstr_rect(&rClipped_src));
-
- rDst = rClipped_src;
+ /* get the visible region */
+ visrgn=CreateRectRgn( 0, 0, 0, 0);
+ GetRandomRgn( hdc, visrgn, SYSRGN);
+ if( !(GetVersion() & 0x80000000)) {
+ /* Window NT/2k/XP */
+ POINT org;
+ GetDCOrgEx(hdc, &org);
+ OffsetRgn( visrgn, -org.x, -org.y);
+ }
+ /* only those pixels in the scroll rectangle that remain in the clipping
+ * rect are scrolled. So first combine Scroll and Clipping rectangles,
+ * if available */
+ if( lprcScroll)
+ if( lprcClip)
+ IntersectRect( &rcClip, lprcClip, lprcScroll);
+ else
+ rcClip = *lprcScroll;
+ else
+ if( lprcClip)
+ rcClip = *lprcClip;
+ else
+ GetClipBox( hdc, &rcClip);
+ /* Then clip again to get the source rectangle that will remain in the
+ * clipping rect */
+ rcSrc = rcClip;
+ OffsetRect( &rcSrc, -dx, -dy);
+ IntersectRect( &rcSrc, &rcSrc, &rcClip);
+ /* now convert to device coordinates */
+ LPtoDP(hdc, (LPPOINT)&rcSrc, 2);
+ /* also dx and dy */
SetRect(&offset, 0, 0, dx, dy);
LPtoDP(hdc, (LPPOINT)&offset, 2);
- OffsetRect( &rDst, offset.right - offset.left, offset.bottom - offset.top );
- TRACE("rDst before clipping %s\n", wine_dbgstr_rect(&rDst));
- IntersectRect( &rDst, &rDst, &rClip );
- TRACE("rDst after clipping %s\n", wine_dbgstr_rect(&rDst));
-
- if (!IsRectEmpty(&rDst))
- {
- /* copy bits */
- RECT rDst_lp = rDst, rSrc_lp = rDst;
-
- OffsetRect( &rSrc_lp, offset.left - offset.right, offset.top - offset.bottom );
- DPtoLP(hdc, (LPPOINT)&rDst_lp, 2);
- DPtoLP(hdc, (LPPOINT)&rSrc_lp, 2);
-
- if (!BitBlt( hdc, rDst_lp.left, rDst_lp.top,
- rDst_lp.right - rDst_lp.left, rDst_lp.bottom - rDst_lp.top,
- hdc, rSrc_lp.left, rSrc_lp.top, SRCCOPY))
- return FALSE;
+ dxdev = offset.right - offset.left;
+ dydev= offset.bottom - offset.top;
+ /* now intersect with the visible region to get the pixels that will
+ * actually scroll */
+ SrcRgn = CreateRectRgnIndirect( &rcSrc);
+ res = CombineRgn( SrcRgn, SrcRgn, visrgn, RGN_AND);
+ if( TRACE_ON( scroll)) dump_region( "Source scroll region: ", SrcRgn);
+ /* if there are any, do it */
+ if( res > NULLREGION) {
+ DWORD i, size;
+ int step;
+ RECT *rect;
+ RGNDATA *rdata = NULL;
+ if(( size = GetRegionData( SrcRgn, 0, NULL )) &&
+ (rdata = HeapAlloc( GetProcessHeap(), 0, size ))) {
+ GetRegionData( SrcRgn, size, rdata );
+ /* the rectangles in the region data are ordered top-to-bottom
+ * So if the scrolling is downward, traverse the array backwards
+ * to avoid touching pixels that have yet to be scrolled */
+ /* FIXME: implement something similar for left-to-right
+ * scrolling. */
+ if( dydev < 0 ) {
+ step = 1;
+ rect = (RECT *)rdata->Buffer;
+ } else {
+ step = -1;
+ rect = ((RECT *)rdata->Buffer) + rdata->rdh.nCount - 1;
+ }
+ for( i = 0; i < rdata->rdh.nCount; i++, rect += step) {
+ DPtoLP(hdc, (LPPOINT)rect, 2);
+ TRACE("Bit blitting %s to %ld,%ld\n", wine_dbgstr_rect(rect),
+ rect->left + dx, rect->top + dy);
+ BitBlt( hdc, rect->left + dx, rect->top + dy,
+ rect->right - rect->left, rect->bottom -rect->top,
+ hdc, rect->left, rect->top, SRCCOPY);
+ }
+ HeapFree( GetProcessHeap(), 0, rdata );
+ } else
+ ERR("Out of memory\n");
}
-
- /* compute update areas. This is the clipped source or'ed with the unclipped source translated minus the
- clipped src translated (rDst) all clipped to rClip */
-
+ /* compute the update areas. This is the combined clip rectangle
+ * minus the scrolled region, and intersected with the visible
+ * region. */
if (hrgnUpdate || lprcUpdate)
{
- HRGN hrgn = hrgnUpdate, hrgn2;
-
- if (hrgn) SetRectRgn( hrgn, rClipped_src.left, rClipped_src.top, rClipped_src.right, rClipped_src.bottom );
- else hrgn = CreateRectRgn( rClipped_src.left, rClipped_src.top, rClipped_src.right, rClipped_src.bottom );
-
- hrgn2 = CreateRectRgnIndirect( &rSrc );
- OffsetRgn(hrgn2, offset.right - offset.left, offset.bottom - offset.top );
- CombineRgn(hrgn, hrgn, hrgn2, RGN_OR);
-
- SetRectRgn( hrgn2, rDst.left, rDst.top, rDst.right, rDst.bottom );
- CombineRgn( hrgn, hrgn, hrgn2, RGN_DIFF );
+ HRGN hrgn = hrgnUpdate;
+ HRGN DstRgn;
- SetRectRgn( hrgn2, rClip.left, rClip.top, rClip.right, rClip.bottom );
- CombineRgn( hrgn, hrgn, hrgn2, RGN_AND );
+ /* still needs to be converted to device coordinates */
+ LPtoDP(hdc, (LPPOINT)&rcClip, 2);
+ if( hrgn )
+ SetRectRgn( hrgn, rcClip.left, rcClip.top, rcClip.right,
+ rcClip.bottom);
+ else
+ hrgn = CreateRectRgnIndirect( &rcClip);
+ DstRgn = SrcRgn; /* change the name */
+ OffsetRgn( DstRgn, dxdev, dydev);
+ CombineRgn( hrgn, hrgn, visrgn, RGN_AND);
+ CombineRgn( hrgn, hrgn, DstRgn, RGN_DIFF);
- if( lprcUpdate )
- {
+ if( TRACE_ON( scroll)) dump_region( "Update region: ", hrgn);
+ if( lprcUpdate ) {
GetRgnBox( hrgn, lprcUpdate );
-
/* Put the lprcUpdate in logical coordinate */
DPtoLP( hdc, (LPPOINT)lprcUpdate, 2 );
TRACE("returning lprcUpdate %s\n", wine_dbgstr_rect(lprcUpdate));
}
- if (!hrgnUpdate) DeleteObject( hrgn );
- DeleteObject( hrgn2 );
+ if( !hrgnUpdate)
+ DeleteObject( hrgn);
}
+ DeleteObject( visrgn );
+ DeleteObject( SrcRgn );
return TRUE;
}
--- wine/dlls/user/tests/win.c 2005-03-01 10:16:21.000000000 +0100
+++ mywine/dlls/user/tests/win.c 2005-03-04 14:12:33.000000000 +0100
@@ -45,6 +45,8 @@
#define LONG_PTR INT_PTR
#define ULONG_PTR UINT_PTR
+void dump_region(HRGN hrgn);
+
static HWND (WINAPI *pGetAncestor)(HWND,UINT);
static BOOL (WINAPI *pGetWindowInfo)(HWND,WINDOWINFO*);
@@ -2333,6 +2335,48 @@ void test_nccalcscroll( HWND parent)
DestroyWindow( hwnd);
}
+
+void test_scrollvalidate( HWND parent)
+{
+ HDC hdc;
+ HRGN hrgn=CreateRectRgn(0,0,0,0);
+ HRGN exprgn, tmprgn;
+ RECT rc, rcu, cliprc;
+ /* create two overlapping child windows. The visual region
+ * of hwnd1 is clipped by the overlapping part of
+ * hwnd2 because of the WS_CLIPSIBLING style */
+ HWND hwnd2 = CreateWindowExA(0, "static", NULL,
+ WS_CHILD| WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER ,
+ 75, 50, 100, 100, parent, 0, 0, NULL);
+ HWND hwnd1 = CreateWindowExA(0, "static", NULL,
+ WS_CHILD| WS_VISIBLE | WS_CLIPSIBLINGS | WS_BORDER ,
+ 25, 70, 100, 100, parent, 0, 0, NULL);
+ ShowWindow( parent, SW_SHOW);
+ UpdateWindow( parent);
+ GetClientRect( hwnd1, &rc);
+ cliprc=rc;
+ hdc = GetDC( hwnd1);
+ /* for a visual touch */
+ TextOut( hdc, 0,10, "0123456789", 10);
+ ScrollDC( hdc, -10, -5, &rc, &cliprc, hrgn, &rcu);
+ dump_region(hrgn);
+ /* create a region with what is expected */
+ exprgn = CreateRectRgn( 39,0,49,74);
+ tmprgn = CreateRectRgn( 88,79,98,93);
+ CombineRgn( exprgn, exprgn, tmprgn, RGN_OR);
+ tmprgn = CreateRectRgn( 0, 93,98,98);
+ CombineRgn( exprgn, exprgn, tmprgn, RGN_OR);
+ ok( EqualRgn( exprgn, exprgn), "wrong update region\n");
+ trace("update rect is %ld,%ld - %ld,%ld\n",
+ rcu.left,rcu.top,rcu.right,rcu.bottom);
+ /* clean up */
+ DeleteObject( hrgn);
+ DeleteObject( exprgn);
+ DeleteObject( tmprgn);
+ DestroyWindow( hwnd1);
+ DestroyWindow( hwnd2);
+}
+
START_TEST(win)
{
pGetAncestor = (void *)GetProcAddress( GetModuleHandleA("user32.dll"), "GetAncestor" );
@@ -2390,6 +2434,7 @@ START_TEST(win)
test_mouse_input(hwndMain);
test_validatergn(hwndMain);
test_nccalcscroll( hwndMain);
+ test_scrollvalidate( hwndMain);
UnhookWindowsHookEx(hhook);
}
--- wine/dlls/user/tests/msg.c 2005-03-01 10:16:20.000000000 +0100
+++ mywine/dlls/user/tests/msg.c 2005-03-01 12:27:21.000000000 +0100
@@ -3305,7 +3305,7 @@ static void test_button_messages(void)
/************* painting message test ********************/
-static void dump_region(HRGN hrgn)
+void dump_region(HRGN hrgn)
{
DWORD i, size;
RGNDATA *data = NULL;
More information about the wine-patches
mailing list