Commit e8698e9e authored by Rein Klazes's avatar Rein Klazes Committed by Alexandre Julliard

When there are no pixels to scroll, ScrollWindowEx must still scroll

children and update the hrgnUpdate and rcUpdate arguments.
parent 9e2e594a
...@@ -61,30 +61,33 @@ static HWND fix_caret(HWND hWnd, LPRECT lprc, UINT flags) ...@@ -61,30 +61,33 @@ static HWND fix_caret(HWND hWnd, LPRECT lprc, UINT flags)
} }
/************************************************************************* /*************************************************************************
* scroll_window * ScrollWindowEx (USER32.@)
* *
* Note: contrary to what the doc says, pixels that are scrolled from the * Note: contrary to what the doc says, pixels that are scrolled from the
* outside of clipRect to the inside are NOT painted. * outside of clipRect to the inside are NOT painted.
* *
* Parameter are the same as in ScrollWindowEx, with the additional
* requirement that rect and clipRect are _valid_ pointers, to
* rectangles _within_ the client are. Moreover, there is something
* to scroll.
*/ */
static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy,
const RECT *clipRect, HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags ) const RECT *rect, const RECT *clipRect,
HRGN hrgnUpdate, LPRECT rcUpdate,
UINT flags )
{ {
INT retVal; INT retVal = NULLREGION;
BOOL bOwnRgn = TRUE; BOOL bOwnRgn = TRUE;
BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE)); BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE));
HRGN hrgnTemp; HRGN hrgnTemp;
HDC hDC; HDC hDC;
RECT rc, cliprc; RECT rc, cliprc;
RECT caretrc;
HWND hwndCaret = NULL;
TRACE( "%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x\n", TRACE( "%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x\n",
hwnd, dx, dy, hrgnUpdate, rcUpdate, wine_dbgstr_rect(rect), flags ); hwnd, dx, dy, hrgnUpdate, rcUpdate, wine_dbgstr_rect(rect), flags );
TRACE( "clipRect = %s\n", wine_dbgstr_rect(clipRect)); TRACE( "clipRect = %s\n", wine_dbgstr_rect(clipRect));
if (!WIN_IsWindowDrawable( hwnd, TRUE )) return ERROR;
hwnd = WIN_GetFullHandle( hwnd );
GetClientRect(hwnd, &rc); GetClientRect(hwnd, &rc);
if (rect) IntersectRect(&rc, &rc, rect); if (rect) IntersectRect(&rc, &rc, rect);
...@@ -94,29 +97,40 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, ...@@ -94,29 +97,40 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect,
if( hrgnUpdate ) bOwnRgn = FALSE; if( hrgnUpdate ) bOwnRgn = FALSE;
else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 ); else if( bUpdate ) hrgnUpdate = CreateRectRgn( 0, 0, 0, 0 );
hDC = GetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE ); if( !IsRectEmpty(&cliprc) && (dx || dy)) {
if (hDC) caretrc = rc;
{ hwndCaret = fix_caret(hwnd, &caretrc, flags);
ScrollDC( hDC, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate );
ReleaseDC( hwnd, hDC ); hDC = GetDCEx( hwnd, 0, DCX_CACHE | DCX_USESTYLE );
if (hDC)
{
ScrollDC( hDC, dx, dy, &rc, &cliprc, hrgnUpdate, rcUpdate );
if (!bUpdate) ReleaseDC( hwnd, hDC );
RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE );
}
/* Take into account the fact that some damage may have occurred during the scroll */ if (!bUpdate)
hrgnTemp = CreateRectRgn( 0, 0, 0, 0 ); RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE );
retVal = GetUpdateRgn( hwnd, hrgnTemp, FALSE ); }
if (retVal != NULLREGION)
{ /* Take into account the fact that some damage may have occurred during
HRGN hrgnClip = CreateRectRgnIndirect(&cliprc); * the scroll */
OffsetRgn( hrgnTemp, dx, dy ); hrgnTemp = CreateRectRgn( 0, 0, 0, 0 );
CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND ); retVal = GetUpdateRgn( hwnd, hrgnTemp, FALSE );
RedrawWindow( hwnd, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE ); if (retVal != NULLREGION)
DeleteObject( hrgnClip ); {
HRGN hrgnClip = CreateRectRgnIndirect(&cliprc);
OffsetRgn( hrgnTemp, dx, dy );
CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND );
RedrawWindow( hwnd, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE );
DeleteObject( hrgnClip );
}
DeleteObject( hrgnTemp );
} else {
/* nothing was scrolled */
if( !bOwnRgn)
SetRectRgn( hrgnUpdate, 0, 0, 0, 0 );
SetRectEmpty( rcUpdate);
} }
DeleteObject( hrgnTemp );
if( flags & SW_SCROLLCHILDREN ) if( flags & SW_SCROLLCHILDREN )
{ {
...@@ -129,7 +143,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, ...@@ -129,7 +143,7 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect,
{ {
GetWindowRect( list[i], &r ); GetWindowRect( list[i], &r );
MapWindowPoints( 0, hwnd, (POINT *)&r, 2 ); MapWindowPoints( 0, hwnd, (POINT *)&r, 2 );
if (!rect || IntersectRect(&dummy, &r, &rc)) if (!rect || IntersectRect(&dummy, &r, rect))
SetWindowPos( list[i], 0, r.left + dx, r.top + dy, 0, 0, SetWindowPos( list[i], 0, r.left + dx, r.top + dy, 0, 0,
SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE |
SWP_NOREDRAW | SWP_DEFERERASE ); SWP_NOREDRAW | SWP_DEFERERASE );
...@@ -143,6 +157,11 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, ...@@ -143,6 +157,11 @@ static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect,
((flags & SW_ERASE) ? RDW_ERASENOW : 0) | ((flags & SW_ERASE) ? RDW_ERASENOW : 0) |
((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) ); ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) );
if( hwndCaret ) {
SetCaretPos( caretrc.left + dx, caretrc.top + dy );
ShowCaret(hwndCaret);
}
if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate ); if( bOwnRgn && hrgnUpdate ) DeleteObject( hrgnUpdate );
return retVal; return retVal;
...@@ -249,46 +268,3 @@ BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll, ...@@ -249,46 +268,3 @@ BOOL WINAPI ScrollDC( HDC hdc, INT dx, INT dy, const RECT *lprcScroll,
} }
return TRUE; return TRUE;
} }
/*************************************************************************
* ScrollWindowEx (USER32.@)
*
* NOTE: Use this function instead of ScrollWindow32
*/
INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy,
const RECT *rect, const RECT *clipRect,
HRGN hrgnUpdate, LPRECT rcUpdate,
UINT flags )
{
RECT rc, cliprc;
INT result;
if (!WIN_IsWindowDrawable( hwnd, TRUE )) return ERROR;
hwnd = WIN_GetFullHandle( hwnd );
GetClientRect(hwnd, &rc);
if (rect) IntersectRect(&rc, &rc, rect);
if (clipRect) IntersectRect(&cliprc,&rc,clipRect);
else cliprc = rc;
if (!IsRectEmpty(&cliprc) && (dx || dy))
{
RECT caretrc = rc;
HWND hwndCaret = fix_caret(hwnd, &caretrc, flags);
result = scroll_window( hwnd, dx, dy, rect, clipRect,
hrgnUpdate, rcUpdate, flags );
if( hwndCaret )
{
SetCaretPos( caretrc.left + dx, caretrc.top + dy );
ShowCaret(hwndCaret);
}
}
else
result = NULLREGION;
return result;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment