From bbc3788d1b290bc71904e9f26921c34a281f076d Mon Sep 17 00:00:00 2001
From: Hirofumi Katayama <katayama.hirofumi.mz@gmail.com>
Date: Thu, 7 Nov 2019 18:17:26 +0900
Subject: [PATCH v6] user32: Implement DM_REPOSITION message

Dialog Message DM_REPOSITION was not implemented.
This message realizes repositioning of dialog boxes.
Test is also added.

Signed-off-by: Hirofumi Katayama <katayama.hirofumi.mz@gmail.com>
---
 dlls/user32/defdlg.c       | 48 ++++++++++++++++++++++++++++++++++++++
 dlls/user32/tests/dialog.c | 35 +++++++++++++++++++++++++++
 2 files changed, 83 insertions(+)

diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c
index 00a73c6b92..7bdf0cf301 100644
--- a/dlls/user32/defdlg.c
+++ b/dlls/user32/defdlg.c
@@ -208,6 +208,48 @@ static BOOL DEFDLG_SetDefButton( HWND hwndDlg, DIALOGINFO *dlgInfo, HWND hwndNew
     return TRUE;
 }
 
+static void DEFDLG_Reposition(HWND hwnd)
+{
+    HMONITOR hMon;
+    MONITORINFO mi = { sizeof(mi) };
+    RECT rc;
+    SIZE size;
+
+    if (GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD)
+        return;
+
+    hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY);
+
+    if (!GetMonitorInfoW(hMon, &mi) || !GetWindowRect(hwnd, &rc))
+        return;
+
+    size.cx = rc.right - rc.left;
+    size.cy = rc.bottom - rc.top;
+
+    if (rc.right > mi.rcWork.right)
+    {
+        rc.right = mi.rcWork.right;
+        rc.left = rc.right - size.cx;
+    }
+    if (rc.bottom > mi.rcWork.bottom)
+    {
+        rc.bottom = mi.rcWork.bottom;
+        rc.top = rc.bottom - size.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);
+}
 
 /***********************************************************************
  *           DEFDLG_Proc
@@ -279,6 +321,10 @@ static LRESULT DEFDLG_Proc( HWND hwnd, UINT msg, WPARAM wParam,
             }
             return 0;
 
+        case DM_REPOSITION:
+            DEFDLG_Reposition(hwnd);
+            return 0;
+
         case WM_NEXTDLGCTL:
             if (dlgInfo)
             {
@@ -383,6 +429,7 @@ LRESULT WINAPI DefDlgProcA( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
             case WM_SETFOCUS:
             case DM_SETDEFID:
             case DM_GETDEFID:
+            case DM_REPOSITION:
             case WM_NEXTDLGCTL:
             case WM_GETFONT:
             case WM_CLOSE:
@@ -441,6 +488,7 @@ LRESULT WINAPI DefDlgProcW( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam )
             case WM_SETFOCUS:
             case DM_SETDEFID:
             case DM_GETDEFID:
+            case DM_REPOSITION:
             case WM_NEXTDLGCTL:
             case WM_GETFONT:
             case WM_CLOSE:
diff --git a/dlls/user32/tests/dialog.c b/dlls/user32/tests/dialog.c
index b72f08816d..3d1a3f2ffd 100644
--- a/dlls/user32/tests/dialog.c
+++ b/dlls/user32/tests/dialog.c
@@ -2174,6 +2174,40 @@ static void test_dialog_custom_data(void)
     DialogBoxA(g_hinst, "CUSTOM_TEST_DIALOG", NULL, custom_test_dialog_proc);
 }
 
+static INT_PTR CALLBACK reposition_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+    RECT rc;
+    SIZE size;
+
+    if (msg == WM_INITDIALOG)
+    {
+        GetWindowRect(hdlg, &rc);
+        size.cx = rc.right - rc.left;
+        size.cy = rc.bottom - rc.top;
+
+        MoveWindow(hdlg, -100, -100, size.cx, size.cy, TRUE);
+
+        GetWindowRect(hdlg, &rc);
+        ok(rc.left == -100, "rc.left was %ld\n", rc.left);
+        ok(rc.top == -100, "rc.top was %ld\n", rc.top);
+
+        SendMessageW(hdlg, DM_REPOSITION, 0, 0);
+
+        GetWindowRect(hdlg, &rc);
+        ok(rc.left == 0, "rc.left was %ld\n", rc.left);
+        ok(rc.top == 0, "rc.top was %ld\n", rc.top);
+
+        EndDialog(hdlg, 0);
+    }
+
+    return FALSE;
+}
+
+static void test_DM_REPOSITION(void)
+{
+    DialogBoxA(g_hinst, "CUSTOM_TEST_DIALOG", NULL, reposition_dialog_proc);
+}
+
 START_TEST(dialog)
 {
     g_hinst = GetModuleHandleA (0);
@@ -2193,4 +2227,5 @@ START_TEST(dialog)
     test_SaveRestoreFocus();
     test_timer_message();
     test_MessageBox();
+    test_DM_REPOSITION();
 }
-- 
2.23.0

