[PATCH 2/6] user32/tests: Test a recursive activation loop on WM_ACTIVATE
Gabriel Ivăncescu
gabrielopcode at gmail.com
Mon Jan 28 06:34:15 CST 2019
Windows only sends the activation messages and hooks once, until the
SetActiveWindow completes for that window.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---
Note that without the prior patch that fixes this, Wine would enter a long
loop here.
dlls/user32/tests/msg.c | 81 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 366a138..3d9c0b7 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -4772,6 +4772,39 @@ static void test_showwindow(void)
flush_sequence();
}
+static void test_recursive_activation(void)
+{
+ static const struct message seq[] =
+ {
+ { HCBT_ACTIVATE, hook },
+ { WM_NCACTIVATE, sent|wparam, TRUE },
+ { WM_ACTIVATE, sent|wparam, WA_ACTIVE },
+ { HCBT_ACTIVATE, hook },
+ { WM_NCACTIVATE, sent|wparam, FALSE },
+ { WM_ACTIVATE, sent|wparam, WA_INACTIVE },
+ { WM_SETFOCUS, sent|optional },
+ { 0 }
+ };
+ HWND hwnd, recursive;
+
+ hwnd = CreateWindowExA(0, "SimpleWindowClass", NULL, WS_OVERLAPPED|WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok(hwnd != 0, "Failed to create simple window\n");
+
+ recursive = CreateWindowExA(0, "RecursiveActivationClass", NULL, WS_OVERLAPPED|WS_VISIBLE,
+ 10, 10, 50, 50, hwnd, 0, 0, NULL);
+ ok(recursive != 0, "Failed to create recursive activation window\n");
+ SetActiveWindow(hwnd);
+
+ flush_sequence();
+ SetActiveWindow(recursive);
+ ok_sequence(seq, "Recursive Activation", FALSE);
+
+ DestroyWindow(recursive);
+ DestroyWindow(hwnd);
+ flush_sequence();
+}
+
static void test_sys_menu(void)
{
HWND hwnd;
@@ -9699,6 +9732,48 @@ static LRESULT WINAPI ShowWindowProcA(HWND hwnd, UINT message, WPARAM wParam, LP
return ret;
}
+static LRESULT WINAPI recursive_activation_wndprocA(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ static LONG defwndproc_counter = 0;
+ struct recvd_message msg;
+ LRESULT ret;
+
+ switch (message)
+ {
+ /* log only specific messages we are interested in */
+ case WM_NCACTIVATE:
+ case WM_ACTIVATE:
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
+ break;
+ default:
+ return DefWindowProcA(hwnd, message, wParam, lParam);
+ }
+
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.flags = sent|wparam|lparam;
+ if (defwndproc_counter) msg.flags |= defwinproc;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.descr = "recursive_activation";
+ add_message(&msg);
+
+ /* recursively activate ourselves by first losing activation and changing it back */
+ if (message == WM_ACTIVATE && LOWORD(wParam) != WA_INACTIVE)
+ {
+ SetActiveWindow((HWND)lParam);
+ SetActiveWindow(hwnd);
+ return 0;
+ }
+
+ defwndproc_counter++;
+ ret = DefWindowProcA(hwnd, message, wParam, lParam);
+ defwndproc_counter--;
+
+ return ret;
+}
+
static LRESULT WINAPI PaintLoopProcA(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
@@ -9796,6 +9871,10 @@ static BOOL RegisterWindowClasses(void)
cls.lpszClassName = "ShowWindowClass";
if(!RegisterClassA(&cls)) return FALSE;
+ cls.lpfnWndProc = recursive_activation_wndprocA;
+ cls.lpszClassName = "RecursiveActivationClass";
+ if(!RegisterClassA(&cls)) return FALSE;
+
cls.lpfnWndProc = PopupMsgCheckProcA;
cls.lpszClassName = "TestPopupClass";
if(!RegisterClassA(&cls)) return FALSE;
@@ -9851,6 +9930,7 @@ static BOOL is_our_logged_class(HWND hwnd)
{
if (!lstrcmpiA(buf, "TestWindowClass") ||
!lstrcmpiA(buf, "ShowWindowClass") ||
+ !lstrcmpiA(buf, "RecursiveActivationClass") ||
!lstrcmpiA(buf, "TestParentClass") ||
!lstrcmpiA(buf, "TestPopupClass") ||
!lstrcmpiA(buf, "SimpleWindowClass") ||
@@ -17617,6 +17697,7 @@ START_TEST(msg)
test_messages();
test_setwindowpos();
test_showwindow();
+ test_recursive_activation();
invisible_parent_tests();
test_mdi_messages();
test_button_messages();
--
2.19.1
More information about the wine-devel
mailing list