d3d9/tests: Test focus loss message filtering in d3d9ex.

This commit is contained in:
Stefan Dösinger 2014-12-04 21:51:43 +01:00 committed by Alexandre Julliard
parent 36553d862b
commit 0c55b9d2b3
1 changed files with 54 additions and 17 deletions

View File

@ -1723,8 +1723,9 @@ struct message
WPARAM expect_wparam; WPARAM expect_wparam;
}; };
static const struct message *expect_messages, *unexpected_messages; static const struct message *expect_messages;
static HWND device_window, focus_window; static HWND device_window, focus_window;
static BOOL windowposchanged_received;
struct wndproc_thread_param struct wndproc_thread_param
{ {
@ -1772,12 +1773,12 @@ static LRESULT CALLBACK test_proc(HWND hwnd, UINT message, WPARAM wparam, LPARAM
} }
} }
if (unexpected_messages) /* KDE randomly does something with the hidden window during the
{ * mode change that sometimes generates a WM_WINDOWPOSCHANGING
const struct message *i; * message. A WM_WINDOWPOSCHANGED message is not generated, so
for (i = unexpected_messages; i->message; i++) * just flag WM_WINDOWPOSCHANGED as bad. */
ok(i->message != message, "Got unexpected message %x on window %p.\n", message, hwnd); if (message == WM_WINDOWPOSCHANGED)
} windowposchanged_received = TRUE;
return DefWindowProcA(hwnd, message, wparam, lparam); return DefWindowProcA(hwnd, message, wparam, lparam);
} }
@ -1887,24 +1888,26 @@ static void test_wndproc(void)
{WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE}, {WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
{0, 0, FALSE, 0}, {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 /* WM_ACTIVATE is delivered to the window proc because it is
* mode change that sometimes generates a WM_WINDOWPOSCHANGING * generated by SetForegroundWindow before the d3d routine
* message. A WM_WINDOWPOSCHANGED message is not generated, so * starts it work. Don't check for it due to focus-follows-mouse
* just flag WM_WINDOWPOSCHANGED as bad. */ * WMs though. */
{WM_WINDOWPOSCHANGED, 0, FALSE, 0}, {WM_DISPLAYCHANGE, FOCUS_WINDOW, FALSE, 0},
{WM_ACTIVATEAPP, FOCUS_WINDOW, TRUE, FALSE},
{0, 0, FALSE, 0}, {0, 0, FALSE, 0},
}; };
static const struct static const struct
{ {
DWORD create_flags; DWORD create_flags;
const struct message *focus_loss_messages; const struct message *focus_loss_messages;
BOOL iconic;
} }
tests[] = tests[] =
{ {
{0, focus_loss_messages}, {0, focus_loss_messages, TRUE},
{CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc}, {CREATE_DEVICE_NOWINDOWCHANGES, focus_loss_messages_nowc, FALSE},
}; };
hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex); hr = pDirect3DCreate9Ex(D3D_SDK_VERSION, &d3d9ex);
@ -2122,12 +2125,12 @@ static void test_wndproc(void)
flush_events(); flush_events();
expect_messages = focus_loss_messages_hidden; expect_messages = focus_loss_messages_hidden;
unexpected_messages = focus_loss_messages_hidden_unexpected; windowposchanged_received = FALSE;
SetForegroundWindow(GetDesktopWindow()); SetForegroundWindow(GetDesktopWindow());
ok(!expect_messages->message, "Expected message %#x for window %#x, but didn't receive it, i=%u.\n", 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); 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; expect_messages = NULL;
unexpected_messages = NULL;
ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode); ret = EnumDisplaySettingsW(NULL, ENUM_CURRENT_SETTINGS, &devmode);
ok(ret, "Failed to get display mode.\n"); 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", ok(proc == (LONG_PTR)test_proc, "Expected wndproc %#lx, got %#lx, i=%u.\n",
(LONG_PTR)test_proc, proc, i); (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; device_desc.device_window = focus_window;
if (!(device = create_device(focus_window, &device_desc))) if (!(device = create_device(focus_window, &device_desc)))
{ {
skip("Failed to create a D3D device, skipping tests.\n"); skip("Failed to create a D3D device, skipping tests.\n");
goto done; 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); ref = IDirect3DDevice9Ex_Release(device);
ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i); ok(ref == 0, "The device was not properly freed: refcount %u, i=%u.\n", ref, i);