[PATCH v7 4/6] d3d8/tests: Test for window changes when it's not foreground.

Gabriel Ivăncescu gabrielopcode at gmail.com
Tue Jan 18 10:50:28 CST 2022


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

Minimizing/restoring and setting foreground twice + waiting for thread msgs
seems to work in all cases for testing, both on native and wine.

 dlls/d3d8/tests/device.c | 289 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 289 insertions(+)

diff --git a/dlls/d3d8/tests/device.c b/dlls/d3d8/tests/device.c
index fc94dca..b565bc4 100644
--- a/dlls/d3d8/tests/device.c
+++ b/dlls/d3d8/tests/device.c
@@ -3935,16 +3935,50 @@ cleanup:
     DestroyWindow(hwnd);
 }
 
+struct create_window_thread_params
+{
+    HANDLE event;
+    HWND hwnd;
+};
+
+static DWORD WINAPI create_window_thread(void *data)
+{
+    struct create_window_thread_params *params = data;
+    HWND hwnd;
+    MSG msg;
+
+    hwnd = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            10, 20, 30, 40, 0, 0, 0, 0);
+    ok(!!hwnd, "Failed to create window.\n");
+    flush_events();
+    params->hwnd = hwnd;
+    SetEvent(params->event);
+    while (GetMessageA(&msg, 0, 0, 0))
+    {
+        TranslateMessage(&msg);
+        DispatchMessageA(&msg);
+        if (!params->hwnd)
+            break;
+    }
+    DestroyWindow(hwnd);
+    return 0;
+}
+
 static void test_window_style(void)
 {
+    struct create_window_thread_params thread_params;
     RECT focus_rect, fullscreen_rect, r;
     LONG device_style, device_exstyle;
     LONG focus_style, focus_exstyle;
     struct device_desc device_desc;
     LONG style, expected_style;
     IDirect3DDevice8 *device;
+    HWND active_window;
     IDirect3D8 *d3d8;
+    DWORD_PTR result;
+    HANDLE thread;
     HRESULT hr;
+    DWORD tid;
     ULONG ref;
     BOOL ret;
 
@@ -4055,6 +4089,261 @@ static void test_window_style(void)
 
     ref = IDirect3DDevice8_Release(device);
     ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
+    DestroyWindow(device_window);
+    DestroyWindow(focus_window);
+
+    /* Window changes are done only if the current process has the foreground window at creation */
+    focus_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+    device_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+    active_window = CreateWindowA("static", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            10, 20, 30, 40, 0, 0, 0, 0);
+
+    device_style = GetWindowLongA(device_window, GWL_STYLE);
+    device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
+    focus_style = GetWindowLongA(focus_window, GWL_STYLE);
+    focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
+
+    ret = SetForegroundWindow(active_window);
+    ok(ret, "Failed to set foreground window.\n");
+    ok(GetActiveWindow() == active_window, "Unexpected active window.\n");
+
+    device_desc.device_window = device_window;
+    device_desc.flags = CREATE_DEVICE_FULLSCREEN;
+    device = create_device(d3d8, focus_window, &device_desc);
+    ok(!!device, "Failed to create a D3D device.\n");
+
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    expected_style = device_exstyle | WS_EX_TOPMOST;
+    todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", expected_style, style);
+
+    style = GetWindowLongA(focus_window, GWL_STYLE);
+    ok(style == focus_style, "Expected focus window style %#x, got %#x.\n", focus_style, style);
+    style = GetWindowLongA(focus_window, GWL_EXSTYLE);
+    ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n", focus_exstyle, style);
+
+    device_desc.flags = 0;
+    hr = reset_device(device, &device_desc);
+    ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
+
+    ret = SetForegroundWindow(GetDesktopWindow());
+    ok(ret, "Failed to set foreground window.\n");
+    device_desc.flags = CREATE_DEVICE_FULLSCREEN;
+    hr = reset_device(device, &device_desc);
+    ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
+    ShowWindow(device_window, SW_SHOWNOACTIVATE);
+
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    expected_style = device_exstyle | WS_EX_TOPMOST;
+    todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", expected_style, style);
+    GetWindowRect(device_window, &r);
+    ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n", wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
+
+    ref = IDirect3DDevice8_Release(device);
+    ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
+    DestroyWindow(active_window);
+    DestroyWindow(device_window);
+    DestroyWindow(focus_window);
+
+    focus_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+    device_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+
+    device_style = GetWindowLongA(device_window, GWL_STYLE);
+    device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
+    focus_style = GetWindowLongA(focus_window, GWL_STYLE);
+    focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
+
+    thread_params.hwnd = NULL;
+    thread_params.event = CreateEventW(NULL, 0, 0, NULL);
+    ok(!!thread_params.event, "Failed to create event.\n");
+    thread = CreateThread(NULL, 0, create_window_thread, &thread_params, 0, &tid);
+    ok(!!thread, "Failed to create thread.\n");
+    ok(WaitForSingleObject(thread_params.event, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed.\n");
+    ok(!!thread_params.hwnd, "Failed to create window in another thread.\n");
+    CloseHandle(thread_params.event);
+
+    /* Minimize and restore the other thread's window, otherwise native fails to
+       set the foreground window to it, even if it's done from the thread itself. */
+    ShowWindow(thread_params.hwnd, SW_MINIMIZE);
+    ShowWindow(thread_params.hwnd, SW_RESTORE);
+    /* Set focus twice to make KDE and fvwm in focus-follows-mouse mode happy. */
+    SetForegroundWindow(thread_params.hwnd);
+    flush_events();
+    SetForegroundWindow(thread_params.hwnd);
+    flush_events();
+    /* Wait for thread to process all related messages */
+    SendMessageTimeoutW(thread_params.hwnd, WM_NULL, 0, 0, 0, 2000, &result);
+
+    SetActiveWindow(NULL);
+    ok(GetForegroundWindow() == thread_params.hwnd, "Unexpected foreground window.\n");
+
+    device_desc.device_window = device_window;
+    device_desc.flags = CREATE_DEVICE_FULLSCREEN;
+    device = create_device(d3d8, focus_window, &device_desc);
+    ok(!!device, "Failed to create a D3D device.\n");
+
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    expected_style = device_exstyle | WS_EX_TOPMOST;
+    todo_wine ok(style == expected_style || broken(style == (expected_style & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", expected_style, style);
+
+    style = GetWindowLongA(focus_window, GWL_STYLE);
+    ok(style == focus_style, "Expected focus window style %#x, got %#x.\n", focus_style, style);
+    style = GetWindowLongA(focus_window, GWL_EXSTYLE);
+    ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n", focus_exstyle, style);
+
+    ref = IDirect3DDevice8_Release(device);
+    ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
+    thread_params.hwnd = NULL;
+    PostThreadMessageW(tid, WM_NULL, 0, 0);
+    DestroyWindow(device_window);
+    DestroyWindow(focus_window);
+    ok(WaitForSingleObject(thread, INFINITE) == WAIT_OBJECT_0, "WaitForSingleObject failed.\n");
+    CloseHandle(thread);
+
+    focus_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+    device_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+
+    device_style = GetWindowLongA(device_window, GWL_STYLE);
+    device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
+    focus_style = GetWindowLongA(focus_window, GWL_STYLE);
+    focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
+
+    ret = SetForegroundWindow(GetDesktopWindow());
+    ok(ret, "Failed to set foreground window.\n");
+    SetActiveWindow(focus_window);
+    ok(GetActiveWindow() == focus_window, "Unexpected active window.\n");
+
+    device_desc.device_window = device_window;
+    device_desc.flags = CREATE_DEVICE_FULLSCREEN;
+    device = create_device(d3d8, focus_window, &device_desc);
+    ok(!!device, "Failed to create a D3D device.\n");
+    ShowWindow(device_window, SW_SHOWNOACTIVATE);
+
+    /* Windows 8 and some versions of Windows 10 have some pretty
+       inconsistent behavior but topmost is set even when inactive. */
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    if (broken(style & WS_EX_TOPMOST))
+    {
+        win_skip("topmost set when inactive due to inconsistent behavior, skipping related tests...\n");
+        goto skip_inactive;
+    }
+    todo_wine ok(style == device_exstyle || broken(style == (device_exstyle & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", device_exstyle, style);
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+
+    style = GetWindowLongA(focus_window, GWL_STYLE);
+    ok(style == focus_style, "Expected focus window style %#x, got %#x.\n", focus_style, style);
+    style = GetWindowLongA(focus_window, GWL_EXSTYLE);
+    ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n", focus_exstyle, style);
+
+    device_desc.flags = 0;
+    hr = reset_device(device, &device_desc);
+    ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
+
+    ret = SetForegroundWindow(GetDesktopWindow());
+    ok(ret, "Failed to set foreground window.\n");
+    SetActiveWindow(focus_window);
+    ok(GetActiveWindow() == focus_window, "Unexpected active window.");
+    device_desc.flags = CREATE_DEVICE_FULLSCREEN;
+    hr = reset_device(device, &device_desc);
+    ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
+
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    todo_wine ok(style == device_exstyle || broken(style == (device_exstyle & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", device_exstyle, style);
+    GetWindowRect(device_window, &r);
+    ok(EqualRect(&r, &fullscreen_rect), "Expected %s, got %s.\n", wine_dbgstr_rect(&fullscreen_rect), wine_dbgstr_rect(&r));
+
+    SetForegroundWindow(focus_window);
+    ok(ret, "Failed to set foreground window.\n");
+    hr = reset_device(device, &device_desc);
+    ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
+
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    todo_wine ok(style == device_exstyle || broken(style == (device_exstyle & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", device_exstyle, style);
+
+    device_desc.flags = 0;
+    hr = reset_device(device, &device_desc);
+    ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
+
+    device_desc.flags = CREATE_DEVICE_FULLSCREEN;
+    hr = reset_device(device, &device_desc);
+    ok(SUCCEEDED(hr), "Failed to reset device, hr %#x.\n", hr);
+
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    todo_wine ok(style == device_exstyle || broken(style == (device_exstyle & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", device_exstyle, style);
+
+    ref = IDirect3DDevice8_Release(device);
+    ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
+    DestroyWindow(device_window);
+    DestroyWindow(focus_window);
+
+    focus_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+    device_window = CreateWindowA("d3d8_test_wc", "d3d8_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+            0, 0, registry_mode.dmPelsWidth / 2, registry_mode.dmPelsHeight / 2, 0, 0, 0, 0);
+
+    device_style = GetWindowLongA(device_window, GWL_STYLE);
+    device_exstyle = GetWindowLongA(device_window, GWL_EXSTYLE);
+    focus_style = GetWindowLongA(focus_window, GWL_STYLE);
+    focus_exstyle = GetWindowLongA(focus_window, GWL_EXSTYLE);
+
+    ret = SetForegroundWindow(GetDesktopWindow());
+    ok(ret, "Failed to set foreground window.\n");
+    SetActiveWindow(device_window);
+    ok(GetActiveWindow() == device_window, "Unexpected active window.\n");
+
+    device_desc.device_window = device_window;
+    device_desc.flags = CREATE_DEVICE_FULLSCREEN;
+    device = create_device(d3d8, focus_window, &device_desc);
+    ok(!!device, "Failed to create a D3D device.\n");
+    ShowWindow(device_window, SW_SHOWNOACTIVATE);
+
+    style = GetWindowLongA(device_window, GWL_STYLE);
+    todo_wine ok(style == device_style || broken(style == (device_style & ~WS_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window style %#x, got %#x.\n", device_style, style);
+    style = GetWindowLongA(device_window, GWL_EXSTYLE);
+    todo_wine ok(style == device_exstyle || broken(style == (device_exstyle & ~WS_EX_OVERLAPPEDWINDOW)) /* w1064v1809 */,
+            "Expected device window extended style %#x, got %#x.\n", device_exstyle, style);
+
+    style = GetWindowLongA(focus_window, GWL_STYLE);
+    ok(style == focus_style, "Expected focus window style %#x, got %#x.\n", focus_style, style);
+    style = GetWindowLongA(focus_window, GWL_EXSTYLE);
+    ok(style == focus_exstyle, "Expected focus window extended style %#x, got %#x.\n", focus_exstyle, style);
+
+skip_inactive:
+    ref = IDirect3DDevice8_Release(device);
+    ok(ref == 0, "The device was not properly freed: refcount %u.\n", ref);
 
 done:
     IDirect3D8_Release(d3d8);
-- 
2.34.1




More information about the wine-devel mailing list