From: Rémi Bernon rbernon@codeweavers.com
We cannot safely switch to the desktop window, and we also cannot safely destroy and re-create windows without risking to lose focus in favor of a foreign window. Lets create a dedicated window to which foreground will be returned whenever the test windows lose it. --- dlls/ddraw/tests/ddraw1.c | 87 +++++++++++++++++++++++++++++++++------ dlls/ddraw/tests/ddraw2.c | 87 +++++++++++++++++++++++++++++++++------ dlls/ddraw/tests/ddraw4.c | 87 +++++++++++++++++++++++++++++++++------ dlls/ddraw/tests/ddraw7.c | 87 +++++++++++++++++++++++++++++++++------ 4 files changed, 300 insertions(+), 48 deletions(-)
diff --git a/dlls/ddraw/tests/ddraw1.c b/dlls/ddraw/tests/ddraw1.c index fb5201f66ba..ab7ddf3be15 100644 --- a/dlls/ddraw/tests/ddraw1.c +++ b/dlls/ddraw/tests/ddraw1.c @@ -30,6 +30,7 @@
static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEA registry_mode; +static HWND foreground;
static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
@@ -113,6 +114,64 @@ static void flush_events(void) } }
+static HWND create_foreground_window(void) +{ + for (UINT retries = 5; retries; retries--) + { + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowW(L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 5, 5, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowW failed, error %lu\n", GetLastError()); + flush_events(); + + if (GetForegroundWindow() == hwnd) + return hwnd; + ret = DestroyWindow(hwnd); + ok(ret, "DestroyWindow failed, error %lu\n", GetLastError()); + flush_events(); + } + + ok(0, "Failed to create foreground window\n"); + return NULL; +} + +static LRESULT CALLBACK foreground_window_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + if (msg == WM_USER) + SetForegroundWindow((HWND)wparam); + if (msg == WM_CLOSE) + PostQuitMessage(0); + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +static DWORD WINAPI foreground_window_thread(void *arg) +{ + HANDLE event = arg; + MSG msg; + + foreground = create_foreground_window(); + SetWindowLongPtrW(foreground, GWLP_WNDPROC, (LONG_PTR)foreground_window_wndproc); + SetEvent(event); + + while (GetMessageW(&msg, NULL, 0, 0)) + { + if (msg.message == WM_QUIT) break; + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + return 0; +} + +static void start_foreground_window_thread(void) +{ + HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); + CloseHandle(CreateThread(NULL, 0, foreground_window_thread, event, 0, NULL)); + WaitForSingleObject(event, 10000); + CloseHandle(event); +} + static BOOL ddraw_get_identifier(IDirectDraw *ddraw, DDDEVICEIDENTIFIER *identifier) { IDirectDraw4 *ddraw4; @@ -1053,6 +1112,8 @@ static void test_clipper_blt(void) window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 10, 10, 640, 480, 0, 0, 0, 0); ShowWindow(window, SW_SHOW); + flush_events(); + ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");
@@ -2632,7 +2693,7 @@ static void test_window_style(void) GetClientRect(window, &r); todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n");
tmp = GetWindowLongA(window, GWL_STYLE); @@ -2720,7 +2781,7 @@ static void test_window_style(void) ok(tmp == exstyle, "Expected window extended style %#lx, got %#lx.\n", exstyle, tmp);
ShowWindow(window, SW_SHOW); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); SetActiveWindow(window); ok(GetActiveWindow() == window, "Unexpected active window.\n"); @@ -2792,7 +2853,7 @@ static void test_window_style(void) expected_style = exstyle | WS_EX_TOPMOST; todo_wine ok(tmp == expected_style, "Expected window extended style %#lx, got %#lx.\n", expected_style, tmp);
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); tmp = GetWindowLongA(window, GWL_STYLE); expected_style = style | WS_VISIBLE | WS_MINIMIZE; @@ -3186,7 +3247,7 @@ static void test_coop_level_mode_set(void) wine_dbgstr_rect(&r));
expect_messages = exclusive_focus_loss_messages; - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); memset(&devmode, 0, sizeof(devmode)); @@ -4461,7 +4522,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Exclusive with window not active. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -4470,7 +4531,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Normal with window not active, then exclusive with the same window. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -4482,7 +4543,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -4504,7 +4565,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Setting DDSCL_NORMAL with recursive invocation. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -8217,7 +8278,7 @@ static void test_lost_device(void) ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); }
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#lx.\n", hr); @@ -8301,7 +8362,7 @@ static void test_lost_device(void) hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); @@ -13835,7 +13896,7 @@ static void test_killfocus(void) hr = IDirectDraw_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL); ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
- SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
DestroyWindow(window); @@ -14794,7 +14855,7 @@ static BOOL CALLBACK test_window_position_cb(HMONITOR monitor, HDC hdc, RECT *mo ret = SetWindowPos(window, 0, monitor_rect->left, monitor_rect->top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); ok(ret, "SetWindowPos failed, error %lu.\n", GetLastError()); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); flush_events(); ret = ShowWindow(window, SW_RESTORE); @@ -16343,6 +16404,8 @@ START_TEST(ddraw1) if ((dwmapi = LoadLibraryA("dwmapi.dll"))) pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
+ start_foreground_window_thread(); + test_coop_level_create_device_window(); test_clipper_blt(); test_coop_level_d3d_state(); diff --git a/dlls/ddraw/tests/ddraw2.c b/dlls/ddraw/tests/ddraw2.c index f163ec80bed..36b7c8eeea8 100644 --- a/dlls/ddraw/tests/ddraw2.c +++ b/dlls/ddraw/tests/ddraw2.c @@ -31,6 +31,7 @@
static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEA registry_mode; +static HWND foreground;
static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
@@ -114,6 +115,64 @@ static void flush_events(void) } }
+static HWND create_foreground_window(void) +{ + for (UINT retries = 5; retries; retries--) + { + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowW(L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 5, 5, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowW failed, error %lu\n", GetLastError()); + flush_events(); + + if (GetForegroundWindow() == hwnd) + return hwnd; + ret = DestroyWindow(hwnd); + ok(ret, "DestroyWindow failed, error %lu\n", GetLastError()); + flush_events(); + } + + ok(0, "Failed to create foreground window\n"); + return NULL; +} + +static LRESULT CALLBACK foreground_window_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + if (msg == WM_USER) + SetForegroundWindow((HWND)wparam); + if (msg == WM_CLOSE) + PostQuitMessage(0); + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +static DWORD WINAPI foreground_window_thread(void *arg) +{ + HANDLE event = arg; + MSG msg; + + foreground = create_foreground_window(); + SetWindowLongPtrW(foreground, GWLP_WNDPROC, (LONG_PTR)foreground_window_wndproc); + SetEvent(event); + + while (GetMessageW(&msg, NULL, 0, 0)) + { + if (msg.message == WM_QUIT) break; + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + return 0; +} + +static void start_foreground_window_thread(void) +{ + HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); + CloseHandle(CreateThread(NULL, 0, foreground_window_thread, event, 0, NULL)); + WaitForSingleObject(event, 10000); + CloseHandle(event); +} + static BOOL ddraw_get_identifier(IDirectDraw2 *ddraw, DDDEVICEIDENTIFIER *identifier) { IDirectDraw4 *ddraw4; @@ -901,6 +960,8 @@ static void test_clipper_blt(void) window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 10, 10, 640, 480, 0, 0, 0, 0); ShowWindow(window, SW_SHOW); + flush_events(); + ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");
@@ -2713,7 +2774,7 @@ static void test_window_style(void) GetClientRect(window, &r); todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n");
tmp = GetWindowLongA(window, GWL_STYLE); @@ -2801,7 +2862,7 @@ static void test_window_style(void) ok(tmp == exstyle, "Expected window extended style %#lx, got %#lx.\n", exstyle, tmp);
ShowWindow(window, SW_SHOW); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); SetActiveWindow(window); ok(GetActiveWindow() == window, "Unexpected active window.\n"); @@ -2873,7 +2934,7 @@ static void test_window_style(void) expected_style = exstyle | WS_EX_TOPMOST; todo_wine ok(tmp == expected_style, "Expected window extended style %#lx, got %#lx.\n", expected_style, tmp);
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); tmp = GetWindowLongA(window, GWL_STYLE); expected_style = style | WS_VISIBLE | WS_MINIMIZE; @@ -3283,7 +3344,7 @@ static void test_coop_level_mode_set(void) wine_dbgstr_rect(&r));
expect_messages = exclusive_focus_loss_messages; - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); memset(&devmode, 0, sizeof(devmode)); @@ -4926,7 +4987,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Exclusive with window not active. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -4935,7 +4996,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Normal with window not active, then exclusive with the same window. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw2_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -4947,7 +5008,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -4969,7 +5030,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Setting DDSCL_NORMAL with recursive invocation. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -9258,7 +9319,7 @@ static void test_lost_device(void) ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); }
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DDERR_SURFACELOST, "Got unexpected hr %#lx.\n", hr); @@ -9341,7 +9402,7 @@ static void test_lost_device(void) hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr);
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDrawSurface_IsLost(surface); ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); @@ -14885,7 +14946,7 @@ static void test_killfocus(void) hr = IDirectDraw2_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL); ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
- SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
DestroyWindow(window); @@ -15752,7 +15813,7 @@ static BOOL CALLBACK test_window_position_cb(HMONITOR monitor, HDC hdc, RECT *mo ret = SetWindowPos(window, 0, monitor_rect->left, monitor_rect->top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); ok(ret, "SetWindowPos failed, error %lu.\n", GetLastError()); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); flush_events(); ret = ShowWindow(window, SW_RESTORE); @@ -17414,6 +17475,8 @@ START_TEST(ddraw2) if ((dwmapi = LoadLibraryA("dwmapi.dll"))) pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
+ start_foreground_window_thread(); + test_coop_level_create_device_window(); test_clipper_blt(); test_coop_level_d3d_state(); diff --git a/dlls/ddraw/tests/ddraw4.c b/dlls/ddraw/tests/ddraw4.c index 60eaa3ec8d0..1e9a964d86d 100644 --- a/dlls/ddraw/tests/ddraw4.c +++ b/dlls/ddraw/tests/ddraw4.c @@ -32,6 +32,7 @@ HRESULT WINAPI GetSurfaceFromDC(HDC dc, struct IDirectDrawSurface **surface, HDC
static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEA registry_mode; +static HWND foreground;
static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *);
@@ -120,6 +121,64 @@ static void flush_events(void) } }
+static HWND create_foreground_window(void) +{ + for (UINT retries = 5; retries; retries--) + { + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowW(L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 5, 5, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowW failed, error %lu\n", GetLastError()); + flush_events(); + + if (GetForegroundWindow() == hwnd) + return hwnd; + ret = DestroyWindow(hwnd); + ok(ret, "DestroyWindow failed, error %lu\n", GetLastError()); + flush_events(); + } + + ok(0, "Failed to create foreground window\n"); + return NULL; +} + +static LRESULT CALLBACK foreground_window_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + if (msg == WM_USER) + SetForegroundWindow((HWND)wparam); + if (msg == WM_CLOSE) + PostQuitMessage(0); + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +static DWORD WINAPI foreground_window_thread(void *arg) +{ + HANDLE event = arg; + MSG msg; + + foreground = create_foreground_window(); + SetWindowLongPtrW(foreground, GWLP_WNDPROC, (LONG_PTR)foreground_window_wndproc); + SetEvent(event); + + while (GetMessageW(&msg, NULL, 0, 0)) + { + if (msg.message == WM_QUIT) break; + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + return 0; +} + +static void start_foreground_window_thread(void) +{ + HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); + CloseHandle(CreateThread(NULL, 0, foreground_window_thread, event, 0, NULL)); + WaitForSingleObject(event, 10000); + CloseHandle(event); +} + static BOOL ddraw_get_identifier(IDirectDraw4 *ddraw, DDDEVICEIDENTIFIER *identifier) { HRESULT hr; @@ -1093,6 +1152,8 @@ static void test_clipper_blt(void) window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 10, 10, 640, 480, 0, 0, 0, 0); ShowWindow(window, SW_SHOW); + flush_events(); + ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");
@@ -2953,7 +3014,7 @@ static void test_window_style(void) GetClientRect(window, &r); todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n");
tmp = GetWindowLongA(window, GWL_STYLE); @@ -3041,7 +3102,7 @@ static void test_window_style(void) ok(tmp == exstyle, "Expected window extended style %#lx, got %#lx.\n", exstyle, tmp);
ShowWindow(window, SW_SHOW); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); SetActiveWindow(window); ok(GetActiveWindow() == window, "Unexpected active window.\n"); @@ -3113,7 +3174,7 @@ static void test_window_style(void) expected_style = exstyle | WS_EX_TOPMOST; todo_wine ok(tmp == expected_style, "Expected window extended style %#lx, got %#lx.\n", expected_style, tmp);
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); tmp = GetWindowLongA(window, GWL_STYLE); expected_style = style | WS_VISIBLE | WS_MINIMIZE; @@ -3524,7 +3585,7 @@ static void test_coop_level_mode_set(void)
expect_messages = exclusive_focus_loss_messages; focus_test_ddraw = ddraw; - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); focus_test_ddraw = NULL; @@ -6119,7 +6180,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Exclusive with window not active. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -6128,7 +6189,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Normal with window not active, then exclusive with the same window. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw4_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -6140,7 +6201,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -6162,7 +6223,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Setting DDSCL_NORMAL with recursive invocation. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -10632,7 +10693,7 @@ static void test_lost_device(void) ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); }
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw4_TestCooperativeLevel(ddraw); ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#lx.\n", hr); @@ -10732,7 +10793,7 @@ static void test_lost_device(void) ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); }
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw4_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); @@ -17493,7 +17554,7 @@ static void test_killfocus(void) hr = IDirectDraw4_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL); ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
- SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
DestroyWindow(window); @@ -18824,7 +18885,7 @@ static BOOL CALLBACK test_window_position_cb(HMONITOR monitor, HDC hdc, RECT *mo ret = SetWindowPos(window, 0, monitor_rect->left, monitor_rect->top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); ok(ret, "SetWindowPos failed, error %lu.\n", GetLastError()); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); flush_events(); ret = ShowWindow(window, SW_RESTORE); @@ -20495,6 +20556,8 @@ START_TEST(ddraw4) if ((dwmapi = LoadLibraryA("dwmapi.dll"))) pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
+ start_foreground_window_thread(); + test_process_vertices(); test_coop_level_create_device_window(); test_clipper_blt(); diff --git a/dlls/ddraw/tests/ddraw7.c b/dlls/ddraw/tests/ddraw7.c index a3df2fa659f..7a3c96fa315 100644 --- a/dlls/ddraw/tests/ddraw7.c +++ b/dlls/ddraw/tests/ddraw7.c @@ -32,6 +32,7 @@ HRESULT WINAPI GetSurfaceFromDC(HDC dc, struct IDirectDrawSurface **surface, HDC static HRESULT (WINAPI *pDirectDrawCreateEx)(GUID *guid, void **ddraw, REFIID iid, IUnknown *outer_unknown); static BOOL is_ddraw64 = sizeof(DWORD) != sizeof(DWORD *); static DEVMODEA registry_mode; +static HWND foreground; static const GUID *hw_device_guid = &IID_IDirect3DHALDevice;
static HRESULT (WINAPI *pDwmIsCompositionEnabled)(BOOL *); @@ -161,6 +162,64 @@ static void flush_events(void) } }
+static HWND create_foreground_window(void) +{ + for (UINT retries = 5; retries; retries--) + { + HWND hwnd; + BOOL ret; + + hwnd = CreateWindowW(L"static", NULL, WS_POPUP | WS_VISIBLE, 0, 0, 5, 5, NULL, NULL, NULL, NULL); + ok(hwnd != NULL, "CreateWindowW failed, error %lu\n", GetLastError()); + flush_events(); + + if (GetForegroundWindow() == hwnd) + return hwnd; + ret = DestroyWindow(hwnd); + ok(ret, "DestroyWindow failed, error %lu\n", GetLastError()); + flush_events(); + } + + ok(0, "Failed to create foreground window\n"); + return NULL; +} + +static LRESULT CALLBACK foreground_window_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + if (msg == WM_USER) + SetForegroundWindow((HWND)wparam); + if (msg == WM_CLOSE) + PostQuitMessage(0); + return DefWindowProcW(hwnd, msg, wparam, lparam); +} + +static DWORD WINAPI foreground_window_thread(void *arg) +{ + HANDLE event = arg; + MSG msg; + + foreground = create_foreground_window(); + SetWindowLongPtrW(foreground, GWLP_WNDPROC, (LONG_PTR)foreground_window_wndproc); + SetEvent(event); + + while (GetMessageW(&msg, NULL, 0, 0)) + { + if (msg.message == WM_QUIT) break; + TranslateMessage(&msg); + DispatchMessageW(&msg); + } + + return 0; +} + +static void start_foreground_window_thread(void) +{ + HANDLE event = CreateEventA(NULL, FALSE, FALSE, NULL); + CloseHandle(CreateThread(NULL, 0, foreground_window_thread, event, 0, NULL)); + WaitForSingleObject(event, 10000); + CloseHandle(event); +} + static BOOL ddraw_get_identifier(IDirectDraw7 *ddraw, DDDEVICEIDENTIFIER2 *identifier) { HRESULT hr; @@ -1178,6 +1237,8 @@ static void test_clipper_blt(void) window = CreateWindowA("static", "ddraw_test", WS_OVERLAPPEDWINDOW, 10, 10, 640, 480, 0, 0, 0, 0); ShowWindow(window, SW_SHOW); + flush_events(); + ddraw = create_ddraw(); ok(!!ddraw, "Failed to create a ddraw object.\n");
@@ -2715,7 +2776,7 @@ static void test_window_style(void) GetClientRect(window, &r); todo_wine ok(!EqualRect(&r, &fullscreen_rect), "Client rect and window rect are equal.\n");
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n");
tmp = GetWindowLongA(window, GWL_STYLE); @@ -2803,7 +2864,7 @@ static void test_window_style(void) ok(tmp == exstyle, "Expected window extended style %#lx, got %#lx.\n", exstyle, tmp);
ShowWindow(window, SW_SHOW); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); SetActiveWindow(window); ok(GetActiveWindow() == window, "Unexpected active window.\n"); @@ -2875,7 +2936,7 @@ static void test_window_style(void) expected_style = exstyle | WS_EX_TOPMOST; todo_wine ok(tmp == expected_style, "Expected window extended style %#lx, got %#lx.\n", expected_style, tmp);
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); tmp = GetWindowLongA(window, GWL_STYLE); expected_style = style | WS_VISIBLE | WS_MINIMIZE; @@ -3285,7 +3346,7 @@ static void test_coop_level_mode_set(void)
expect_messages = exclusive_focus_loss_messages; focus_test_ddraw = ddraw; - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); ok(!expect_messages->message, "Expected message %#x, but didn't receive it.\n", expect_messages->message); focus_test_ddraw = NULL; @@ -5960,7 +6021,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Exclusive with window not active. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -5969,7 +6030,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Normal with window not active, then exclusive with the same window. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; hr = IDirectDraw7_SetCooperativeLevel(ddraw, window, DDSCL_NORMAL); ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr); @@ -5981,7 +6042,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Recursive set of DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -6003,7 +6064,7 @@ static void test_coop_level_activateapp(void) ok(SUCCEEDED(hr), "Failed to set cooperative level, hr %#lx.\n", hr);
/* Setting DDSCL_NORMAL with recursive invocation. */ - SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); activateapp_testdata.received = FALSE; activateapp_testdata.ddraw = ddraw; activateapp_testdata.window = window; @@ -10498,7 +10559,7 @@ static void test_lost_device(void) ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); }
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw7_TestCooperativeLevel(ddraw); ok(hr == DDERR_NOEXCLUSIVEMODE, "Got unexpected hr %#lx.\n", hr); @@ -10600,7 +10661,7 @@ static void test_lost_device(void) ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); }
- ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); hr = IDirectDraw7_TestCooperativeLevel(ddraw); ok(hr == DD_OK, "Got unexpected hr %#lx.\n", hr); @@ -17485,7 +17546,7 @@ static void test_killfocus(void) hr = IDirectDraw7_CreateSurface(killfocus_ddraw, &surface_desc, &killfocus_surface, NULL); ok(SUCCEEDED(hr), "Failed to create surface, hr %#lx.\n", hr);
- SetForegroundWindow(GetDesktopWindow()); + SetForegroundWindow(foreground); ok(!killfocus_ddraw, "WM_KILLFOCUS was not received.\n");
DestroyWindow(window); @@ -19204,7 +19265,7 @@ static BOOL CALLBACK test_window_position_cb(HMONITOR monitor, HDC hdc, RECT *mo ret = SetWindowPos(window, 0, monitor_rect->left, monitor_rect->top, 0, 0, SWP_NOZORDER | SWP_NOSIZE); ok(ret, "SetWindowPos failed, error %lu.\n", GetLastError()); - ret = SetForegroundWindow(GetDesktopWindow()); + ret = SetForegroundWindow(foreground); ok(ret, "Failed to set foreground window.\n"); flush_events(); ret = ShowWindow(window, SW_RESTORE); @@ -20919,6 +20980,8 @@ START_TEST(ddraw7) if ((dwmapi = LoadLibraryA("dwmapi.dll"))) pDwmIsCompositionEnabled = (void *)GetProcAddress(dwmapi, "DwmIsCompositionEnabled");
+ start_foreground_window_thread(); + test_process_vertices(); test_coop_level_create_device_window(); test_clipper_blt();