[PATCH 2/2] d3d/tests: Show that WM_SYSCOMMAND(SC_RESTORE) is delivered only once.

Stefan Dösinger stefan at codeweavers.com
Mon Jan 26 09:03:57 CST 2015


This single delivery happens after d3d already passed the message to
DefWindowProc. Thus there is no way our wndproc can prevent d3d8/9 from
handling it.

I don't think this check is strictly necessary since our wndproc doesn't
do anything with WM_SYSCOMMAND that might cause d3d9 to think we did not
handle it. Still with the existing test code it is theoretically
possible that the message is delivered before the messages generated by
DefWindowProc arrive and then a second time after d3d9 is done handling
it.

I am using InterlockedIncrement because the same wndproc is used for the
third test window that is controlled by a different thread. I changed
windowposchanged_received for consistency.

At some point we may consider porting ok_sequence() from
dlls/user32/tests/msg.c to the d3d tests, but right now I think this is
overkill and we are better served with the two counters.
---
 dlls/d3d8/tests/device.c | 19 +++++++++++++++----
 dlls/d3d9/tests/d3d9ex.c | 19 +++++++++++++++----
 dlls/d3d9/tests/device.c | 21 ++++++++++++++++-----
 3 files changed, 46 insertions(+), 13 deletions(-)

diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index 235dc73..b75513e 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -2183,7 +2183,7 @@ struct message
 
 static const struct message *expect_messages;
 static HWND device_window, focus_window;
-static BOOL windowposchanged_received;
+static LONG windowposchanged_received, syscommand_received;
 
 struct wndproc_thread_param
 {
@@ -2236,7 +2236,9 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM
      * message. A WM_WINDOWPOSCHANGED message is not generated, so
      * just flag WM_WINDOWPOSCHANGED as bad. */
     if (message == WM_WINDOWPOSCHANGED)
-        windowposchanged_received = TRUE;
+        InterlockedIncrement(&windowposchanged_received);
+    else if (message == WM_SYSCOMMAND)
+        InterlockedIncrement(&syscommand_received);
 
     return DefWindowProcA(hwnd, message, wparam, lparam);
 }
@@ -2362,6 +2364,11 @@ static void test_wndproc(void)
     };
     static const struct message sc_restore_messages[] =
     {
+        /* WM_SYSCOMMAND is delivered only once, after d3d has already
+         * processed it. Our wndproc has no way to prevent d3d from
+         * handling the message. The second DefWindowProc call done by
+         * our wndproc doesn't do any changes to the window because it
+         * is already restored due to d3d's handling. */
         {WM_WINDOWPOSCHANGING,  FOCUS_WINDOW,   FALSE,  0},
         {WM_WINDOWPOSCHANGED,   FOCUS_WINDOW,   FALSE,  0},
         {WM_SIZE,               FOCUS_WINDOW,   TRUE,   SIZE_RESTORED},
@@ -2601,7 +2608,7 @@ static void test_wndproc(void)
     flush_events();
 
     expect_messages = focus_loss_messages_hidden;
-    windowposchanged_received = FALSE;
+    windowposchanged_received = 0;
     SetForegroundWindow(GetDesktopWindow());
     ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
             expect_messages->message, expect_messages->window);
@@ -2620,10 +2627,12 @@ static void test_wndproc(void)
     ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
     flush_events();
 
+    syscommand_received = 0;
     expect_messages = sc_restore_messages;
     SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
     ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
             expect_messages->message, expect_messages->window);
+    ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
     expect_messages = NULL;
     flush_events();
 
@@ -2684,7 +2693,7 @@ static void test_wndproc(void)
     filter_messages = NULL;
 
     expect_messages = focus_loss_messages_filtered;
-    windowposchanged_received = FALSE;
+    windowposchanged_received = 0;
     SetForegroundWindow(GetDesktopWindow());
     ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
             expect_messages->message, expect_messages->window);
@@ -2697,10 +2706,12 @@ static void test_wndproc(void)
     hr = IDirect3DDevice8_TestCooperativeLevel(device);
     ok(hr == D3DERR_DEVICELOST, "Got unexpected hr %#x.\n", hr);
 
+    syscommand_received = 0;
     expect_messages = sc_restore_messages;
     SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
     ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it.\n",
             expect_messages->message, expect_messages->window);
+    ok(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
     expect_messages = NULL;
     flush_events();
 
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
index 106bc3e..1d16ccf 100644
--- a/dlls/d3d9/tests/d3d9ex.c
+++ b/dlls/d3d9/tests/d3d9ex.c
@@ -1725,7 +1725,7 @@ struct message
 
 static const struct message *expect_messages;
 static HWND device_window, focus_window;
-static BOOL windowposchanged_received;
+static LONG windowposchanged_received, syscommand_received;
 
 struct wndproc_thread_param
 {
@@ -1778,7 +1778,9 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM
      * message. A WM_WINDOWPOSCHANGED message is not generated, so
      * just flag WM_WINDOWPOSCHANGED as bad. */
     if (message == WM_WINDOWPOSCHANGED)
-        windowposchanged_received = TRUE;
+        InterlockedIncrement(&windowposchanged_received);
+    else if (message == WM_SYSCOMMAND)
+        InterlockedIncrement(&syscommand_received);
 
     return DefWindowProcA(hwnd, message, wparam, lparam);
 }
@@ -1900,6 +1902,11 @@ static void test_wndproc(void)
     };
     static const struct message sc_restore_messages[] =
     {
+        /* WM_SYSCOMMAND is delivered only once, after d3d has already
+         * processed it. Our wndproc has no way to prevent d3d from
+         * handling the message. The second DefWindowProc call done by
+         * our wndproc doesn't do any changes to the window because it
+         * is already restored due to d3d's handling. */
         {WM_WINDOWPOSCHANGING,  FOCUS_WINDOW,   FALSE,  0},
         {WM_WINDOWPOSCHANGED,   FOCUS_WINDOW,   FALSE,  0},
         {WM_SIZE,               FOCUS_WINDOW,   TRUE,   SIZE_RESTORED},
@@ -2151,7 +2158,7 @@ static void test_wndproc(void)
         flush_events();
 
         expect_messages = focus_loss_messages_hidden;
-        windowposchanged_received = FALSE;
+        windowposchanged_received = 0;
         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);
@@ -2170,10 +2177,12 @@ static void test_wndproc(void)
         ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
         flush_events();
 
+        syscommand_received = 0;
         expect_messages = sc_restore_messages;
         SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
         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(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
         expect_messages = NULL;
         flush_events();
 
@@ -2232,7 +2241,7 @@ static void test_wndproc(void)
         flush_events();
 
         expect_messages = focus_loss_messages_filtered;
-        windowposchanged_received = FALSE;
+        windowposchanged_received = 0;
         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);
@@ -2247,10 +2256,12 @@ static void test_wndproc(void)
         ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
         flush_events();
 
+        syscommand_received = 0;
         expect_messages = sc_restore_messages;
         SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
         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(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
         expect_messages = NULL;
         flush_events();
 
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 6cf4a81..b11d8d45 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -3137,7 +3137,7 @@ struct message
 
 static const struct message *expect_messages;
 static HWND device_window, focus_window;
-static BOOL windowposchanged_received;
+static LONG windowposchanged_received, syscommand_received;
 
 struct wndproc_thread_param
 {
@@ -3190,7 +3190,9 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM
      * message. A WM_WINDOWPOSCHANGED message is not generated, so
      * just flag WM_WINDOWPOSCHANGED as bad. */
     if (message == WM_WINDOWPOSCHANGED)
-        windowposchanged_received = TRUE;
+        InterlockedIncrement(&windowposchanged_received);
+    else if (message == WM_SYSCOMMAND)
+        InterlockedIncrement(&syscommand_received);
 
     return DefWindowProcA(hwnd, message, wparam, lparam);
 }
@@ -3330,6 +3332,11 @@ static void test_wndproc(void)
     };
     static const struct message sc_restore_messages[] =
     {
+        /* WM_SYSCOMMAND is delivered only once, after d3d has already
+         * processed it. Our wndproc has no way to prevent d3d from
+         * handling the message. The second DefWindowProc call done by
+         * our wndproc doesn't do any changes to the window because it
+         * is already restored due to d3d's handling. */
         {WM_WINDOWPOSCHANGING,  FOCUS_WINDOW,   FALSE,  0},
         {WM_WINDOWPOSCHANGED,   FOCUS_WINDOW,   FALSE,  0},
         {WM_SIZE,               FOCUS_WINDOW,   TRUE,   SIZE_RESTORED},
@@ -3585,7 +3592,7 @@ static void test_wndproc(void)
         flush_events();
 
         expect_messages = focus_loss_messages_hidden;
-        windowposchanged_received = FALSE;
+        windowposchanged_received = 0;
         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);
@@ -3604,10 +3611,12 @@ static void test_wndproc(void)
         ShowWindow(focus_window, SW_SHOWMINNOACTIVE);
         flush_events();
 
+        syscommand_received = 0;
         expect_messages = sc_restore_messages;
         SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
         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(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
         expect_messages = NULL;
         flush_events();
 
@@ -3671,7 +3680,7 @@ static void test_wndproc(void)
         flush_events();
 
         expect_messages = focus_loss_messages_filtered;
-        windowposchanged_received = FALSE;
+        windowposchanged_received = 0;
         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);
@@ -3688,10 +3697,12 @@ static void test_wndproc(void)
         if (tests[i].create_flags & CREATE_DEVICE_NOWINDOWCHANGES)
             ShowWindow(focus_window, SW_MINIMIZE);
 
+        syscommand_received = 0;
         expect_messages = sc_restore_messages;
         SendMessageA(focus_window, WM_SYSCOMMAND, SC_RESTORE, 0);
         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(syscommand_received == 1, "Got unexpected number of WM_SYSCOMMAND messages: %d.\n", syscommand_received);
         expect_messages = NULL;
         flush_events();
 
@@ -3721,7 +3732,7 @@ static void test_wndproc(void)
         flush_events();
 
         expect_messages = reactivate_messages_filtered;
-        windowposchanged_received = FALSE;
+        windowposchanged_received = 0;
         SetForegroundWindow(focus_window);
         flush_events();
         ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n",
-- 
2.0.5




More information about the wine-patches mailing list