2020-01-20 01:17:31 -08:00
|
|
|
From 3f238e248fc4fc4415b3ce5e420c798d516d24ee Mon Sep 17 00:00:00 2001
|
2019-07-25 17:33:23 -07:00
|
|
|
From: Hirofumi Katayama <katayama.hirofumi.mz@gmail.com>
|
|
|
|
Date: Mon, 26 Nov 2018 09:09:52 +0900
|
|
|
|
Subject: [PATCH] user32: Implement TileWindows
|
|
|
|
|
|
|
|
Wine lacks the implementations of TileWindows
|
|
|
|
function of window arrangement.
|
|
|
|
|
|
|
|
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=46197
|
|
|
|
Signed-off-by: Hirofumi Katayama <katayama.hirofumi.mz@gmail.com>
|
|
|
|
---
|
2020-01-20 01:17:31 -08:00
|
|
|
dlls/user32/mdi.c | 179 ++++++++++++++++++++++++++++++++++++++++++++--
|
|
|
|
1 file changed, 175 insertions(+), 4 deletions(-)
|
2019-07-25 17:33:23 -07:00
|
|
|
|
|
|
|
diff --git a/dlls/user32/mdi.c b/dlls/user32/mdi.c
|
2020-01-20 01:17:31 -08:00
|
|
|
index 9679be895ed..c752f967b4d 100644
|
2019-07-25 17:33:23 -07:00
|
|
|
--- a/dlls/user32/mdi.c
|
|
|
|
+++ b/dlls/user32/mdi.c
|
|
|
|
@@ -144,6 +144,10 @@ typedef struct
|
|
|
|
|
|
|
|
static HBITMAP hBmpClose = 0;
|
|
|
|
|
|
|
|
+static WCHAR shelltray[] = {'S','h','e','l','l','_','T','r','a','y','W','n','d',0};
|
|
|
|
+static WCHAR progman[] = {'P','r','o','g','m','a','n',0};
|
|
|
|
+
|
|
|
|
+
|
|
|
|
/* ----------------- declarations ----------------- */
|
|
|
|
static void MDI_UpdateFrameText( HWND, HWND, BOOL, LPCWSTR);
|
|
|
|
static BOOL MDI_AugmentFrameMenu( HWND, HWND );
|
2020-01-20 01:17:31 -08:00
|
|
|
@@ -1929,8 +1933,6 @@ WORD WINAPI
|
2019-07-25 17:33:23 -07:00
|
|
|
CascadeWindows (HWND hwndParent, UINT wFlags, const RECT *lpRect,
|
|
|
|
UINT cKids, const HWND *lpKids)
|
|
|
|
{
|
|
|
|
- static WCHAR shelltray[] = {'S','h','e','l','l','_','T','r','a','y','W','n','d',0};
|
|
|
|
- static WCHAR progman[] = {'P','r','o','g','m','a','n',0};
|
|
|
|
CASCADE_INFO info;
|
|
|
|
HWND hwnd, top, prev;
|
|
|
|
HMONITOR monitor;
|
2020-01-20 01:17:31 -08:00
|
|
|
@@ -2084,8 +2086,177 @@ WORD WINAPI
|
2019-07-25 17:33:23 -07:00
|
|
|
TileWindows (HWND hwndParent, UINT wFlags, const RECT *lpRect,
|
|
|
|
UINT cKids, const HWND *lpKids)
|
|
|
|
{
|
|
|
|
- FIXME("(%p,0x%08x,...,%u,...): stub\n", hwndParent, wFlags, cKids);
|
|
|
|
- return 0;
|
|
|
|
+ HWND hwnd, hwndTop, hwndPrev;
|
|
|
|
+ CASCADE_INFO info;
|
|
|
|
+ RECT rcWork, rcWnd;
|
|
|
|
+ DWORD i, iRow, iColumn, cRows, cColumns, ret = 0;
|
|
|
|
+ INT x, y, cx, cy, cxNew, cyNew, cxWork, cyWork, cxCell, cyCell, cxMin2, cyMin3;
|
|
|
|
+ HDWP hDWP;
|
|
|
|
+ MONITORINFO mi;
|
|
|
|
+ HMONITOR hMon;
|
|
|
|
+ POINT pt;
|
|
|
|
+
|
|
|
|
+ TRACE("(%p,0x%08x,...,%u,...)\n", hwndParent, wFlags, cKids);
|
|
|
|
+
|
|
|
|
+ hwndTop = GetTopWindow(hwndParent);
|
|
|
|
+
|
|
|
|
+ ZeroMemory(&info, sizeof(info));
|
|
|
|
+ info.desktop = GetDesktopWindow();
|
|
|
|
+ info.tray_wnd = FindWindowW(shelltray, NULL);
|
|
|
|
+ info.progman = FindWindowW(progman, NULL);
|
|
|
|
+ info.parent = hwndParent;
|
|
|
|
+ info.flags = wFlags;
|
|
|
|
+
|
|
|
|
+ if (cKids == 0 || lpKids == NULL)
|
|
|
|
+ {
|
|
|
|
+ info.top = hwndTop;
|
|
|
|
+ EnumChildWindows(hwndParent, GetCascadeChildProc, (LPARAM)&info);
|
|
|
|
+
|
|
|
|
+ info.top = NULL;
|
|
|
|
+ GetCascadeChildProc(hwndTop, (LPARAM)&info);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ info.wnd_count = cKids;
|
|
|
|
+ info.wnd_array = (HWND *)lpKids;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (info.wnd_count == 0 || info.wnd_array == NULL)
|
|
|
|
+ return ret;
|
|
|
|
+
|
|
|
|
+ if (lpRect)
|
|
|
|
+ {
|
|
|
|
+ rcWork = *lpRect;
|
|
|
|
+ }
|
|
|
|
+ else if (hwndParent)
|
|
|
|
+ {
|
|
|
|
+ GetClientRect(hwndParent, &rcWork);
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ pt.x = pt.y = 0;
|
|
|
|
+ hMon = MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
|
|
|
|
+ mi.cbSize = sizeof(mi);
|
|
|
|
+ GetMonitorInfoW(hMon, &mi);
|
|
|
|
+ rcWork = mi.rcWork;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ cxWork = rcWork.right - rcWork.left;
|
|
|
|
+ cyWork = rcWork.bottom - rcWork.top;
|
|
|
|
+
|
|
|
|
+ cxMin2 = GetSystemMetrics(SM_CXMIN) * 2;
|
|
|
|
+ cyMin3 = GetSystemMetrics(SM_CYMIN) * 3;
|
|
|
|
+
|
|
|
|
+ /* calculate the numbers and widths of columns and rows */
|
|
|
|
+ if (info.flags & MDITILE_HORIZONTAL)
|
|
|
|
+ {
|
|
|
|
+ cColumns = info.wnd_count;
|
|
|
|
+ cRows = 1;
|
|
|
|
+ for (;;)
|
|
|
|
+ {
|
|
|
|
+ cxCell = cxWork / cColumns;
|
|
|
|
+ cyCell = cyWork / cRows;
|
|
|
|
+ if (cyCell <= cyMin3 || cxCell >= cxMin2)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ ++cRows;
|
|
|
|
+ cColumns = (info.wnd_count + cRows - 1) / cRows;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ cRows = info.wnd_count;
|
|
|
|
+ cColumns = 1;
|
|
|
|
+ for (;;)
|
|
|
|
+ {
|
|
|
|
+ cxCell = cxWork / cColumns;
|
|
|
|
+ cyCell = cyWork / cRows;
|
|
|
|
+ if (cxCell <= cxMin2 || cyCell >= cyMin3)
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ ++cColumns;
|
|
|
|
+ cRows = (info.wnd_count + cColumns - 1) / cColumns;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ hDWP = BeginDeferWindowPos(info.wnd_count);
|
|
|
|
+ if (hDWP == NULL)
|
|
|
|
+ goto cleanup;
|
|
|
|
+
|
|
|
|
+ x = rcWork.left;
|
|
|
|
+ y = rcWork.top;
|
|
|
|
+ hwndPrev = NULL;
|
|
|
|
+ iRow = iColumn = 0;
|
|
|
|
+ for (i = info.wnd_count; i > 0;) /* in reverse order */
|
|
|
|
+ {
|
|
|
|
+ --i;
|
|
|
|
+ hwnd = info.wnd_array[i];
|
|
|
|
+
|
|
|
|
+ if (IsZoomed(hwnd))
|
2022-03-17 17:29:35 -07:00
|
|
|
+ NtUserShowWindow(hwnd, SW_RESTORE | SW_SHOWNA);
|
2019-07-25 17:33:23 -07:00
|
|
|
+
|
|
|
|
+ GetWindowRect(hwnd, &rcWnd);
|
|
|
|
+ cx = rcWnd.right - rcWnd.left;
|
|
|
|
+ cy = rcWnd.bottom - rcWnd.top;
|
|
|
|
+
|
|
|
|
+ /* if we can change the window size */
|
|
|
|
+ if (GetWindowLongPtrW(hwnd, GWL_STYLE) & WS_THICKFRAME)
|
|
|
|
+ {
|
|
|
|
+ cxNew = cxCell;
|
|
|
|
+ cyNew = cyCell;
|
|
|
|
+ /* shrink if we can */
|
|
|
|
+ if (QuerySizeFix(hwnd, &cxNew, &cyNew))
|
|
|
|
+ {
|
|
|
|
+ cx = cxNew;
|
|
|
|
+ cy = cyNew;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ hDWP = DeferWindowPos(hDWP, hwnd, HWND_TOP, x, y, cx, cy, SWP_NOACTIVATE);
|
|
|
|
+ if (hDWP == NULL)
|
|
|
|
+ {
|
|
|
|
+ ret = 0;
|
|
|
|
+ goto cleanup;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (info.flags & MDITILE_HORIZONTAL)
|
|
|
|
+ {
|
|
|
|
+ x += cxCell;
|
|
|
|
+ ++iColumn;
|
|
|
|
+ if (iColumn >= cColumns)
|
|
|
|
+ {
|
|
|
|
+ iColumn = 0;
|
|
|
|
+ ++iRow;
|
|
|
|
+ x = rcWork.left;
|
|
|
|
+ y += cyCell;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ y += cyCell;
|
|
|
|
+ ++iRow;
|
|
|
|
+ if (iRow >= cRows)
|
|
|
|
+ {
|
|
|
|
+ iRow = 0;
|
|
|
|
+ ++iColumn;
|
|
|
|
+ x += cxCell;
|
|
|
|
+ y = rcWork.top;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ hwndPrev = hwnd;
|
|
|
|
+ ++ret;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ EndDeferWindowPos(hDWP);
|
|
|
|
+
|
|
|
|
+ if (hwndPrev)
|
|
|
|
+ SetForegroundWindow(hwndPrev);
|
|
|
|
+
|
|
|
|
+cleanup:
|
|
|
|
+ if (cKids == 0 || lpKids == NULL)
|
|
|
|
+ HeapFree(GetProcessHeap(), 0, info.wnd_array);
|
|
|
|
+
|
|
|
|
+ return (WORD)ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
--
|
2020-01-20 01:17:31 -08:00
|
|
|
2.24.1
|
2019-07-25 17:33:23 -07:00
|
|
|
|