-- v2: win32u: Fix return value of ScrollWindowEx() for invisible windows. user32/tests: Add more ScrollWindowEx() tests.
From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/user32/tests/msg.c | 52 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 48 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 04b01ff5766..5fa733be047 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -12900,10 +12900,16 @@ static const struct message ScrollWindowPaint2[] = { { 0 } };
+static const struct message ScrollWindowExSeq[] = { + { WM_MOVE, sent }, + { 0 } +}; + static void test_scrollwindowex(void) { HWND hwnd, hchild; RECT rect={0,0,130,130}; + int ret;
hwnd = CreateWindowExA(0, "TestWindowClass", "Test Scroll", WS_VISIBLE|WS_OVERLAPPEDWINDOW, @@ -12919,8 +12925,10 @@ static void test_scrollwindowex(void)
/* scroll without the child window */ if (winetest_debug > 1) trace("start scroll\n"); - ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, + ret = ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, SW_ERASE|SW_INVALIDATE); + todo_wine + ok(ret == COMPLEXREGION, "got %d\n", ret); ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE); if (winetest_debug > 1) trace("end scroll\n"); flush_sequence(); @@ -12931,7 +12939,9 @@ static void test_scrollwindowex(void)
/* Now without the SW_ERASE flag */ if (winetest_debug > 1) trace("start scroll\n"); - ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, SW_INVALIDATE); + ret = ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, SW_INVALIDATE); + todo_wine + ok(ret == COMPLEXREGION, "got %d\n", ret); ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE); if (winetest_debug > 1) trace("end scroll\n"); flush_sequence(); @@ -12942,8 +12952,10 @@ static void test_scrollwindowex(void)
/* now scroll the child window as well */ if (winetest_debug > 1) trace("start scroll\n"); - ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, + ret = ScrollWindowEx( hwnd, 10, 10, &rect, NULL, NULL, NULL, SW_SCROLLCHILDREN|SW_ERASE|SW_INVALIDATE); + todo_wine + ok(ret == COMPLEXREGION, "got %d\n", ret); /* wine sends WM_POSCHANGING, WM_POSCHANGED messages */ /* windows sometimes a WM_MOVE */ ok_sequence(WmEmptySeq, "ScrollWindowEx", TRUE); @@ -12954,14 +12966,46 @@ static void test_scrollwindowex(void) flush_events(); flush_sequence();
+ ret = ScrollWindowEx(hwnd, 10, 10, NULL, NULL, NULL, NULL, + SW_SCROLLCHILDREN|SW_ERASE|SW_INVALIDATE); + todo_wine + ok(ret == COMPLEXREGION, "got %d\n", ret); + ok_sequence(ScrollWindowExSeq, "ScrollWindowEx", TRUE); + flush_events(); + flush_sequence(); + ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE); + flush_events(); + flush_sequence(); + /* now scroll with ScrollWindow() */ if (winetest_debug > 1) trace("start scroll with ScrollWindow\n"); - ScrollWindow( hwnd, 5, 5, NULL, NULL); + ret = ScrollWindow( hwnd, 5, 5, NULL, NULL); + ok(ret, "got %d\n", ret); if (winetest_debug > 1) trace("end scroll\n"); flush_sequence(); flush_events(); ok_sequence(ScrollWindowPaint1, "ScrollWindow", FALSE);
+ ShowWindow(hwnd, SW_HIDE); + flush_sequence(); + flush_events(); + + ret = ScrollWindowEx(hwnd, 10, 10, &rect, NULL, NULL, NULL, + SW_SCROLLCHILDREN|SW_ERASE|SW_INVALIDATE); + todo_wine + ok(ret == NULLREGION, "got %d\n", ret); + ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE); + flush_events(); + flush_sequence(); + + ret = ScrollWindowEx(hwnd, 10, 10, NULL, NULL, NULL, NULL, + SW_SCROLLCHILDREN|SW_ERASE|SW_INVALIDATE); + todo_wine + ok(ret == NULLREGION, "got %d\n", ret); + ok_sequence(ScrollWindowExSeq, "ScrollWindowEx", TRUE); + flush_events(); + flush_sequence(); + ok(DestroyWindow(hchild), "failed to destroy window\n"); ok(DestroyWindow(hwnd), "failed to destroy window\n"); flush_sequence();
From: Dmitry Timoshkov dmitry@baikal.ru
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=37706 Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/user32/tests/msg.c | 4 +--- dlls/win32u/dce.c | 7 +++++-- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 5fa733be047..19d08196c1a 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -12992,15 +12992,13 @@ static void test_scrollwindowex(void)
ret = ScrollWindowEx(hwnd, 10, 10, &rect, NULL, NULL, NULL, SW_SCROLLCHILDREN|SW_ERASE|SW_INVALIDATE); - todo_wine ok(ret == NULLREGION, "got %d\n", ret); - ok_sequence(WmEmptySeq, "ScrollWindowEx", FALSE); + ok_sequence(WmEmptySeq, "ScrollWindowEx", TRUE); flush_events(); flush_sequence();
ret = ScrollWindowEx(hwnd, 10, 10, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN|SW_ERASE|SW_INVALIDATE); - todo_wine ok(ret == NULLREGION, "got %d\n", ret); ok_sequence(ScrollWindowExSeq, "ScrollWindowEx", TRUE); flush_events(); diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index 68de024c8b3..a26f5824738 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -2080,10 +2080,13 @@ INT WINAPI NtUserScrollWindowEx( HWND hwnd, INT dx, INT dy, const RECT *rect, rdw_flags = (flags & SW_ERASE) && (flags & SW_INVALIDATE) ? RDW_INVALIDATE | RDW_ERASE : RDW_INVALIDATE;
- if (!is_window_drawable( hwnd, TRUE )) return ERROR; hwnd = get_full_window_handle( hwnd );
- get_client_rect( hwnd, &rc, get_thread_dpi() ); + if (!is_window_drawable( hwnd, TRUE )) + SetRectEmpty( &rc ); + else + get_client_rect( hwnd, &rc, get_thread_dpi() ); + if (clip_rect) intersect_rect( &cliprc, &rc, clip_rect ); else cliprc = rc;
v2: Added a reference to a bug report.