https://git.reactos.org/?p=reactos.git;a=commitdiff;h=bfc6b719cfccb199ce8b0f...
commit bfc6b719cfccb199ce8b0f656dce174a1a9a3a79 Author: Katayama Hirofumi MZ katayama.hirofumi.mz@gmail.com AuthorDate: Thu Jul 26 21:34:00 2018 +0900 Commit: Hermès BÉLUSCA - MAÏTO hermes.belusca-maito@reactos.org CommitDate: Thu Jul 26 14:34:00 2018 +0200
[USER32][WIN32SS] Implement TileWindows function (#678)
CORE-14815 --- win32ss/user/user32/windows/mdi.c | 189 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 181 insertions(+), 8 deletions(-)
diff --git a/win32ss/user/user32/windows/mdi.c b/win32ss/user/user32/windows/mdi.c index 5e892de252..5d9d8bd6ff 100644 --- a/win32ss/user/user32/windows/mdi.c +++ b/win32ss/user/user32/windows/mdi.c @@ -2047,7 +2047,7 @@ GetCascadeChildProc(HWND hwnd, LPARAM lParam) return TRUE; }
-static void +static BOOL QuerySizeFix(HWND hwnd, LPINT pcx, LPINT pcy) { MINMAXINFO mmi; @@ -2060,7 +2060,9 @@ QuerySizeFix(HWND hwnd, LPINT pcx, LPINT pcy) { *pcx = min(max(*pcx, mmi.ptMinTrackSize.x), mmi.ptMaxTrackSize.x); *pcy = min(max(*pcy, mmi.ptMinTrackSize.y), mmi.ptMaxTrackSize.y); + return TRUE; } + return FALSE; }
WORD WINAPI @@ -2162,9 +2164,11 @@ CascadeWindows(HWND hwndParent, UINT wFlags, LPCRECT lpRect, if (cx != cxNew || cy != cyNew) { /* too large. shrink if we can */ - QuerySizeFix(hwnd, &cxNew, &cyNew); - cx = cxNew; - cy = cyNew; + if (QuerySizeFix(hwnd, &cxNew, &cyNew)) + { + cx = cxNew; + cy = cyNew; + } } }
@@ -2216,11 +2220,180 @@ WORD WINAPI CascadeChildWindows( HWND parent, UINT flags ) * Failure: 0 */ WORD WINAPI -TileWindows (HWND hwndParent, UINT wFlags, LPCRECT lpRect, - UINT cKids, const HWND *lpKids) +TileWindows(HWND hwndParent, UINT wFlags, LPCRECT 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.hwndDesktop = GetDesktopWindow(); + info.hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL); + info.hwndProgman = FindWindowW(L"Progman", NULL); + info.hwndParent = hwndParent; + info.wFlags = wFlags; + + if (cKids == 0 || lpKids == NULL) + { + info.hwndTop = hwndTop; + EnumChildWindows(hwndParent, GetCascadeChildProc, (LPARAM)&info); + + info.hwndTop = NULL; + GetCascadeChildProc(hwndTop, (LPARAM)&info); + } + else + { + info.chwnd = cKids; + info.ahwnd = (HWND *)lpKids; + } + + if (info.chwnd == 0 || info.ahwnd == 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.wFlags & MDITILE_HORIZONTAL) + { + cColumns = info.chwnd; + cRows = 1; + for (;;) + { + cxCell = cxWork / cColumns; + cyCell = cyWork / cRows; + if (cyCell <= cyMin3 || cxCell >= cxMin2) + break; + + ++cRows; + cColumns = (info.chwnd + cRows - 1) / cRows; + } + } + else + { + cRows = info.chwnd; + cColumns = 1; + for (;;) + { + cxCell = cxWork / cColumns; + cyCell = cyWork / cRows; + if (cxCell <= cxMin2 || cyCell >= cyMin3) + break; + + ++cColumns; + cRows = (info.chwnd + cColumns - 1) / cColumns; + } + } + + hDWP = BeginDeferWindowPos(info.chwnd); + if (hDWP == NULL) + goto cleanup; + + x = rcWork.left; + y = rcWork.top; + hwndPrev = NULL; + iRow = iColumn = 0; + for (i = info.chwnd; i > 0;) /* in reverse order */ + { + --i; + hwnd = info.ahwnd[i]; + + if (IsZoomed(hwnd)) + ShowWindow(hwnd, SW_RESTORE | SW_SHOWNA); + + 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.wFlags & 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.ahwnd); + + return (WORD)ret; }