From: "katahiromz ." Subject: [PATCH v10] user32: Implement DM_REPOSITION. Message-Id: Date: Sat, 16 Nov 2019 13:38:17 +0900 See attachment. From 1535e6e456713b15ac133dd18cbc61e725d08d53 Mon Sep 17 00:00:00 2001 From: Hirofumi Katayama Date: Sat, 16 Nov 2019 13:04:55 +0900 Subject: [PATCH v10] user32: Implement DM_REPOSITION. DM_REPOSITION is dialog message that can reposition the workarea when the dialog is partially/entirely in outside of the workarea. Signed-off-by: Hirofumi Katayama --- dlls/user32/defdlg.c | 48 ++++++++++++++++++++++++ dlls/user32/tests/dialog.c | 77 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/dlls/user32/defdlg.c b/dlls/user32/defdlg.c index 00a73c6b92..1210477f77 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; + LONG width, height; + + if (GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD) + return; + + hMon = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST); + + if (!GetMonitorInfoW(hMon, &mi) || !GetWindowRect(hwnd, &rc)) + return; + + width = rc.right - rc.left; + height = rc.bottom - rc.top; + + if (rc.right > mi.rcWork.right) + { + rc.right = mi.rcWork.right; + rc.left = rc.right - width; + } + if (rc.bottom > mi.rcWork.bottom - 4) + { + rc.bottom = mi.rcWork.bottom - 4; + rc.top = rc.bottom - height; + } + + 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..1e20e6770b 100644 --- a/dlls/user32/tests/dialog.c +++ b/dlls/user32/tests/dialog.c @@ -2174,6 +2174,82 @@ static void test_dialog_custom_data(void) DialogBoxA(g_hinst, "CUSTOM_TEST_DIALOG", NULL, custom_test_dialog_proc); } +static INT_PTR CALLBACK reposition_test_dialog_proc(HWND hdlg, UINT msg, WPARAM wparam, LPARAM lparam) +{ + if (msg == WM_INITDIALOG) + { + RECT rc, rcWork; + INT width, height; + HMONITOR hMon; + MONITORINFO mi = { sizeof(mi) }; + + /* get monitor info */ + hMon = MonitorFromWindow(hdlg, MONITOR_DEFAULTTONEAREST); + ok(hMon != NULL, "hMon is NULL\n"); + ok(GetMonitorInfoW(hMon, &mi) == TRUE, "GetMonitorInfoW failed\n"); + rcWork = mi.rcWork; + + /* get size */ + GetWindowRect(hdlg, &rc); + width = rc.right - rc.left; + height = rc.bottom - rc.top; + + /* move */ + ok(SetWindowPos(hdlg, NULL, rcWork.left - 80, rcWork.top - 80, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER | + SWP_NOZORDER) == TRUE, "SetWindowPos failed\n"); + ok(GetWindowRect(hdlg, &rc) == TRUE, "GetWindowRect failed\n"); + ok(rc.left == rcWork.left - 80, "rc.left:%ld, rcWork.left:%ld\n", rc.left, rcWork.left); + ok(rc.top == rcWork.top - 80, "rc.top:%ld, rcWork.top:%ld\n", rc.top, rcWork.top); + ok(rc.right == rc.left + width, "rc.right:%ld, rc.left:%ld, width:%d\n", rc.right, rc.left, width); + ok(rc.bottom == rc.top + height, "rc.bottom:%ld, rc.top:%ld, height:%d\n", rc.bottom, rc.top, height); + + /* reposition */ + ok(SendMessageW(hdlg, DM_REPOSITION, 0, 0) == 0, "SendMessageW returned non-zero\n"); + ok(GetWindowRect(hdlg, &rc) == TRUE, "GetWindowRect failed\n"); + ok(rc.left == rcWork.left, "rc.left:%ld, rcWork.left:%ld\n", rc.left, rcWork.left); + ok(rc.top == rcWork.top, "rc.top:%ld, rcWork.top:%ld\n", rc.top, rcWork.top); + ok(rc.right == rc.left + width, "rc.right:%ld, rc.left:%ld, width:%d\n", rc.right, rc.left, width); + ok(rc.bottom == rc.top + height, "rc.bottom:%ld, rc.top:%ld, height:%d\n", rc.bottom, rc.top, height); + + /* move */ + ok(SetWindowPos(hdlg, NULL, + rcWork.right - width + 80, rcWork.bottom - height + 80, 0, 0, + SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOOWNERZORDER | + SWP_NOZORDER) == TRUE, "SetWindowPos failed\n"); + ok(GetWindowRect(hdlg, &rc) == TRUE, "GetWindowRect failed\n"); + ok(rc.left == rcWork.right - width + 80, "rc.left:%ld, rcWork.right:%ld, width:%d\n", + rc.left, rcWork.right, width); + ok(rc.top == rcWork.bottom - height + 80, "rc.top:%ld, rcWork.bottom:%ld, height:%d\n", + rc.top, rcWork.bottom, height); + ok(rc.right == rc.left + width, "rc.right:%ld, rc.left:%ld, width:%d\n", + rc.right, rc.left, width); + ok(rc.bottom == rc.top + height, "rc.bottom:%ld, rc.top:%ld, height:%d\n", + rc.bottom, rc.top, height); + + /* reposition */ + ok(SendMessageW(hdlg, DM_REPOSITION, 0, 0) == 0, "SendMessageW returned non-zero\n"); + ok(GetWindowRect(hdlg, &rc) == TRUE, "GetWindowRect failed\n"); + ok(rc.left == rcWork.right - width, "rc.left:%ld, rcWork.right:%ld, width:%d\n", + rc.left, rcWork.right, width); + ok(rc.top == rcWork.bottom - height - 4, "rc.top:%ld, rcWork.bottom:%ld, height:%d", + rc.top, rcWork.bottom, height); + ok(rc.right == rc.left + width, "rc.right:%ld, rc.left:%ld, width:%d\n", + rc.right, rc.left, width); + ok(rc.bottom == rc.top + height, "rc.bottom:%ld, rc.top:%ld, height:%d\n", + rc.bottom, rc.top, height); + + EndDialog(hdlg, 0); + } + + return FALSE; +} + +static void test_DM_REPOSITION(void) +{ + DialogBoxA(g_hinst, "CUSTOM_TEST_DIALOG", NULL, reposition_test_dialog_proc); +} + START_TEST(dialog) { g_hinst = GetModuleHandleA (0); @@ -2193,4 +2269,5 @@ START_TEST(dialog) test_SaveRestoreFocus(); test_timer_message(); test_MessageBox(); + test_DM_REPOSITION(); } -- 2.23.0