📄 winpos.c
字号:
}
}
if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
co_IntPostOrSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
return TRUE;
}
LRESULT FASTCALL
co_WinPosGetNonClientSize(PWINDOW_OBJECT Window, RECT* WindowRect, RECT* ClientRect)
{
LRESULT Result;
ASSERT_REFS_CO(Window);
*ClientRect = *WindowRect;
Result = co_IntSendMessage(Window->hSelf, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);
FixClientRect(ClientRect, WindowRect);
return Result;
}
BOOLEAN FASTCALL
co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
{
BOOLEAN WasVisible;
UINT Swp = 0;
RECT NewPos;
BOOLEAN ShowFlag;
// HRGN VisibleRgn;
ASSERT_REFS_CO(Window);
WasVisible = (Window->Style & WS_VISIBLE) != 0;
switch (Cmd)
{
case SW_HIDE:
{
if (!WasVisible)
{
return(FALSE);
}
Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
if (Window->hSelf != UserGetActiveWindow())
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
break;
}
case SW_SHOWMINNOACTIVE:
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
case SW_SHOWMINIMIZED:
Swp |= SWP_SHOWWINDOW;
/* Fall through. */
case SW_MINIMIZE:
{
Swp |= SWP_NOACTIVATE;
if (!(Window->Style & WS_MINIMIZE))
{
Swp |= co_WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos) |
SWP_FRAMECHANGED;
}
else
{
Swp |= SWP_NOSIZE | SWP_NOMOVE;
if (! WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
}
break;
}
case SW_SHOWMAXIMIZED:
{
Swp |= SWP_SHOWWINDOW;
if (!(Window->Style & WS_MAXIMIZE))
{
Swp |= co_WinPosMinMaximize(Window, SW_MAXIMIZE, &NewPos) |
SWP_FRAMECHANGED;
}
else
{
Swp |= SWP_NOSIZE | SWP_NOMOVE;
if (! WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
}
break;
}
case SW_SHOWNA:
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
case SW_SHOW:
Swp |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE;
/* Don't activate the topmost window. */
break;
case SW_SHOWNOACTIVATE:
//Swp |= SWP_NOZORDER;
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
/* Fall through. */
case SW_SHOWNORMAL:
case SW_SHOWDEFAULT:
case SW_RESTORE:
Swp |= SWP_SHOWWINDOW;
if (Window->Style & (WS_MINIMIZE | WS_MAXIMIZE))
{
Swp |= co_WinPosMinMaximize(Window, SW_RESTORE, &NewPos) |
SWP_FRAMECHANGED;
}
else
{
Swp |= SWP_NOSIZE | SWP_NOMOVE;
if (! WasVisible)
{
Swp |= SWP_FRAMECHANGED;
}
}
break;
}
ShowFlag = (Cmd != SW_HIDE);
if (ShowFlag != WasVisible)
{
co_IntSendMessage(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0);
}
/* We can't activate a child window */
if ((Window->Style & WS_CHILD) &&
!(Window->ExStyle & WS_EX_MDICHILD))
{
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
co_WinPosSetWindowPos(Window, 0 != (Window->ExStyle & WS_EX_TOPMOST)
? HWND_TOPMOST : HWND_TOP,
NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, LOWORD(Swp));
if (Cmd == SW_HIDE)
{
PWINDOW_OBJECT ThreadFocusWindow;
/* FIXME: This will cause the window to be activated irrespective
* of whether it is owned by the same thread. Has to be done
* asynchronously.
*/
if (Window->hSelf == UserGetActiveWindow())
{
co_WinPosActivateOtherWindow(Window);
}
//temphack
ThreadFocusWindow = UserGetWindowObject(IntGetThreadFocusWindow());
/* Revert focus to parent */
if (ThreadFocusWindow && (Window == ThreadFocusWindow ||
IntIsChildWindow(Window, ThreadFocusWindow)))
{
//faxme: as long as we have ref on Window, we also, indirectly, have ref on parent...
co_UserSetFocus(Window->Parent);
}
}
/* FIXME: Check for window destruction. */
if ((Window->Flags & WINDOWOBJECT_NEED_SIZE) &&
!(Window->Status & WINDOWSTATUS_DESTROYING))
{
WPARAM wParam = SIZE_RESTORED;
Window->Flags &= ~WINDOWOBJECT_NEED_SIZE;
if (Window->Style & WS_MAXIMIZE)
{
wParam = SIZE_MAXIMIZED;
}
else if (Window->Style & WS_MINIMIZE)
{
wParam = SIZE_MINIMIZED;
}
co_IntSendMessage(Window->hSelf, WM_SIZE, wParam,
MAKELONG(Window->ClientRect.right -
Window->ClientRect.left,
Window->ClientRect.bottom -
Window->ClientRect.top));
co_IntSendMessage(Window->hSelf, WM_MOVE, 0,
MAKELONG(Window->ClientRect.left,
Window->ClientRect.top));
IntEngWindowChanged(Window, WOC_RGN_CLIENT);
}
/* Activate the window if activation is not requested and the window is not minimized */
/*
if (!(Swp & (SWP_NOACTIVATE | SWP_HIDEWINDOW)) && !(Window->Style & WS_MINIMIZE))
{
WinPosChangeActiveWindow(Wnd, FALSE);
}
*/
return(WasVisible);
}
#if 0
/* find child of 'parent' that contains the given point (in parent-relative coords) */
PWINDOW_OBJECT child_window_from_point(PWINDOW_OBJECT parent, int x, int y )
{
PWINDOW_OBJECT Wnd;// = parent->FirstChild;
// LIST_FOR_EACH_ENTRY( Wnd, &parent->children, struct window, entry )
for (Wnd = parent->FirstChild; Wnd; Wnd = Wnd->NextSibling)
{
if (!IntPtInWindow( Wnd, x, y )) continue; /* skip it */
/* if window is minimized or disabled, return at once */
if (Wnd->Style & (WS_MINIMIZE|WS_DISABLED)) return Wnd;
/* if point is not in client area, return at once */
if (x < Wnd->ClientRect.left || x >= Wnd->ClientRect.right ||
y < Wnd->ClientRect.top || y >= Wnd->ClientRect.bottom)
return Wnd;
return child_window_from_point( Wnd, x - Wnd->ClientRect.left, y - Wnd->ClientRect.top );
}
return parent; /* not found any child */
}
#endif
/* wine server: child_window_from_point
Caller must dereference the "returned" Window
*/
static
VOID FASTCALL
co_WinPosSearchChildren(
PWINDOW_OBJECT ScopeWin,
PUSER_MESSAGE_QUEUE OnlyHitTests,
POINT *Point,
PWINDOW_OBJECT* Window,
USHORT *HitTest
)
{
PWINDOW_OBJECT Current;
HWND *List, *phWnd;
USER_REFERENCE_ENTRY Ref;
ASSERT_REFS_CO(ScopeWin);
if ((List = IntWinListChildren(ScopeWin)))
{
for (phWnd = List; *phWnd; ++phWnd)
{
if (!(Current = UserGetWindowObject(*phWnd)))
continue;
if (!(Current->Style & WS_VISIBLE))
{
continue;
}
if ((Current->Style & (WS_POPUP | WS_CHILD | WS_DISABLED)) ==
(WS_CHILD | WS_DISABLED))
{
continue;
}
if (!IntPtInWindow(Current, Point->x, Point->y))
{
continue;
}
if (*Window) UserDerefObject(*Window);
*Window = Current;
UserRefObject(*Window);
if (Current->Style & WS_MINIMIZE)
{
*HitTest = HTCAPTION;
break;
}
if (Current->Style & WS_DISABLED)
{
*HitTest = HTERROR;
break;
}
UserRefObjectCo(Current, &Ref);
if (OnlyHitTests && (Current->MessageQueue == OnlyHitTests))
{
*HitTest = co_IntSendMessage(Current->hSelf, WM_NCHITTEST, 0,
MAKELONG(Point->x, Point->y));
if ((*HitTest) == (USHORT)HTTRANSPARENT)
{
UserDerefObjectCo(Current);
continue;
}
}
else
*HitTest = HTCLIENT;
if (Point->x >= Current->ClientRect.left &&
Point->x < Current->ClientRect.right &&
Point->y >= Current->ClientRect.top &&
Point->y < Current->ClientRect.bottom)
{
co_WinPosSearchChildren(Current, OnlyHitTests, Point, Window, HitTest);
}
UserDerefObjectCo(Current);
break;
}
ExFreePool(List);
}
}
/* wine: WINPOS_WindowFromPoint */
USHORT FASTCALL
co_WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint,
PWINDOW_OBJECT* Window)
{
HWND DesktopWindowHandle;
PWINDOW_OBJECT DesktopWindow;
POINT Point = *WinPoint;
USHORT HitTest;
ASSERT_REFS_CO(ScopeWin);
*Window = NULL;
if(!ScopeWin)
{
DPRINT1("WinPosWindowFromPoint(): ScopeWin == NULL!\n");
return(HTERROR);
}
if (ScopeWin->Style & WS_DISABLED)
{
return(HTERROR);
}
/* Translate the point to the space of the scope window. */
DesktopWindowHandle = IntGetDesktopWindow();
if((DesktopWindowHandle != ScopeWin->hSelf) &&
(DesktopWindow = UserGetWindowObject(DesktopWindowHandle)))
{
Point.x += ScopeWin->ClientRect.left - DesktopWindow->ClientRect.left;
Point.y += ScopeWin->ClientRect.top - DesktopWindow->ClientRect.top;
}
HitTest = HTNOWHERE;
co_WinPosSearchChildren(ScopeWin, OnlyHitTests, &Point, Window, &HitTest);
return ((*Window) ? HitTest : HTNOWHERE);
}
BOOL
STDCALL
NtUserGetMinMaxInfo(
HWND hWnd,
MINMAXINFO *MinMaxInfo,
BOOL SendMessage)
{
POINT Size;
PINTERNALPOS InternalPos;
PWINDOW_OBJECT Window = NULL;
MINMAXINFO SafeMinMax;
NTSTATUS Status;
DECLARE_RETURN(BOOL);
USER_REFERENCE_ENTRY Ref;
DPRINT("Enter NtUserGetMinMaxInfo\n");
UserEnterExclusive();
if(!(Window = UserGetWindowObject(hWnd)))
{
RETURN( FALSE);
}
UserRefObjectCo(Window, &Ref);
Size.x = Window->WindowRect.left;
Size.y = Window->WindowRect.top;
InternalPos = WinPosInitInternalPos(Window, &Size,
&Window->WindowRect);
if(InternalPos)
{
if(SendMessage)
{
co_WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition,
&SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
}
else
{
WinPosFillMinMaxInfoStruct(Window, &SafeMinMax);
}
Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
if(!NT_SUCCESS(Status))
{
SetLastNtError(Status);
RETURN( FALSE);
}
RETURN( TRUE);
}
RETURN( FALSE);
CLEANUP:
if (Window) UserDerefObjectCo(Window);
DPRINT("Leave NtUserGetMinMaxInfo, ret=%i\n",_ret_);
UserLeave();
END_CLEANUP;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -