Mostly to show that there is a WM_ACTIVATE message before WM_SYSCOMMAND SC_RESTORE and after WM_WINDOWPOSCHANGED
The Alt+Tab test won't work on non-Windows because the emulated key inputs doesn't reach the host, unless we required user interaction.
Signed-off-by: Zhiyi Zhang zzhang@codeweavers.com --- v2: SetActiveWindow only when restoring from iconic state and window is visible. v3: Add a test to verify message sequence. v4: Add DefWindowProcA test to compare results. Add explorer patch. Supersede 165927~165929
dlls/user32/tests/msg.c | 141 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 141 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index 6d0f0637ee..cf491ad1c0 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -15345,6 +15345,46 @@ static const struct message NCXBUTTONUPSeq2[] = { 0 } };
+/* DefWindowProcA(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0) to minimized visible window */ +static const struct message WmRestoreMinimizedOverlappedSeq[] = +{ + { HCBT_SYSCOMMAND, hook|wparam|lparam, SC_RESTORE, 0 }, + { HCBT_MINMAX, hook }, + { WM_QUERYOPEN, sent }, + { WM_GETTEXT, sent|optional }, + { WM_NCACTIVATE, sent|optional }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, + { WM_WINDOWPOSCHANGED, sent|optional }, + { WM_WINDOWPOSCHANGING, sent|optional }, + { WM_GETMINMAXINFO, sent|defwinproc }, + { WM_NCCALCSIZE, sent|optional }, + { WM_NCPAINT, sent|optional }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ERASEBKGND, sent|optional }, + { WM_WINDOWPOSCHANGED, sent|optional }, + { HCBT_ACTIVATE, hook }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE }, + { WM_ACTIVATEAPP, sent|wparam, TRUE }, + { WM_NCACTIVATE, sent|wparam, TRUE }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ACTIVATE, sent|wparam, TRUE }, + { HCBT_SETFOCUS, hook }, + { WM_SETFOCUS, sent|defwinproc }, + { WM_NCPAINT, sent }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ERASEBKGND, sent }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_FRAMECHANGED|SWP_STATECHANGED }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc }, + { WM_NCCALCSIZE, sent|optional }, + { WM_NCPAINT, sent|optional }, + { WM_ERASEBKGND, sent|optional }, + { WM_ACTIVATE, sent|wparam, TRUE }, + { WM_SYNCPAINT, sent|optional }, + { WM_PAINT, sent }, + { 0 } +}; + struct rbuttonup_thread_data { HWND hwnd; @@ -15399,6 +15439,15 @@ static void test_defwinproc(void) GetWindowTextA(hwnd, buffA, ARRAY_SIZE(buffA)); ok(!strcmp(buffA, "test_defwndproc"), "unexpected window text, %s\n", buffA);
+ ShowWindow(hwnd, SW_MINIMIZE); + flush_events(); + flush_sequence(); + + DefWindowProcA(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0); + flush_events(); + ok_sequence(WmRestoreMinimizedOverlappedSeq, "DefWindowProcA(SC_RESTORE):overlapped", TRUE); + flush_sequence(); + GetCursorPos(&pos); GetWindowRect(hwnd, &rect); x = (rect.left+rect.right) / 2; @@ -17522,6 +17571,97 @@ static void test_DoubleSetCapture(void) DestroyWindow(hwnd); }
+static const struct message WmRestoreMinimizedSeq[] = +{ + { HCBT_ACTIVATE, hook }, + { WM_WINDOWPOSCHANGING, sent|wparam, SWP_NOSIZE|SWP_NOMOVE }, + { WM_WINDOWPOSCHANGED, sent|wparam, SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE }, + { WM_ACTIVATEAPP, sent|wparam, 1 }, + { WM_NCACTIVATE, sent|wparam, 0x200001 }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ACTIVATE, sent|wparam, 0x200001 }, /* Note that activate messages are after WM_WINDOWPOSCHANGED and before WM_SYSCOMMAND */ + { HCBT_KEYSKIPPED, hook|optional }, + { WM_SYSKEYUP, sent|optional }, + { WM_SYSCOMMAND, sent|wparam, SC_RESTORE }, + { HCBT_SYSCOMMAND, hook|wparam, SC_RESTORE }, + { HCBT_SYSCOMMAND, hook|wparam|optional, SC_RESTORE }, + { HCBT_MINMAX, hook }, + { HCBT_MINMAX, hook|optional }, + { WM_QUERYOPEN, sent|defwinproc }, + { WM_QUERYOPEN, sent|optional }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_WINDOWPOSCHANGING, sent|wparam|defwinproc, SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, + { WM_GETMINMAXINFO, sent|defwinproc }, + { WM_NCCALCSIZE, sent|wparam|defwinproc, 1 }, + { WM_NCPAINT, sent|wparam|defwinproc|optional, 1 }, + { WM_GETTEXT, sent|defwinproc|optional }, + { WM_ERASEBKGND, sent|defwinproc }, + { WM_WINDOWPOSCHANGED, sent|wparam|defwinproc, SWP_FRAMECHANGED|SWP_NOCOPYBITS|SWP_STATECHANGED }, + { WM_MOVE, sent|defwinproc }, + { WM_SIZE, sent|defwinproc }, + { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, 1 }, + { WM_NCPAINT, sent|wparam|defwinproc|optional, 1 }, + { WM_ERASEBKGND, sent|defwinproc|optional }, + { HCBT_SETFOCUS, hook }, + { WM_SETFOCUS, sent|defwinproc }, + { WM_ACTIVATE, sent|wparam|defwinproc, 1 }, + { WM_PAINT, sent| optional }, + { WM_SETFOCUS, sent|defwinproc|optional }, + { HCBT_KEYSKIPPED, hook|optional }, + { WM_KEYUP, sent|optional }, + { HCBT_KEYSKIPPED, hook|optional }, + { WM_SYSKEYUP, sent|optional }, + { HCBT_KEYSKIPPED, hook|optional }, + { WM_KEYUP, sent|optional }, + { WM_PAINT, sent| optional }, + { 0 } +}; + +static void test_restore_messages(void) +{ + INPUT ip = {0}; + HWND hwnd; + INT i; + + hwnd = CreateWindowExA(0, "TestWindowClass", "Test overlapped", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 100, + 100, 200, 200, 0, 0, 0, NULL); + ok (hwnd != 0, "Failed to create overlapped window\n"); + SetForegroundWindow(hwnd); + ShowWindow(hwnd, SW_MINIMIZE); + flush_events(); + flush_sequence(); + + for (i = 0; i < 5; i++) + { + /* Send Alt+Tab to restore test window from minimized state */ + ip.type = INPUT_KEYBOARD; + ip.ki.wVk = VK_MENU; + SendInput(1, &ip, sizeof(INPUT)); + ip.ki.wVk = VK_TAB; + SendInput(1, &ip, sizeof(INPUT)); + ip.ki.wVk = VK_MENU; + ip.ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(1, &ip, sizeof(INPUT)); + ip.ki.wVk = VK_TAB; + ip.ki.dwFlags = KEYEVENTF_KEYUP; + SendInput(1, &ip, sizeof(INPUT)); + flush_events(); + if (!IsIconic(hwnd)) + break; + Sleep(500); + } + + if (IsIconic(hwnd)) + { + skip("Alt+Tab failed to bring up test window.\n"); + goto done; + } + ok_sequence(WmRestoreMinimizedSeq, "Restore minimized window", TRUE); + +done: + DestroyWindow(hwnd); +} + static void init_funcs(void) { HMODULE hKernel32 = GetModuleHandleA("kernel32.dll"); @@ -17646,6 +17786,7 @@ START_TEST(msg) test_quit_message(); test_notify_message(); test_SetActiveWindow(); + test_restore_messages();
if (!pTrackMouseEvent) win_skip("TrackMouseEvent is not available\n");
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=53307
Your paranoid android.
=== wvistau64_zh_CN (32 bit report) ===
user32: msg.c:5139: Test failed: ShowWindow(SW_RESTORE):overlapped: 18: the msg sequence is not complete: expected 0000 - actual 0088
=== w1064v1809 (32 bit report) ===
user32: msg.c:9334: Test failed: Shift+MouseButton press/release: 7: the msg 0x0202 was expected, but got msg 0x0007 instead msg.c:9334: Test failed: Shift+MouseButton press/release: 8: the msg 0x0202 was expected, but got msg 0x0101 instead msg.c:9334: Test failed: Shift+MouseButton press/release: 10: the msg 0x0101 should have been sent msg.c:9334: Test failed: Shift+MouseButton press/release: 11: the msg 0x0101 was expected, but got msg 0x0202 instead msg.c:9334: Test failed: Shift+MouseButton press/release: 12: the msg sequence is not complete: expected 0000 - actual 0202 msg.c:10207: Test failed: did not get expected count for minimum timeout (54 != ~100).
=== debian9 (32 bit French report) ===
user32: msg.c:8713: Test failed: WaitForSingleObject failed 102 msg.c:8719: Test failed: destroy child on thread exit: 0: the msg 0x0082 was expected, but got msg 0x000f instead msg.c:8719: Test failed: destroy child on thread exit: 1: the msg 0x000f was expected, but got msg 0x0014 instead msg.c:8719: Test failed: destroy child on thread exit: 2: the msg sequence is not complete: expected 0014 - actual 0000