From b6c11108ec190a27f9c549d1e79c7003149a3eff Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Thu, 18 Feb 2016 12:15:55 +0100 Subject: [PATCH] Added patch to ensure MessageBox is topmost when MB_SYSTEMMODAL style is set. --- patches/patchinstall.sh | 18 +++ ...-some-tests-to-see-when-MessageBox-g.patch | 142 ++++++++++++++++++ ...x-should-be-topmost-when-MB_SYSTEMMO.patch | 49 ++++++ .../definition | 1 + 4 files changed, 210 insertions(+) create mode 100644 patches/user32-MessageBox_WS_EX_TOPMOST/0001-user32-tests-Add-some-tests-to-see-when-MessageBox-g.patch create mode 100644 patches/user32-MessageBox_WS_EX_TOPMOST/0002-user32-MessageBox-should-be-topmost-when-MB_SYSTEMMO.patch create mode 100644 patches/user32-MessageBox_WS_EX_TOPMOST/definition diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 0dcb3717..ec1ab2b6 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -311,6 +311,7 @@ patch_enable_all () enable_user32_Invalidate_Key_State="$1" enable_user32_ListBox_Size="$1" enable_user32_MDI_Extra_Data="$1" + enable_user32_MessageBox_WS_EX_TOPMOST="$1" enable_user32_Mouse_Message_Hwnd="$1" enable_user32_Refresh_MDI_Menus="$1" enable_user32_ScrollWindowEx="$1" @@ -1075,6 +1076,9 @@ patch_enable () user32-MDI_Extra_Data) enable_user32_MDI_Extra_Data="$2" ;; + user32-MessageBox_WS_EX_TOPMOST) + enable_user32_MessageBox_WS_EX_TOPMOST="$2" + ;; user32-Mouse_Message_Hwnd) enable_user32_Mouse_Message_Hwnd="$2" ;; @@ -6328,6 +6332,20 @@ if test "$enable_user32_MDI_Extra_Data" -eq 1; then ) >> "$patchlist" fi +# Patchset user32-MessageBox_WS_EX_TOPMOST +# | +# | Modified files: +# | * dlls/user32/msgbox.c, dlls/user32/tests/dialog.c +# | +if test "$enable_user32_MessageBox_WS_EX_TOPMOST" -eq 1; then + patch_apply user32-MessageBox_WS_EX_TOPMOST/0001-user32-tests-Add-some-tests-to-see-when-MessageBox-g.patch + patch_apply user32-MessageBox_WS_EX_TOPMOST/0002-user32-MessageBox-should-be-topmost-when-MB_SYSTEMMO.patch + ( + echo '+ { "Dmitry Timoshkov", "user32/tests: Add some tests to see when MessageBox gains WS_EX_TOPMOST style.", 1 },'; + echo '+ { "Dmitry Timoshkov", "user32: MessageBox should be topmost when MB_SYSTEMMODAL style is set.", 1 },'; + ) >> "$patchlist" +fi + # Patchset user32-Mouse_Message_Hwnd # | # | This patchset fixes the following Wine bugs: diff --git a/patches/user32-MessageBox_WS_EX_TOPMOST/0001-user32-tests-Add-some-tests-to-see-when-MessageBox-g.patch b/patches/user32-MessageBox_WS_EX_TOPMOST/0001-user32-tests-Add-some-tests-to-see-when-MessageBox-g.patch new file mode 100644 index 00000000..12892c2a --- /dev/null +++ b/patches/user32-MessageBox_WS_EX_TOPMOST/0001-user32-tests-Add-some-tests-to-see-when-MessageBox-g.patch @@ -0,0 +1,142 @@ +From 95fd970d76fc01963d2590a962603439b944472d Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +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 | 112 +++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 112 insertions(+) + +diff --git a/dlls/user32/tests/dialog.c b/dlls/user32/tests/dialog.c +index eede834..71a2f48 100644 +--- a/dlls/user32/tests/dialog.c ++++ b/dlls/user32/tests/dialog.c +@@ -1443,12 +1443,124 @@ static void test_timer_message(void) + DialogBoxA(g_hinst, "RADIO_TEST_DIALOG", NULL, timer_message_dlg_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; ++ } ++ } ++ ++ 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, ¶ms, 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 & test[i].ex_style) == 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, ¶ms, 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 & test[i].ex_style) == 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_GetNextDlgItem(); + test_IsDialogMessage(); + test_WM_NEXTDLGCTL(); +-- +2.7.1 + diff --git a/patches/user32-MessageBox_WS_EX_TOPMOST/0002-user32-MessageBox-should-be-topmost-when-MB_SYSTEMMO.patch b/patches/user32-MessageBox_WS_EX_TOPMOST/0002-user32-MessageBox-should-be-topmost-when-MB_SYSTEMMO.patch new file mode 100644 index 00000000..774f9afa --- /dev/null +++ b/patches/user32-MessageBox_WS_EX_TOPMOST/0002-user32-MessageBox-should-be-topmost-when-MB_SYSTEMMO.patch @@ -0,0 +1,49 @@ +From 6da3751e3a45b8753f5605e93d669f4ff1bb78e1 Mon Sep 17 00:00:00 2001 +From: Dmitry Timoshkov +Date: Thu, 18 Feb 2016 10:22:29 +0800 +Subject: user32: MessageBox should be topmost when MB_SYSTEMMODAL style is + set. + +--- + dlls/user32/msgbox.c | 4 ++-- + dlls/user32/tests/dialog.c | 2 -- + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/dlls/user32/msgbox.c b/dlls/user32/msgbox.c +index 2ba98c9..e5dc120 100644 +--- a/dlls/user32/msgbox.c ++++ b/dlls/user32/msgbox.c +@@ -313,8 +313,8 @@ static void MSGBOX_OnInit(HWND hwnd, LPMSGBOXPARAMSW lpmb) + } + + /*handle modal message boxes*/ +- if (((lpmb->dwStyle & MB_TASKMODAL) && (lpmb->hwndOwner==NULL)) || (lpmb->dwStyle & MB_SYSTEMMODAL)) +- SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); ++ if (lpmb->dwStyle & MB_SYSTEMMODAL) ++ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + + HeapFree( GetProcessHeap(), 0, buffer ); + } +diff --git a/dlls/user32/tests/dialog.c b/dlls/user32/tests/dialog.c +index 71a2f48..416e914 100644 +--- a/dlls/user32/tests/dialog.c ++++ b/dlls/user32/tests/dialog.c +@@ -1522,7 +1522,6 @@ static void test_MessageBox(void) + + 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 & test[i].ex_style) == test[i].ex_style, "%d: got window ex_style %#x\n", i, ex_style); + + PostMessageA(hwnd, WM_COMMAND, IDCANCEL, 0); +@@ -1544,7 +1543,6 @@ static void test_MessageBox(void) + + 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 & test[i].ex_style) == test[i].ex_style, "%d: got window ex_style %#x\n", i, ex_style); + + PostMessageA(hwnd, WM_COMMAND, IDCANCEL, 0); +-- +2.7.1 + diff --git a/patches/user32-MessageBox_WS_EX_TOPMOST/definition b/patches/user32-MessageBox_WS_EX_TOPMOST/definition new file mode 100644 index 00000000..42facfbf --- /dev/null +++ b/patches/user32-MessageBox_WS_EX_TOPMOST/definition @@ -0,0 +1 @@ +Fixes: MessageBox should be topmost when MB_SYSTEMMODAL style is set