diff --git a/base/shell/explorer/taskswnd.cpp b/base/shell/explorer/taskswnd.cpp index dcbc5cb7be5..78ab5ca5cfb 100644 --- a/base/shell/explorer/taskswnd.cpp +++ b/base/shell/explorer/taskswnd.cpp @@ -1551,14 +1551,24 @@ public: ::SetForegroundWindow(m_Tray->GetHWND()); break; + case HSHELL_GETMINRECT: + if (lParam) + { + SHELLHOOKINFO *HookInfo = (SHELLHOOKINFO *)lParam; + POINTS *ppts = (POINTS *)&HookInfo->rc; + ppts[0].x = ppts[0].y = -32000; + ppts[1].x = ppts[0].x + GetSystemMetrics(SM_CXMINIMIZED); + ppts[1].y = ppts[0].y + GetSystemMetrics(SM_CYMINIMIZED); + return TRUE; + } + break; + case HSHELL_LANGUAGE: case HSHELL_SYSMENU: case HSHELL_ENDTASK: case HSHELL_ACCESSIBILITYSTATE: case HSHELL_WINDOWREPLACED: case HSHELL_WINDOWREPLACING: - - case HSHELL_GETMINRECT: default: { #if DEBUG_SHELL_HOOK diff --git a/sdk/include/reactos/undocuser.h b/sdk/include/reactos/undocuser.h index b2bc7a8ccc9..538ed0b9e6f 100644 --- a/sdk/include/reactos/undocuser.h +++ b/sdk/include/reactos/undocuser.h @@ -403,6 +403,12 @@ typedef enum tagSETIMEHOTKEY_ACTION SETIMEHOTKEY_INITIALIZE } SETIMEHOTKEY_ACTION; +typedef struct tagSHELLHOOKINFO +{ + HWND hwnd; + RECT rc; +} SHELLHOOKINFO, *PSHELLHOOKINFO, *LPSHELLHOOKINFO; + #ifdef __cplusplus } /* extern "C" */ #endif /* defined(__cplusplus) */ diff --git a/win32ss/user/ntuser/desktop.c b/win32ss/user/ntuser/desktop.c index 6ccb291ac82..343b7e492c2 100644 --- a/win32ss/user/ntuser/desktop.c +++ b/win32ss/user/ntuser/desktop.c @@ -1646,7 +1646,6 @@ IntHideDesktop(PDESKTOP Desktop) return STATUS_SUCCESS; } -static HWND* FASTCALL UserBuildShellHookHwndList(PDESKTOP Desktop) { diff --git a/win32ss/user/ntuser/winpos.c b/win32ss/user/ntuser/winpos.c index 2e5822994f3..5ef40319c3b 100644 --- a/win32ss/user/ntuser/winpos.c +++ b/win32ss/user/ntuser/winpos.c @@ -777,6 +777,49 @@ co_WinPosArrangeIconicWindows(PWND parent) return yspacing; } +HWND* FASTCALL UserBuildShellHookHwndList(PDESKTOP Desktop); + +BOOL UserSendMinRectMessages(PWND pWnd, LPRECT prc) +{ + PDESKTOP Desktop = IntGetActiveDesktop(); + HWND *HwndList, *cursor, hwndTarget = UserHMGetHandle(pWnd); + BOOL ret = FALSE; + ULONG_PTR ulResult; + + if (ISITHOOKED(WH_SHELL)) + { + co_HOOK_CallHooks(WH_SHELL, HSHELL_GETMINRECT, (WPARAM)hwndTarget, (LPARAM)prc); + ret = TRUE; + } + + if (!gpsi->uiShellMsg) + gpsi->uiShellMsg = IntAddAtom(L"SHELLHOOK"); + + if (!Desktop) + { + TRACE("IntShellHookNotify: No desktop!\n"); + return ret; + } + + HwndList = UserBuildShellHookHwndList(Desktop); + if (HwndList) + { + for (cursor = HwndList; *cursor; cursor++) + { + if (co_IntSendMessageTimeout(*cursor, WM_KLUDGEMINRECT, + (WPARAM)hwndTarget, (LPARAM)prc, + 0, 100, &ulResult)) + { + ret = TRUE; + } + } + + ExFreePoolWithTag(HwndList, USERTAG_WINDOWLIST); + } + + return ret; +} + static VOID FASTCALL WinPosFindIconPos(PWND Window, POINT *Pos) { @@ -787,16 +830,31 @@ WinPosFindIconPos(PWND Window, POINT *Pos) pwndParent = Window->spwndParent; if (UserIsDesktopWindow(pwndParent)) { - ERR("FIXME: Parent is Desktop, Min off screen!\n"); - /* FIXME: ReactOS doesn't support iconic minimize to desktop */ - Pos->x = Pos->y = -32000; - Window->InternalPos.flags |= WPF_MININIT; - Window->InternalPos.IconPos.x = Pos->x; - Window->InternalPos.IconPos.y = Pos->y; - return; + POINT pt; + PMONITOR monitor; + RECTL rc = { 0, 0, 0, 0 }; + UserSendMinRectMessages(Window, &rc); + if (!RECTL_bIsEmptyRect(&rc)) + { + Pos->x = rc.left; + Pos->y = rc.top; + Window->InternalPos.IconPos.x = Pos->x; + Window->InternalPos.IconPos.y = Pos->y; + Window->InternalPos.flags |= WPF_MININIT; + TRACE("Position is set! X:%d Y:%d\n",Pos->x,Pos->y); + return; + } + pt.x = Window->rcWindow.left; + pt.y = Window->rcWindow.top; + monitor = UserMonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST); + if (!monitor) + return; + rectParent = monitor->rcWork; + } + else + { + IntGetClientRect(pwndParent, &rectParent); } - - IntGetClientRect( pwndParent, &rectParent ); // FIXME: Support Minimize Metrics gspv.mm.iArrange. // Default: ARW_BOTTOMLEFT x = rectParent.left; diff --git a/win32ss/user/user32/windows/defwnd.c b/win32ss/user/user32/windows/defwnd.c index 852f2281dd9..38b5ac0c179 100644 --- a/win32ss/user/user32/windows/defwnd.c +++ b/win32ss/user/user32/windows/defwnd.c @@ -1029,6 +1029,27 @@ NormalImeMsgHandling: goto NormalImeMsgHandling; } + case WM_KLUDGEMINRECT: + { + LPRECT prc = (LPRECT)lParam; + SHELLHOOKINFO HookInfo; + POINTS *ppts = (POINTS *)&HookInfo.rc; + + HookInfo.hwnd = (HWND)wParam; + ppts[0].x = (SHORT)prc->left; + ppts[0].y = (SHORT)prc->top; + ppts[1].x = (SHORT)prc->right; + ppts[1].y = (SHORT)prc->bottom; + + if (!gpsi->uiShellMsg) + SetTaskmanWindow(NULL); + + if (SendMessageA(hWnd, gpsi->uiShellMsg, HSHELL_GETMINRECT, (LPARAM)&HookInfo)) + SetRect(prc, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y); + + return 0; + } + default: Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, FALSE); } @@ -1230,6 +1251,27 @@ NormalImeMsgHandling: goto NormalImeMsgHandling; } + case WM_KLUDGEMINRECT: + { + LPRECT prc = (LPRECT)lParam; + SHELLHOOKINFO HookInfo; + POINTS *ppts = (POINTS *)&HookInfo.rc; + + HookInfo.hwnd = (HWND)wParam; + ppts[0].x = (SHORT)prc->left; + ppts[0].y = (SHORT)prc->top; + ppts[1].x = (SHORT)prc->right; + ppts[1].y = (SHORT)prc->bottom; + + if (!gpsi->uiShellMsg) + SetTaskmanWindow(NULL); + + if (SendMessageA(hWnd, gpsi->uiShellMsg, HSHELL_GETMINRECT, (LPARAM)&HookInfo)) + SetRect(prc, ppts[0].x, ppts[0].y, ppts[1].x, ppts[1].y); + + return 0; + } + default: Result = User32DefWindowProc(hWnd, Msg, wParam, lParam, TRUE); }