Erich Hoover : user32: Prioritize focus for dialog owner on EndDialog.
Alexandre Julliard
julliard at winehq.org
Fri Nov 18 10:19:06 CST 2011
Module: wine
Branch: master
Commit: d2029908514d84e8fc0a805803fe9a427229e046
URL: http://source.winehq.org/git/wine.git/?a=commit;h=d2029908514d84e8fc0a805803fe9a427229e046
Author: Erich Hoover <ehoover at mines.edu>
Date: Tue Nov 15 17:58:32 2011 -0700
user32: Prioritize focus for dialog owner on EndDialog.
---
dlls/user32/dialog.c | 14 ++++++++++++--
dlls/user32/tests/msg.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 59 insertions(+), 2 deletions(-)
diff --git a/dlls/user32/dialog.c b/dlls/user32/dialog.c
index aa159c7..b9e739a 100644
--- a/dlls/user32/dialog.c
+++ b/dlls/user32/dialog.c
@@ -928,7 +928,8 @@ BOOL WINAPI EndDialog( HWND hwnd, INT_PTR retval )
dlgInfo->flags |= DF_END;
wasEnabled = (dlgInfo->flags & DF_OWNERENABLED);
- if (wasEnabled && (owner = GetWindow( hwnd, GW_OWNER )))
+ owner = GetWindow( hwnd, GW_OWNER );
+ if (wasEnabled && owner)
DIALOG_EnableOwner( owner );
/* Windows sets the focus to the dialog itself in EndDialog */
@@ -942,7 +943,16 @@ BOOL WINAPI EndDialog( HWND hwnd, INT_PTR retval )
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE
| SWP_NOZORDER | SWP_NOACTIVATE | SWP_HIDEWINDOW);
- if (hwnd == GetActiveWindow()) WINPOS_ActivateOtherWindow( hwnd );
+ if (hwnd == GetActiveWindow())
+ {
+ /* If this dialog was given an owner then set the focus to that owner
+ even when the owner is disabled (normally when a window closes any
+ disabled windows cannot receive the focus). */
+ if (owner)
+ SetForegroundWindow( owner );
+ else
+ WINPOS_ActivateOtherWindow( hwnd );
+ }
/* unblock dialog loop */
PostMessageA(hwnd, WM_NULL, 0, 0);
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 0376162..1e8e253 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -11256,6 +11256,52 @@ static void test_dialog_messages(void)
UnregisterClass(cls.lpszClassName, cls.hInstance);
}
+static void test_EndDialog(void)
+{
+ HWND hparent, hother, hactive, hdlg;
+ WNDCLASS cls;
+
+ hparent = CreateWindowExA(0, "TestParentClass", "Test parent",
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_DISABLED,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok (hparent != 0, "Failed to create parent window\n");
+
+ hother = CreateWindowExA(0, "TestParentClass", "Test parent 2",
+ WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 100, 100, 200, 200, 0, 0, 0, NULL);
+ ok (hother != 0, "Failed to create parent window\n");
+
+ ok(GetClassInfo(0, "#32770", &cls), "GetClassInfo failed\n");
+ cls.lpszClassName = "MyDialogClass";
+ cls.hInstance = GetModuleHandle(0);
+ /* need a cast since a dlgproc is used as a wndproc */
+ cls.lpfnWndProc = (WNDPROC)test_dlg_proc;
+ if (!RegisterClass(&cls)) assert(0);
+
+ flush_sequence();
+ SetForegroundWindow(hother);
+ hactive = GetForegroundWindow();
+ ok(hother == hactive, "Wrong window has focus (%p != %p)\n", hother, hactive);
+
+ /* create a dialog where the parent is disabled, this parent should still
+ receive the focus when the dialog exits (even though "normally" a
+ disabled window should not receive the focus) */
+ hdlg = CreateDialogParam(0, "CLASS_TEST_DIALOG_2", hparent, test_dlg_proc, 0);
+ ok(IsWindow(hdlg), "CreateDialogParam failed\n");
+ SetForegroundWindow(hdlg);
+ hactive = GetForegroundWindow();
+ ok(hdlg == hactive, "Wrong window has focus (%p != %p)\n", hdlg, hactive);
+ EndDialog(hdlg, 0);
+ hactive = GetForegroundWindow();
+ ok(hparent == hactive, "Wrong window has focus (parent != active) (active: %p, parent: %p, dlg: %p, other: %p)\n", hactive, hparent, hdlg, hother);
+ DestroyWindow(hdlg);
+ flush_sequence();
+
+ DestroyWindow( hother );
+ DestroyWindow( hparent );
+ UnregisterClass(cls.lpszClassName, cls.hInstance);
+}
+
static void test_nullCallback(void)
{
HWND hwnd;
@@ -13573,6 +13619,7 @@ START_TEST(msg)
test_SetWindowRgn();
test_sys_menu();
test_dialog_messages();
+ test_EndDialog();
test_nullCallback();
test_dbcs_wm_char();
test_menu_messages();
More information about the wine-cvs
mailing list