[USER32] Check whether the window is minimized upon SM_REPOSITION CORE-16490
[reactos.git] / win32ss / user / user32 / windows / dialog.c
index aa39401..1acb4f5 100644 (file)
@@ -19,7 +19,7 @@
 /*
  * PROJECT:         ReactOS user32.dll
  * FILE:            win32ss/user/user32/windows/dialog.c
- * PURPOSE:         Input
+ * 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 ********************************************************/
@@ -44,6 +41,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(user32);
 #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 **********************************************************/
@@ -199,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
@@ -1039,6 +1037,11 @@ static HWND DIALOG_CreateIndirect( HINSTANCE hInst, LPCVOID dlgTemplate,
                         SendMessageW( focus, EM_SETSEL, 0, MAXLONG );
                     SetFocus( focus );
                 }
+                else
+                {
+                    if (!(template.style & WS_CHILD))
+                        SetFocus( hwnd );
+                }
             }
 //// ReactOS see 43396, Fixes setting focus on Open and Close dialogs to the FileName edit control in OpenOffice.
 //// This now breaks test_SaveRestoreFocus.
@@ -1176,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
  *
@@ -1250,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)
             {
@@ -1382,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 ) \
@@ -1390,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;
@@ -1682,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:
@@ -1742,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:
@@ -2257,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
@@ -2535,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);
@@ -2559,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;
@@ -2574,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)))
                  {
@@ -2588,7 +2664,6 @@ IsDialogMessageW(
                  else
                  {
                      SendMessageW( hDlg, WM_COMMAND, IDOK, (LPARAM)GetDlgItem( hDlg, IDOK ) );
-
                  }
              }
              return TRUE;