[PATCH 2/8] d3d9/tests: Test focus loss message filtering in d3d9ex.

Stefan Dösinger stefan at codeweavers.com
Thu Dec 4 03:36:28 CST 2014


---
 dlls/d3d9/tests/d3d9ex.c | 71 ++++++++++++++++++++++++++++++++++++------------
 1 file changed, 54 insertions(+), 17 deletions(-)

diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
index 0ac9db7..e207405 100644
--- a/dlls/d3d9/tests/d3d9ex.c
+++ b/dlls/d3d9/tests/d3d9ex.c
@@ -1723,8 +1723,9 @@ struct message
     WPARAM expect_wparam;
 };
 
-static const struct message *expect_messages, *unexpected_messages;
+static const struct message *expect_messages;
 static HWND device_window, focus_window;
+static BOOL windowposchanged_received;
 
 struct wndproc_thread_param
 {
@@ -1772,12 +1773,12 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM
         }
     }
 
-    if (unexpected_messages)
-    {
-        const struct message *i;
-        for (i = unexpected_messages; i->message; i++)
-            ok(i->message != message, "Got unexpected message %x on window %p.\n", message, hwnd);
-    }
+    /* KDE randomly does something with the hidden window during the
+     * mode change that sometimes generates a WM_WINDOWPOSCHANGING
+     * message. A WM_WINDOWPOSCHANGED message is not generated, so
+     * just flag WM_WINDOWPOSCHANGED as bad. */
+    if (message == WM_WINDOWPOSCHANGED)
+        windowposchanged_received = TRUE;
 
     return DefWindowProcA(hwnd, message, wparam, lparam);
 }
@@ -1887,24 +1888,26 @@ static void test_wndproc(void)
         {WM_ACTIVATEAPP,        FOCUS_WINDOW,   TRUE,   FALSE},
         {0,                     0,              FALSE,  0},
     };
-    static const struct message focus_loss_messages_hidden_unexpected[] =
+    static const struct message focus_loss_messages_filtered[] =
     {
-        /* KDE randomly does something with the hidden window during the
-         * mode change that sometimes generates a WM_WINDOWPOSCHANGING
-         * message. A WM_WINDOWPOSCHANGED message is not generated, so
-         * just flag WM_WINDOWPOSCHANGED as bad. */
-        {WM_WINDOWPOSCHANGED,   0,              FALSE,  0},
+        /* WM_ACTIVATE is delivered to the window proc because it is
+         * generated by SetForegroundWindow before the d3d routine
+         * starts it work. Don't check for it due to focus-follows-mouse
+         * WMs though. */
+        {WM_DISPLAYCHANGE,      FOCUS_WINDOW,   FALSE,  0},
+        {WM_ACTIVATEAPP,        FOCUS_WINDOW,   TRUE,   FALSE},
         {0,                     0,              FALSE,  0},
     };
     static const struct
     {
         DWORD create_flags;
         const struct message *focus_loss_messages;
+        BOOL iconic;
     }
     tests[] =
     {
-        {0,                               focus_loss_messages},
-        {CREATE_DEVICE_NOWINDOWCHANGES,   focus_loss_messages_nowc},
+        {0,                               focus_loss_messages,          TRUE},
+        {CREATE_DEVICE_NOWINDOWCHANGES,   focus_loss_messages_nowc,     FALSE},
     };
 
     hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
@@ -2122,12 +2125,12 @@ static void test_wndproc(void)
         flush_events();
 
         expect_messages = focus_loss_messages_hidden;
-        unexpected_messages = focus_loss_messages_hidden_unexpected;
+        windowposchanged_received = FALSE;
         SetForegroundWindow(GetDesktopWindow());
         ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
                 expect_messages->message, expect_messages->window, i);
+        ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
         expect_messages = NULL;
-        unexpected_messages = NULL;
 
         ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
         ok(ret, "Failed to get display mode.\n");
@@ -2152,13 +2155,47 @@ static void test_wndproc(void)
         ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
                 (LONG_PTR)test_proc, proc, i);
 
+        /* Hide the device window. It prevents WM_ACTIVATEAPP messages from being sent
+         * on native in the test below. It isn't needed anyways. Creating the third
+         * device will show it again. */
+        filter_messages = NULL;
+        ShowWindow(device_window, SW_HIDE);
+        filter_messages = focus_window;
+
         device_desc.device_window = focus_window;
         if (!(device = create_device(focus_window, &device_desc)))
         {
             skip("Failed to create a D3D device, skipping tests.\n");
             goto done;
         }
+        filter_messages = NULL;
+        SetForegroundWindow(focus_window); /* For KDE. */
+        flush_events();
+
+        expect_messages = focus_loss_messages_filtered;
+        windowposchanged_received = FALSE;
+        SetForegroundWindow(GetDesktopWindow());
+        ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
+                expect_messages->message, expect_messages->window, i);
+        if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
+            ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
+        else
+            todo_wine ok(!windowposchanged_received, "Received WM_WINDOWPOSCHANGED but did not expect it, i=%u.\n", i);
+        expect_messages = NULL;
+
+        /* The window is iconic even though no message was sent. */
+        ok(!IsIconic(focus_window) == !tests[i].iconic,
+                "Expected IsIconic %u, got %u, i=%u.\n", tests[i].iconic, IsIconic(focus_window), i);
 
+        /* This test can't activate, drop focus and restore focus like in plain d3d9 because d3d9ex
+         * immediately restores the device on activation. There are plenty of WM_WINDOWPOSCHANGED
+         * messages that are generated by ShowWindow, so testing for their absence is pointless. */
+        ShowWindow(focus_window, SW_MINIMIZE);
+        ShowWindow(focus_window, SW_RESTORE);
+        SetForegroundWindow(focus_window);
+        flush_events();
+
+        filter_messages = focus_window;
         ref = IDirect3DDevice9Ex_Release(device);
         ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);
 
-- 
2.0.4




More information about the wine-patches mailing list