[2/2] user32: Fix for finding nested default buttons

André Hentschel nerv at dawncrow.de
Sun Jul 10 09:06:36 CDT 2011


---
 dlls/user32/controls.h     |    1 +
 dlls/user32/defdlg.c       |    2 +-
 dlls/user32/dialog.c       |   38 +++++++++++++++++++++++++++++++++++++-
 dlls/user32/tests/dialog.c |    2 +-
 4 files changed, 40 insertions(+), 3 deletions(-)

diff --git a/dlls/user32/controls.h b/dlls/user32/controls.h
index 66d6659..2038f4c 100644
--- a/dlls/user32/controls.h
+++ b/dlls/user32/controls.h
@@ -240,6 +240,7 @@ typedef struct tagDIALOGINFO
 
 extern DIALOGINFO *DIALOG_get_info( HWND hwnd, BOOL create ) DECLSPEC_HIDDEN;
 extern INT DIALOG_DoDialogBox( HWND hwnd, HWND owner ) DECLSPEC_HIDDEN;
+extern HWND DEFDLG_FindDefButton( HWND hwndDlg ) DECLSPEC_HIDDEN;
 
 HRGN set_control_clipping( HDC hdc, const RECT *rect ) DECLSPEC_HIDDEN;
 
diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c
index fecd417..1cdd19a 100644
--- a/dlls/user32/defdlg.c
+++ b/dlls/user32/defdlg.c
@@ -109,7 +109,7 @@ static void DEFDLG_RestoreFocus( HWND hwnd )
  *
  * Find the current default push-button.
  */
-static HWND DEFDLG_FindDefButton( HWND hwndDlg )
+HWND DEFDLG_FindDefButton( HWND hwndDlg )
 {
     HWND hwndChild, hwndTmp;
 
diff --git a/dlls/user32/dialog.c b/dlls/user32/dialog.c
index 2aa89d9..f27e3d4 100644
--- a/dlls/user32/dialog.c
+++ b/dlls/user32/dialog.c
@@ -1120,6 +1120,36 @@ static void DIALOG_FixChildrenOnChangeFocus (HWND hwndDlg, HWND hwndNext)
 }
 
 /***********************************************************************
+*           DIALOG_IdToHwnd
+*
+* Return the HWND for a Child ID.
+*/
+HWND DIALOG_IdToHwnd( HWND hwndDlg, INT id )
+{
+    int i;
+    HWND *list = WIN_ListChildren( hwndDlg );
+    HWND ret = 0;
+
+    if (!list) return 0;
+
+    for (i = 0; list[i]; i++)
+    {
+        if (GetWindowLongPtrW( list[i], GWLP_ID ) == id)
+        {
+            ret = list[i];
+            break;
+        }
+
+        /* Recurse into every child */
+        ret = GetDlgItem( list[i], id );
+        if (ret) break;
+    }
+
+    HeapFree( GetProcessHeap(), 0, list );
+    return ret;
+}
+
+/***********************************************************************
  *		IsDialogMessageW (USER32.@)
  */
 BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg )
@@ -1227,7 +1257,13 @@ BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg )
                 }
                 else if (DC_HASDEFID == HIWORD(dw = SendMessageW (hwndDlg, DM_GETDEFID, 0, 0)))
                 {
-                    HWND hwndDef = GetDlgItem(hwndDlg, LOWORD(dw));
+                    HWND hwndDef = DEFDLG_FindDefButton(hwndDlg);
+                    if (!hwndDef)
+                    {
+                        DIALOGINFO *dlgInfo = DIALOG_get_info( hwndDlg, FALSE );
+                        if(dlgInfo && !(dlgInfo->flags & DF_END) && dlgInfo->idResult)
+                           hwndDef = DIALOG_IdToHwnd(hwndDlg, dlgInfo->idResult);
+                    }
                     if (hwndDef ? IsWindowEnabled(hwndDef) : LOWORD(dw)==IDOK)
                         SendMessageW( hwndDlg, WM_COMMAND, MAKEWPARAM( LOWORD(dw), BN_CLICKED ), (LPARAM)hwndDef);
                 }
diff --git a/dlls/user32/tests/dialog.c b/dlls/user32/tests/dialog.c
index 61a3777..34e3802 100644
--- a/dlls/user32/tests/dialog.c
+++ b/dlls/user32/tests/dialog.c
@@ -1005,7 +1005,7 @@ static void test_NestedDefButton(void)
     g_bReceivedCommand = FALSE;
     FormEnterMsg (&msg, child3);
     ok(IsDialogMessage (hwnd, &msg), "Did not handle the ENTER\n");
-    todo_wine ok(g_bReceivedCommand, "Did not triggered the default Button action\n");
+    ok(g_bReceivedCommand, "Did not triggered the default Button action\n");
 
     DestroyWindow(child3);
     DestroyWindow(child2);
-- 

Best Regards, André Hentschel



More information about the wine-patches mailing list