From f71be05ba7bd7a758200c395f1c211f38e5e98f2 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Wed, 29 Aug 2012 12:22:58 +0200 Subject: [PATCH] user32: ScrollWindow should not use a cached DC, unlike ScrollWindowEx. --- dlls/user32/painting.c | 36 +++++++++++++++++------------ dlls/user32/tests/dce.c | 51 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 15 deletions(-) diff --git a/dlls/user32/painting.c b/dlls/user32/painting.c index dcf615d18a..98dfc54a74 100644 --- a/dlls/user32/painting.c +++ b/dlls/user32/painting.c @@ -1367,17 +1367,8 @@ INT WINAPI ExcludeUpdateRgn( HDC hdc, HWND hwnd ) } -/************************************************************************* - * ScrollWindowEx (USER32.@) - * - * Note: contrary to what the doc says, pixels that are scrolled from the - * outside of clipRect to the inside are NOT painted. - * - */ -INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, - const RECT *rect, const RECT *clipRect, - HRGN hrgnUpdate, LPRECT rcUpdate, - UINT flags ) +static INT scroll_window( HWND hwnd, INT dx, INT dy, const RECT *rect, const RECT *clipRect, + HRGN hrgnUpdate, LPRECT rcUpdate, UINT flags, BOOL is_ex ) { INT retVal = NULLREGION; BOOL bOwnRgn = TRUE; @@ -1416,11 +1407,12 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, newCaretPos.x = newCaretPos.y = 0; if( !IsRectEmpty(&cliprc) && (dx || dy)) { - DWORD dcxflags = DCX_CACHE; + DWORD dcxflags = 0; DWORD style = GetWindowLongW( hwnd, GWL_STYLE ); hwndCaret = fix_caret(hwnd, &rc, dx, dy, flags, &moveCaret, &newCaretPos); + if (is_ex) dcxflags |= DCX_CACHE; if( style & WS_CLIPSIBLINGS) dcxflags |= DCX_CLIPSIBLINGS; if( GetClassLongW( hwnd, GCL_STYLE ) & CS_PARENTDC) dcxflags |= DCX_PARENTCLIP; @@ -1522,6 +1514,21 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, } +/************************************************************************* + * ScrollWindowEx (USER32.@) + * + * Note: contrary to what the doc says, pixels that are scrolled from the + * outside of clipRect to the inside are NOT painted. + * + */ +INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, + const RECT *rect, const RECT *clipRect, + HRGN hrgnUpdate, LPRECT rcUpdate, + UINT flags ) +{ + return scroll_window( hwnd, dx, dy, rect, clipRect, hrgnUpdate, rcUpdate, flags, TRUE ); +} + /************************************************************************* * ScrollWindow (USER32.@) * @@ -1529,9 +1536,8 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, BOOL WINAPI ScrollWindow( HWND hwnd, INT dx, INT dy, const RECT *rect, const RECT *clipRect ) { - return (ERROR != ScrollWindowEx( hwnd, dx, dy, rect, clipRect, 0, NULL, - (rect ? 0 : SW_SCROLLCHILDREN) | - SW_INVALIDATE | SW_ERASE )); + return scroll_window( hwnd, dx, dy, rect, clipRect, 0, NULL, + SW_INVALIDATE | SW_ERASE | (rect ? 0 : SW_SCROLLCHILDREN), FALSE ) != ERROR; } diff --git a/dlls/user32/tests/dce.c b/dlls/user32/tests/dce.c index 9b5a89ebea..1aa548ef6d 100644 --- a/dlls/user32/tests/dce.c +++ b/dlls/user32/tests/dce.c @@ -406,6 +406,56 @@ static void test_begin_paint(void) "clip box should have been reset %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); } +/* test ScrollWindow with window DCs */ +static void test_scroll_window(void) +{ + PAINTSTRUCT ps; + HDC hdc; + RECT clip, rect; + + /* ScrollWindow uses the window DC, ScrollWindowEx doesn't */ + + UpdateWindow( hwnd_owndc ); + SetRect( &clip, 25, 25, 50, 50 ); + ScrollWindow( hwnd_owndc, -5, -10, NULL, &clip ); + hdc = BeginPaint( hwnd_owndc, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 25 && rect.top >= 25 && rect.right <= 50 && rect.bottom <= 50, + "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); + EndPaint( hwnd_owndc, &ps ); + + SetViewportExtEx( hdc, 2, 3, NULL ); + SetViewportOrgEx( hdc, 30, 20, NULL ); + + ScrollWindow( hwnd_owndc, -5, -10, NULL, &clip ); + hdc = BeginPaint( hwnd_owndc, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 25 && rect.top >= 25 && rect.right <= 50 && rect.bottom <= 50, + "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); + EndPaint( hwnd_owndc, &ps ); + + ScrollWindowEx( hwnd_owndc, -5, -10, NULL, &clip, 0, NULL, SW_INVALIDATE | SW_ERASE ); + hdc = BeginPaint( hwnd_owndc, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= -5 && rect.top >= 5 && rect.right <= 20 && rect.bottom <= 30, + "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); + EndPaint( hwnd_owndc, &ps ); + + SetViewportExtEx( hdc, 1, 1, NULL ); + SetViewportOrgEx( hdc, 0, 0, NULL ); + + ScrollWindowEx( hwnd_owndc, -5, -10, NULL, &clip, 0, NULL, SW_INVALIDATE | SW_ERASE ); + hdc = BeginPaint( hwnd_owndc, &ps ); + SetRectEmpty( &rect ); + GetClipBox( hdc, &rect ); + ok( rect.left >= 25 && rect.top >= 25 && rect.right <= 50 && rect.bottom <= 50, + "invalid clip box %d,%d-%d,%d\n", rect.left, rect.top, rect.right, rect.bottom ); + EndPaint( hwnd_owndc, &ps ); +} + static void test_invisible_create(void) { HWND hwnd_owndc = CreateWindowA("owndc_class", NULL, WS_OVERLAPPED, @@ -559,6 +609,7 @@ START_TEST(dce) test_parameters(); test_dc_visrgn(); test_begin_paint(); + test_scroll_window(); test_invisible_create(); test_dc_layout();