From 7a0cb3382e4d57adf72203c381105340d893d21b Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 18 Feb 2016 10:17:46 +0800
Subject: user32/tests: Add some tests to see when MessageBox gains
 WS_EX_TOPMOST style.

---
 dlls/user32/tests/dialog.c | 113 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

diff --git a/dlls/user32/tests/dialog.c b/dlls/user32/tests/dialog.c
index 4289b3f..945d971 100644
--- a/dlls/user32/tests/dialog.c
+++ b/dlls/user32/tests/dialog.c
@@ -1508,12 +1508,125 @@ static void test_dialog_custom_data(void)
     DialogBoxA(g_hinst, "CUSTOM_TEST_DIALOG", NULL, custom_test_dialog_proc);
 }
 
+struct create_window_params
+{
+    BOOL owner;
+    char caption[64];
+    DWORD style;
+};
+
+static DWORD WINAPI create_window_thread(void *param)
+{
+    struct create_window_params *p = param;
+    HWND owner = 0;
+
+    if (p->owner)
+    {
+        owner = CreateWindowExA(0, "Static", NULL, WS_POPUP, 10, 10, 10, 10, 0, 0, 0, NULL);
+        ok(owner != 0, "failed to create owner window\n");
+    }
+
+    MessageBoxA(owner, NULL, p->caption, p->style);
+
+    if (owner) DestroyWindow(owner);
+
+    return 0;
+}
+
+static HWND wait_for_window(const char *caption)
+{
+    HWND hwnd;
+    DWORD timeout = 0;
+
+    for (;;)
+    {
+        hwnd = FindWindowA(NULL, caption);
+        if (hwnd) break;
+
+        Sleep(50);
+        timeout += 50;
+        if (timeout > 3000)
+        {
+            ok(0, "failed to wait for a window %s\n", caption);
+            break;
+        }
+    }
+
+    Sleep(50);
+    return hwnd;
+}
+
+static void test_MessageBox(void)
+{
+    static const struct
+    {
+        DWORD mb_style;
+        DWORD ex_style;
+    } test[] =
+    {
+        { MB_OK, 0 },
+        { MB_OK | MB_TASKMODAL, 0 },
+        { MB_OK | MB_SYSTEMMODAL, WS_EX_TOPMOST },
+    };
+    DWORD tid, i;
+    HANDLE thread;
+    struct create_window_params params;
+
+    sprintf(params.caption, "pid %08x, tid %08x, time %08x",
+            GetCurrentProcessId(), GetCurrentThreadId(), GetCurrentTime());
+
+    params.owner = FALSE;
+
+    for (i = 0; i < sizeof(test)/sizeof(test[0]); i++)
+    {
+        HWND hwnd;
+        DWORD ex_style;
+
+        params.style = test[i].mb_style;
+
+        thread = CreateThread(NULL, 0, create_window_thread, &params, 0, &tid);
+
+        hwnd = wait_for_window(params.caption);
+        ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
+        todo_wine_if(test[i].ex_style == WS_EX_TOPMOST)
+        ok((ex_style & WS_EX_TOPMOST) == test[i].ex_style, "%d: got window ex_style %#x\n", i, ex_style);
+
+        PostMessageA(hwnd, WM_COMMAND, IDCANCEL, 0);
+
+        ok(WaitForSingleObject(thread, 5000) != WAIT_TIMEOUT, "thread failed to terminate\n");
+        CloseHandle(thread);
+    }
+
+    params.owner = TRUE;
+
+    for (i = 0; i < sizeof(test)/sizeof(test[0]); i++)
+    {
+        HWND hwnd;
+        DWORD ex_style;
+
+        params.style = test[i].mb_style;
+
+        thread = CreateThread(NULL, 0, create_window_thread, &params, 0, &tid);
+
+        hwnd = wait_for_window(params.caption);
+        ex_style = GetWindowLongA(hwnd, GWL_EXSTYLE);
+        todo_wine_if(test[i].ex_style == WS_EX_TOPMOST)
+        ok((ex_style & WS_EX_TOPMOST) == test[i].ex_style, "%d: got window ex_style %#x\n", i, ex_style);
+
+        PostMessageA(hwnd, WM_COMMAND, IDCANCEL, 0);
+
+        ok(WaitForSingleObject(thread, 5000) != WAIT_TIMEOUT, "thread failed to terminate\n");
+        CloseHandle(thread);
+    }
+}
+
 START_TEST(dialog)
 {
     g_hinst = GetModuleHandleA (0);
 
     if (!RegisterWindowClasses()) assert(0);
 
+    test_MessageBox();
     test_dialog_custom_data();
     test_GetNextDlgItem();
     test_IsDialogMessage();
-- 
2.7.1

