[USER32] Check whether the window is minimized upon SM_REPOSITION CORE-16490
[reactos.git] / win32ss / user / user32 / windows / dialog.c
index 48304d1..1acb4f5 100644 (file)
@@ -18,8 +18,8 @@
  */
 /*
  * PROJECT:         ReactOS user32.dll
- * FILE:            dll/win32/user32/windows/dialog.c
- * PURPOSE:         Input
+ * FILE:            win32ss/user/user32/windows/dialog.c
+ * PURPOSE:         Dialog Manager
  * PROGRAMMER:      Casper S. Hornstrup (chorns@users.sourceforge.net)
  *                  Thomas Weidenmueller (w3seek@users.sourceforge.net)
  *                  Steven Edwards (Steven_Ed4153@yahoo.com)
  *      09-05-2001  CSH  Created
  */
 
-/* INCLUDES ******************************************************************/
-
 #include <user32.h>
 
-#include <wine/debug.h>
 WINE_DEFAULT_DEBUG_CHANNEL(user32);
 
 /* MACROS/DEFINITIONS ********************************************************/
 
 #define DF_END  0x0001
-#define DF_OWNERENABLED 0x0002
 #define DF_DIALOGACTIVE 0x4000 // ReactOS
 #define DWLP_ROS_DIALOGINFO (DWLP_USER+sizeof(ULONG_PTR))
 #define GETDLGINFO(hwnd) DIALOG_get_info(hwnd, FALSE)
 #define SETDLGINFO(hwnd, info) SetWindowLongPtrW((hwnd), DWLP_ROS_DIALOGINFO, (LONG_PTR)(info))
 #define GET_WORD(ptr)  (*(WORD *)(ptr))
 #define GET_DWORD(ptr) (*(DWORD *)(ptr))
+#define GET_LONG(ptr) (*(const LONG *)(ptr))
 #define DLG_ISANSI 2
 
 /* INTERNAL STRUCTS **********************************************************/
@@ -172,43 +169,6 @@ DIALOGINFO *DIALOG_get_info( HWND hWnd, BOOL create )
     return dlgInfo;
 }
 
-/***********************************************************************
- *           DIALOG_EnableOwner
- *
- * Helper function for modal dialogs to enable again the
- * owner of the dialog box.
- */
-void DIALOG_EnableOwner( HWND hOwner )
-{
-    /* Owner must be a top-level window */
-    if (hOwner)
-        hOwner = GetAncestor( hOwner, GA_ROOT );
-    if (!hOwner) return;
-    EnableWindow( hOwner, TRUE );
-}
-
-
-/***********************************************************************
- *           DIALOG_DisableOwner
- *
- * Helper function for modal dialogs to disable the
- * owner of the dialog box. Returns TRUE if owner was enabled.
- */
-BOOL DIALOG_DisableOwner( HWND hOwner )
-{
-    /* Owner must be a top-level window */
-    if (hOwner)
-        hOwner = GetAncestor( hOwner, GA_ROOT );
-    if (!hOwner) return FALSE;
-    if (IsWindowEnabled( hOwner ))
-    {
-        EnableWindow( hOwner, FALSE );
-        return TRUE;
-    }
-    else
-        return FALSE;
-}
-
 /***********************************************************************
  *           DIALOG_GetControl32
  *
@@ -237,8 +197,8 @@ static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info,
 
     if (dialogEx)
     {
-        /* id is a DWORD for DIALOGEX */
-        info->id = GET_DWORD(p);
+        /* id is 4 bytes for DIALOGEX */
+        info->id = GET_LONG(p);
         p += 2;
     }
     else
@@ -308,7 +268,7 @@ static const WORD *DIALOG_GetControl32( const WORD *p, DLG_CONTROL_INFO *info,
 
     if (GET_WORD(p))
     {
-        info->data = p + 1;
+        info->data = p;
         p += GET_WORD(p) / sizeof(WORD);
     }
     else info->data = NULL;
@@ -546,7 +506,6 @@ INT DIALOG_DoDialogBox( HWND hwnd, HWND owner )
     DIALOGINFO * dlgInfo;
     MSG msg;
     INT retval;
-    HWND ownerMsg = GetAncestor( owner, GA_ROOT );
     BOOL bFirstEmpty;
     PWND pWnd;
 
@@ -571,7 +530,7 @@ INT DIALOG_DoDialogBox( HWND hwnd, HWND owner )
                 if (!(GetWindowLongPtrW( hwnd, GWL_STYLE ) & DS_NOIDLEMSG))
                {
                     /* No message present -> send ENTERIDLE and wait */
-                    if (ownerMsg) SendMessageW( ownerMsg, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hwnd );
+                    SendMessageW( owner, WM_ENTERIDLE, MSGF_DIALOGBOX, (LPARAM)hwnd );
                 }
                 GetMessageW( &msg, 0, 0, 0 );
             }
@@ -585,16 +544,16 @@ INT DIALOG_DoDialogBox( HWND hwnd, HWND owner )
 
             /*
              * If the user is pressing Ctrl+C, send a WM_COPY message.
-             * Guido Pola, Bug 5281, Is there another way to check if the Dialog it's a MessageBox?
+             * Guido Pola, CORE-4829, Is there another way to check if the Dialog is a MessageBox?
              */
-            ifmsg.message == WM_KEYDOWN &&
+            if (msg.message == WM_KEYDOWN &&
                 pWnd->state & WNDS_MSGBOX && // Yes!
-                GetForegroundWindow() == hwnd )
+                GetForegroundWindow() == hwnd)
             {
-                if( msg.wParam == L'C' && GetKeyState(VK_CONTROL) < 0 )
-                    SendMessageW( hwnd, WM_COPY, 0, 0);
+                if (msg.wParam == L'C' && GetKeyState(VK_CONTROL) < 0)
+                    SendMessageW(hwnd, WM_COPY, 0, 0);
             }
-            
+
             if (!IsWindow( hwnd )) return 0;
             if (!(dlgInfo->flags & DF_END) && !IsDialogMessageW( hwnd, &msg))
             {
@@ -611,7 +570,6 @@ INT DIALOG_DoDialogBox( HWND hwnd, HWND owner )
             }
         }
     }
-    if (dlgInfo->flags & DF_OWNERENABLED) DIALOG_EnableOwner( owner );
     retval = dlgInfo->idResult;
     DestroyWindow( hwnd );
     return retval;
@@ -802,8 +760,7 @@ static void DEFDLG_RestoreFocus( HWND hwnd, BOOL justActivate )
     else
         DEFDLG_SetFocus( infoPtr->hwndFocus );
 
-    /* This used to set infoPtr->hwndFocus to NULL for no apparent reason,
-       sometimes losing focus when receiving WM_SETFOCUS messages. */
+    infoPtr->hwndFocus = NULL;
 }
 
 /***********************************************************************
@@ -816,7 +773,7 @@ static void DEFDLG_RestoreFocus( HWND hwnd, BOOL justActivate )
  */
 static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
                                    HWND owner, DLGPROC dlgProc, LPARAM param,
-                                   BOOL unicode, BOOL modal )
+                                   BOOL unicode, HWND *modal_owner )
 {
     HWND hwnd;
     RECT rect;
@@ -825,7 +782,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
     DLG_TEMPLATE template;
     DIALOGINFO * dlgInfo = NULL;
     DWORD units = GetDialogBaseUnits();
-    BOOL ownerEnabled = TRUE;
+    HWND disabled_owner = NULL;
     HMENU hMenu = 0;
     HFONT hUserFont = 0;
     UINT flags = 0;
@@ -888,10 +845,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
 
     /* Create dialog main window */
 
-    rect.left = rect.top = 0;
-    rect.right = MulDiv(template.cx, xBaseUnit, 4);
-    rect.bottom =  MulDiv(template.cy, yBaseUnit, 8);
-
+    SetRect(&rect, 0, 0, MulDiv(template.cx, xBaseUnit, 4), MulDiv(template.cy, yBaseUnit, 8));
     if (template.style & DS_CONTROL)
         template.style &= ~(WS_CAPTION|WS_SYSMENU);
     template.style |= DS_3DLOOK;
@@ -932,7 +886,10 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
         {
             pos.x += MulDiv(template.x, xBaseUnit, 4);
             pos.y += MulDiv(template.y, yBaseUnit, 8);
-            if (!(template.style & (WS_CHILD|DS_ABSALIGN))) ClientToScreen( owner, &pos );
+            //
+            // REACTOS : Need an owner to be passed!!!
+            //
+            if (!(template.style & (WS_CHILD|DS_ABSALIGN)) && owner ) ClientToScreen( owner, &pos );
         }
         if ( !(template.style & WS_CHILD) )
         {
@@ -955,10 +912,35 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
         }
     }
 
-    if (modal)
+    if (modal_owner && owner)
     {
-        ownerEnabled = DIALOG_DisableOwner( owner );
-        if (ownerEnabled) flags |= DF_OWNERENABLED;
+        HWND parent = NULL;
+        /*
+         * Owner needs to be top level window. We need to duplicate the logic from server,
+         * because we need to disable it before creating dialog window. Note that we do that
+         * even if dialog has WS_CHILD, but only for modal dialogs, which matched what
+         * Windows does.
+         */
+        while ((GetWindowLongW( owner, GWL_STYLE ) & (WS_POPUP|WS_CHILD)) == WS_CHILD)
+        {
+            parent = GetParent( owner );
+            if (!parent || parent == GetDesktopWindow()) break;
+            owner = parent;
+        }
+        ////// Wine'ie babies need to fix your code!!!! CORE-11633
+        if (!parent) parent = GetAncestor( owner, GA_ROOT );
+
+        if (parent)
+        {
+           owner = parent;
+
+           if (IsWindowEnabled( owner ))
+           {
+               disabled_owner = owner;
+               EnableWindow( disabled_owner, FALSE );
+           }
+        }
+        *modal_owner = owner;
     }
 
     if (unicode)
@@ -999,7 +981,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
     {
         if (hUserFont) DeleteObject( hUserFont );
         if (hMenu) DestroyMenu( hMenu );
-        if (modal && (flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
+        if (disabled_owner) EnableWindow( disabled_owner, TRUE );
         return 0;
     }
 
@@ -1012,7 +994,7 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
     {
         if (hUserFont) DeleteObject( hUserFont );
         if (hMenu) DestroyMenu( hMenu );
-        if (modal && (flags & DF_OWNERENABLED)) DIALOG_EnableOwner(owner);
+        if (disabled_owner) EnableWindow( disabled_owner, TRUE );
         return 0;
     }
     //
@@ -1047,13 +1029,23 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
                 /* By returning TRUE, app has requested a default focus assignment.
                  * WM_INITDIALOG may have changed the tab order, so find the first
                  * tabstop control again. */
-                dlgInfo->hwndFocus = GetNextDlgTabItem( hwnd, 0, FALSE );
-                if (!dlgInfo->hwndFocus) dlgInfo->hwndFocus = GetNextDlgGroupItem( hwnd, 0, FALSE );
-                if( dlgInfo->hwndFocus )
-                    SetFocus( dlgInfo->hwndFocus );
+                focus = GetNextDlgTabItem( hwnd, 0, FALSE );
+                if (!focus) focus = GetNextDlgGroupItem( hwnd, 0, FALSE );
+                if (focus)
+                {
+                    if (SendMessageW( focus, WM_GETDLGCODE, 0, 0 ) & DLGC_HASSETSEL)
+                        SendMessageW( focus, EM_SETSEL, 0, MAXLONG );
+                    SetFocus( focus );
+                }
+                else
+                {
+                    if (!(template.style & WS_CHILD))
+                        SetFocus( hwnd );
+                }
             }
-//// ReactOS
-            DEFDLG_SaveFocus( hwnd );
+//// ReactOS see 43396, Fixes setting focus on Open and Close dialogs to the FileName edit control in OpenOffice.
+//// This now breaks test_SaveRestoreFocus.
+            //DEFDLG_SaveFocus( hwnd );
 ////
         }
 //// ReactOS Rev 30613 & 30644
@@ -1063,11 +1055,12 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
         if (template.style & WS_VISIBLE && !(GetWindowLongPtrW( hwnd, GWL_STYLE ) & WS_VISIBLE))
         {
            ShowWindow( hwnd, SW_SHOWNORMAL );   /* SW_SHOW doesn't always work */
+           UpdateWindow( hwnd );
            IntNotifyWinEvent(EVENT_SYSTEM_DIALOGSTART, hwnd, OBJID_WINDOW, CHILDID_SELF, 0);
         }
         return hwnd;
     }
-    if (modal && ownerEnabled) DIALOG_EnableOwner(owner);
+    if (disabled_owner) EnableWindow( disabled_owner, TRUE );
     IntNotifyWinEvent(EVENT_SYSTEM_DIALOGEND, hwnd, OBJID_WINDOW, CHILDID_SELF, 0);
     if( IsWindow(hwnd) )
     {
@@ -1186,7 +1179,53 @@ static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo, HWND hwndNew
     return TRUE;
 }
 
+#ifdef __REACTOS__
+static void DEFDLG_Reposition(HWND hwnd)
+{
+    HMONITOR hMon;
+    MONITORINFO mi = { sizeof(mi) };
+    RECT rc;
+    LONG cx, cy;
+
+    if (GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD)
+        return;
 
+    if (IsIconic(hwnd))
+        return;
+
+    hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
+
+    if (!GetMonitorInfoW(hMon, &mi) || !GetWindowRect(hwnd, &rc))
+        return;
+
+    cx = rc.right - rc.left;
+    cy = rc.bottom - rc.top;
+
+    if (rc.right > mi.rcWork.right)
+    {
+        rc.right = mi.rcWork.right;
+        rc.left = rc.right - cx;
+    }
+    if (rc.bottom > mi.rcWork.bottom - 4)
+    {
+        rc.bottom = mi.rcWork.bottom - 4;
+        rc.top = rc.bottom - cy;
+    }
+
+    if (rc.left < mi.rcWork.left)
+    {
+        rc.left = mi.rcWork.left;
+    }
+    if (rc.top < mi.rcWork.top)
+    {
+        rc.top = mi.rcWork.top;
+    }
+
+    SetWindowPos(hwnd, NULL, rc.left, rc.top, 0, 0,
+                 SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE |
+                 SWP_NOZORDER);
+}
+#endif
 /***********************************************************************
  *           DEFDLG_Proc
  *
@@ -1260,6 +1299,11 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
             }
             return 0;
 
+#ifdef __REACTOS__
+        case DM_REPOSITION:
+            DEFDLG_Reposition(hwnd);
+            return 0;
+#endif
         case WM_NEXTDLGCTL:
             if (dlgInfo)
             {
@@ -1392,6 +1436,7 @@ static INT DIALOG_DlgDirListW( HWND hDlg, LPWSTR spec, INT idLBox,
     HWND hwnd;
     LPWSTR orig_spec = spec;
     WCHAR any[] = {'*','.','*',0};
+    WCHAR star[] = {'*',0};
 
 #define SENDMSG(msg,wparam,lparam) \
     ((attrib & DDL_POSTMSGS) ? PostMessageW( hwnd, msg, wparam, lparam ) \
@@ -1400,10 +1445,16 @@ static INT DIALOG_DlgDirListW( HWND hDlg, LPWSTR spec, INT idLBox,
     TRACE("%p %s %d %d %04x\n", hDlg, debugstr_w(spec), idLBox, idStatic, attrib );
 
     /* If the path exists and is a directory, chdir to it */
-    if (!spec || !spec[0] || SetCurrentDirectoryW( spec )) spec = any;
+    if (!spec || !spec[0] || SetCurrentDirectoryW( spec )) spec = star;
     else
     {
         WCHAR *p, *p2;
+
+        if (!strchrW(spec, '*') && !strchrW(spec, '?'))
+        {
+            SetLastError(ERROR_NO_WILDCARD_CHARACTERS);
+            return FALSE;
+        }
         p = spec;
         if ((p2 = strchrW( p, ':' ))) p = p2 + 1;
         if ((p2 = strrchrW( p, '\\' ))) p = p2;
@@ -1576,7 +1627,7 @@ CreateDialogIndirectParamAorW(
  *   Also wine has one more parameter identifying weather it should call
  *   the function with unicode or not
  */
-  return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit , Flags == DLG_ISANSI ? FALSE : TRUE, FALSE );
+  return DIALOG_CreateIndirect( hInstance, lpTemplate, hWndParent, lpDialogFunc, lParamInit , Flags == DLG_ISANSI ? FALSE : TRUE, NULL );
 }
 
 
@@ -1670,7 +1721,7 @@ DefDlgProcA(
     BOOL result = FALSE;
 
     /* Perform DIALOGINFO initialization if not done */
-    if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0;
+    if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0; //// REACTOS : Always TRUE! See RealGetWindowClass.
 
     SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 );
 
@@ -1692,6 +1743,9 @@ DefDlgProcA(
             case WM_SETFOCUS:
             case DM_SETDEFID:
             case DM_GETDEFID:
+#ifdef __REACTOS__
+            case DM_REPOSITION:
+#endif
             case WM_NEXTDLGCTL:
             case WM_GETFONT:
             case WM_CLOSE:
@@ -1730,7 +1784,7 @@ DefDlgProcW(
     BOOL result = FALSE;
 
     /* Perform DIALOGINFO initialization if not done */
-    if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0;
+    if(!(dlgInfo = DIALOG_get_info( hDlg, TRUE ))) return 0; //// REACTOS : Always TRUE! See RealGetWindowClass.
 
     SetWindowLongPtrW( hDlg, DWLP_MSGRESULT, 0 );
 
@@ -1752,6 +1806,9 @@ DefDlgProcW(
             case WM_SETFOCUS:
             case DM_SETDEFID:
             case DM_GETDEFID:
+#ifdef __REACTOS__
+            case DM_REPOSITION:
+#endif
             case WM_NEXTDLGCTL:
             case WM_GETFONT:
             case WM_CLOSE:
@@ -1792,7 +1849,7 @@ DialogBoxIndirectParamAorW(
  *  Also wine has one more parameter identifying weather it should call
  *  the function with unicode or not
  */
-  HWND hWnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, Flags == DLG_ISANSI ? FALSE : TRUE, TRUE );
+  HWND hWnd = DIALOG_CreateIndirect( hInstance, hDialogTemplate, hWndParent, lpDialogFunc, dwInitParam, Flags == DLG_ISANSI ? FALSE : TRUE, &hWndParent );
   if (hWnd) return DIALOG_DoDialogBox( hWnd, hWndParent );
   return -1;
 }
@@ -1857,7 +1914,7 @@ DialogBoxParamA(
         SetLastError(ERROR_INVALID_WINDOW_HANDLE);
         return 0;
     }
-    hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, FALSE, TRUE);
+    hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, FALSE, &hWndParent );
     if (hwnd) return DIALOG_DoDialogBox(hwnd, hWndParent);
     return -1;
 }
@@ -1890,7 +1947,7 @@ DialogBoxParamW(
         SetLastError(ERROR_INVALID_WINDOW_HANDLE);
         return 0;
     }
-    hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, TRUE, TRUE);
+    hwnd = DIALOG_CreateIndirect(hInstance, ptr, hWndParent, lpDialogFunc, dwInitParam, TRUE, &hWndParent );
     if (hwnd) return DIALOG_DoDialogBox(hwnd, hWndParent);
     return -1;
 }
@@ -2021,7 +2078,7 @@ DlgDirSelectExW(
 
 
 /*
- * @implemented Modified for ReactOS.
+ * @implemented Modified for ReactOS. Do not Port Sync!!!
  */
 BOOL
 WINAPI
@@ -2029,7 +2086,6 @@ EndDialog(
   HWND hwnd,
   INT_PTR retval)
 {
-    BOOL wasEnabled = TRUE;
     DIALOGINFO * dlgInfo;
     HWND owner;
     BOOL wasActive;
@@ -2044,11 +2100,16 @@ EndDialog(
     wasActive = (hwnd == GetActiveWindow());
     dlgInfo->idResult = retval;
     dlgInfo->flags |= DF_END;
-    wasEnabled = (dlgInfo->flags & DF_OWNERENABLED);
 
-    owner = GetWindow( hwnd, GW_OWNER );
-    if (wasEnabled && owner)
-        DIALOG_EnableOwner( owner );
+    if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_POPUP|WS_CHILD)) == WS_CHILD)
+    {
+       owner = GetAncestor( hwnd, GA_PARENT);
+    }
+    else
+       owner = GetWindow( hwnd, GW_OWNER );    
+
+    if (owner)
+        EnableWindow( owner, TRUE );
 
     /* Windows sets the focus to the dialog itself in EndDialog */
 
@@ -2063,9 +2124,7 @@ EndDialog(
 
     if (wasActive && owner)
     {
-        /* 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 this dialog was given an owner then set the focus to that owner. */
         SetActiveWindow(owner);
     }
     else if (hwnd == GetActiveWindow()) // Check it again!
@@ -2265,9 +2324,9 @@ GetNextDlgGroupItem(
      */
     retvalue = hCtl;
     hwnd = hCtl;
-    while (hwndNext = GetWindow (hwnd, GW_HWNDNEXT),
-           1)
+    while (1)
     {
+        hwndNext = GetWindow (hwnd, GW_HWNDNEXT);
         while (!hwndNext)
         {
             /* Climb out until there is a next sibling of the ancestor or we
@@ -2485,6 +2544,9 @@ IsDialogMessageW(
 {
     INT dlgCode = 0;
 
+    if (!IsWindow( hDlg ))
+        return FALSE;
+
     if (CallMsgFilterW( lpMsg, MSGF_DIALOGBOX )) return TRUE;
 
     if (hDlg == GetDesktopWindow()) return FALSE;
@@ -2540,7 +2602,7 @@ IsDialogMessageW(
                             WCHAR *buffer = HeapAlloc (GetProcessHeap(), 0, maxlen * sizeof(WCHAR));
                             if (buffer)
                             {
-                                INT length;
+                                SIZE_T length;
                                 SendMessageW (hwndNext, WM_GETTEXT, maxlen, (LPARAM) buffer);
                                 length = strlenW (buffer);
                                 HeapFree (GetProcessHeap(), 0, buffer);
@@ -2564,8 +2626,16 @@ IsDialogMessageW(
              if (!(dlgCode & DLGC_WANTARROWS))
              {
                  BOOL fPrevious = (lpMsg->wParam == VK_LEFT || lpMsg->wParam == VK_UP);
-                 HWND hwndNext = GetNextDlgGroupItem (hDlg, GetFocus(), fPrevious );
-                 SendMessageW( hDlg, WM_NEXTDLGCTL, (WPARAM)hwndNext, 1 );
+                 HWND hwndNext = GetNextDlgGroupItem( hDlg, lpMsg->hwnd, fPrevious );
+                 if (hwndNext && SendMessageW( hwndNext, WM_GETDLGCODE, lpMsg->wParam, (LPARAM)lpMsg ) == (DLGC_BUTTON | DLGC_RADIOBUTTON))
+                 {
+                     SetFocus( hwndNext );
+                     if ((GetWindowLongW( hwndNext, GWL_STYLE ) & BS_TYPEMASK) == BS_AUTORADIOBUTTON &&
+                         SendMessageW( hwndNext, BM_GETCHECK, 0, 0 ) != BST_CHECKED)
+                         SendMessageW( hwndNext, BM_CLICK, 1, 0 );
+                 }
+                 else
+                     SendMessageW( hDlg, WM_NEXTDLGCTL, (WPARAM)hwndNext, 1 );
                  return TRUE;
              }
              break;
@@ -2579,10 +2649,11 @@ IsDialogMessageW(
          case VK_RETURN:
               {
                  DWORD dw;
-                 if ((GetFocus() == lpMsg->hwnd) &&
-                     (SendMessageW (lpMsg->hwnd, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
+                 HWND hwndFocus = GetFocus();
+                 if (IsChild( hDlg, hwndFocus ) &&
+                     (SendMessageW (hwndFocus, WM_GETDLGCODE, 0, 0) & DLGC_DEFPUSHBUTTON))
                  {
-                     SendMessageW (hDlg, WM_COMMAND, MAKEWPARAM (GetDlgCtrlID(lpMsg->hwnd),BN_CLICKED), (LPARAM)lpMsg->hwnd);
+                     SendMessageW( hDlg, WM_COMMAND, MAKEWPARAM( GetDlgCtrlID( hwndFocus ), BN_CLICKED ), (LPARAM)hwndFocus );
                  }
                  else if (DC_HASDEFID == HIWORD(dw = SendMessageW (hDlg, DM_GETDEFID, 0, 0)))
                  {
@@ -2593,7 +2664,6 @@ IsDialogMessageW(
                  else
                  {
                      SendMessageW( hDlg, WM_COMMAND, IDOK, (LPARAM)GetDlgItem( hDlg, IDOK ) );
-
                  }
              }
              return TRUE;