diff --git a/dlls/user/tests/msg.c b/dlls/user/tests/msg.c index 3fa8d573250..342015e774e 100644 --- a/dlls/user/tests/msg.c +++ b/dlls/user/tests/msg.c @@ -5226,6 +5226,72 @@ todo_wine { "unexpected error %ld\n", GetLastError()); } +static const struct message ScrollWindowPaint1[] = { + { WM_PAINT, sent }, + { WM_ERASEBKGND, sent|beginpaint }, + { 0 } +}; + +static const struct message ScrollWindowPaint2[] = { + { WM_PAINT, sent }, + { 0 } +}; + +static void test_scrollwindowex(void) +{ + HWND hwnd, hchild; + RECT rect={0,0,130,130}; + MSG msg; + + hwnd = CreateWindowExA(0, "TestWindowClass", "Test Scroll", + WS_VISIBLE|WS_OVERLAPPEDWINDOW, + 100, 100, 200, 200, 0, 0, 0, NULL); + ok (hwnd != 0, "Failed to create overlapped window\n"); + hchild = CreateWindowExA(0, "TestWindowClass", "Test child", + WS_VISIBLE|WS_CAPTION|WS_CHILD, + 10, 10, 150, 150, hwnd, 0, 0, NULL); + ok (hchild != 0, "Failed to create child\n"); + UpdateWindow(hwnd); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + flush_sequence(); + + /* scroll without the child window */ + trace("start scroll\n"); + ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, + SW_ERASE|SW_INVALIDATE); + ok_sequence(WmEmptySeq, "ScrollWindowEx\n", 0); + trace("end scroll\n"); + flush_sequence(); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(ScrollWindowPaint1, "ScrollWindowEx\n", 0); + + /* Now without the SW_ERASE flag */ + trace("start scroll\n"); + ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, SW_INVALIDATE); + ok_sequence(WmEmptySeq, "ScrollWindowEx\n", 0); + trace("end scroll\n"); + flush_sequence(); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(ScrollWindowPaint2, "ScrollWindowEx\n", 0); + + /* now scroll the child window as well */ + trace("start scroll\n"); + ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, + SW_SCROLLCHILDREN|SW_ERASE|SW_INVALIDATE); + todo_wine { /* wine sends WM_POSCHANGING, WM_POSCHANGED messages */ + /* windows sometimes a WM_MOVE */ + ok_sequence(WmEmptySeq, "ScrollWindowEx\n", 0); + } + trace("end scroll\n"); + flush_sequence(); + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + ok_sequence(ScrollWindowPaint1, "ScrollWindowEx\n", 0); + + ok(DestroyWindow(hchild), "failed to destroy window\n"); + ok(DestroyWindow(hwnd), "failed to destroy window\n"); + flush_sequence(); +} + START_TEST(msg) { HMODULE user32 = GetModuleHandleA("user32.dll"); @@ -5264,6 +5330,7 @@ START_TEST(msg) pUnhookWinEvent = 0; hEvent_hook = 0; + test_scrollwindowex(); test_messages(); test_mdi_messages(); test_button_messages(); diff --git a/windows/scroll.c b/windows/scroll.c index e5ab6720459..ec7d33581b4 100644 --- a/windows/scroll.c +++ b/windows/scroll.c @@ -75,6 +75,7 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, INT retVal = NULLREGION; BOOL bOwnRgn = TRUE; BOOL bUpdate = (rcUpdate || hrgnUpdate || flags & (SW_INVALIDATE | SW_ERASE)); + int rdw_flags; HRGN hrgnTemp; HDC hDC; RECT rc, cliprc; @@ -84,6 +85,11 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, TRACE( "%p, %d,%d hrgnUpdate=%p rcUpdate = %p %s %04x\n", hwnd, dx, dy, hrgnUpdate, rcUpdate, wine_dbgstr_rect(rect), flags ); TRACE( "clipRect = %s\n", wine_dbgstr_rect(clipRect)); + if( flags & ~( SW_SCROLLCHILDREN | SW_INVALIDATE | SW_ERASE)) + FIXME("some flags (%04x) are unhandled\n", flags); + + rdw_flags = (flags & SW_ERASE) && (flags & SW_INVALIDATE) ? + RDW_INVALIDATE | RDW_ERASE : RDW_INVALIDATE ; if (!WIN_IsWindowDrawable( hwnd, TRUE )) return ERROR; hwnd = WIN_GetFullHandle( hwnd ); @@ -109,7 +115,7 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, ReleaseDC( hwnd, hDC ); if (!bUpdate) - RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE ); + RedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags); } /* Take into account the fact that some damage may have occurred during @@ -121,7 +127,7 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, HRGN hrgnClip = CreateRectRgnIndirect(&cliprc); OffsetRgn( hrgnTemp, dx, dy ); CombineRgn( hrgnTemp, hrgnTemp, hrgnClip, RGN_AND ); - RedrawWindow( hwnd, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE ); + RedrawWindow( hwnd, NULL, hrgnTemp, rdw_flags); DeleteObject( hrgnClip ); } DeleteObject( hrgnTemp ); @@ -153,8 +159,7 @@ INT WINAPI ScrollWindowEx( HWND hwnd, INT dx, INT dy, } if( flags & (SW_INVALIDATE | SW_ERASE) ) - RedrawWindow( hwnd, NULL, hrgnUpdate, RDW_INVALIDATE | RDW_ERASE | - ((flags & SW_ERASE) ? RDW_ERASENOW : 0) | + RedrawWindow( hwnd, NULL, hrgnUpdate, rdw_flags | ((flags & SW_SCROLLCHILDREN) ? RDW_ALLCHILDREN : 0 ) ); if( hwndCaret ) {