📄 winpos.c
字号:
IntGetWindowBorderMeasures(Window, &XInc, &YInc);
Info->ptMaxSize.x = WorkArea.right - WorkArea.left + 2 * XInc;
Info->ptMaxSize.y = WorkArea.bottom - WorkArea.top + 2 * YInc;
Info->ptMaxTrackSize.x = Info->ptMaxSize.x;
Info->ptMaxTrackSize.y = Info->ptMaxSize.y;
if (Window->InternalPos != NULL)
{
Info->ptMaxPosition = Window->InternalPos->MaxPos;
}
else
{
Info->ptMaxPosition.x = WorkArea.left - XInc;
Info->ptMaxPosition.y = WorkArea.top - YInc;
}
}
UINT FASTCALL
co_WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
POINT* MinTrack, POINT* MaxTrack)
{
MINMAXINFO MinMax;
ASSERT_REFS_CO(Window);
WinPosFillMinMaxInfoStruct(Window, &MinMax);
co_IntSendMessage(Window->hSelf, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
MinMax.ptMaxTrackSize.x = max(MinMax.ptMaxTrackSize.x,
MinMax.ptMinTrackSize.x);
MinMax.ptMaxTrackSize.y = max(MinMax.ptMaxTrackSize.y,
MinMax.ptMinTrackSize.y);
if (MaxSize)
*MaxSize = MinMax.ptMaxSize;
if (MaxPos)
*MaxPos = MinMax.ptMaxPosition;
if (MinTrack)
*MinTrack = MinMax.ptMinTrackSize;
if (MaxTrack)
*MaxTrack = MinMax.ptMaxTrackSize;
return 0; //FIXME: what does it return?
}
static
VOID FASTCALL
FixClientRect(PRECT ClientRect, PRECT WindowRect)
{
if (ClientRect->left < WindowRect->left)
{
ClientRect->left = WindowRect->left;
}
else if (WindowRect->right < ClientRect->left)
{
ClientRect->left = WindowRect->right;
}
if (ClientRect->right < WindowRect->left)
{
ClientRect->right = WindowRect->left;
}
else if (WindowRect->right < ClientRect->right)
{
ClientRect->right = WindowRect->right;
}
if (ClientRect->top < WindowRect->top)
{
ClientRect->top = WindowRect->top;
}
else if (WindowRect->bottom < ClientRect->top)
{
ClientRect->top = WindowRect->bottom;
}
if (ClientRect->bottom < WindowRect->top)
{
ClientRect->bottom = WindowRect->top;
}
else if (WindowRect->bottom < ClientRect->bottom)
{
ClientRect->bottom = WindowRect->bottom;
}
}
static
LONG FASTCALL
co_WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
RECT* WindowRect, RECT* ClientRect)
{
PWINDOW_OBJECT Parent;
UINT wvrFlags = 0;
ASSERT_REFS_CO(Window);
/* Send WM_NCCALCSIZE message to get new client area */
if ((WinPos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE)
{
NCCALCSIZE_PARAMS params;
WINDOWPOS winposCopy;
params.rgrc[0] = *WindowRect;
params.rgrc[1] = Window->WindowRect;
params.rgrc[2] = Window->ClientRect;
Parent = Window->Parent;
if (0 != (Window->Style & WS_CHILD) && Parent)
{
IntGdiOffsetRect(&(params.rgrc[0]), - Parent->ClientRect.left,
- Parent->ClientRect.top);
IntGdiOffsetRect(&(params.rgrc[1]), - Parent->ClientRect.left,
- Parent->ClientRect.top);
IntGdiOffsetRect(&(params.rgrc[2]), - Parent->ClientRect.left,
- Parent->ClientRect.top);
}
params.lppos = &winposCopy;
winposCopy = *WinPos;
wvrFlags = co_IntSendMessage(Window->hSelf, WM_NCCALCSIZE, TRUE, (LPARAM) ¶ms);
/* If the application send back garbage, ignore it */
if (params.rgrc[0].left <= params.rgrc[0].right &&
params.rgrc[0].top <= params.rgrc[0].bottom)
{
*ClientRect = params.rgrc[0];
if ((Window->Style & WS_CHILD) && Parent)
{
IntGdiOffsetRect(ClientRect, Parent->ClientRect.left,
Parent->ClientRect.top);
}
FixClientRect(ClientRect, WindowRect);
}
/* FIXME: WVR_ALIGNxxx */
if (ClientRect->left != Window->ClientRect.left ||
ClientRect->top != Window->ClientRect.top)
{
WinPos->flags &= ~SWP_NOCLIENTMOVE;
}
if ((ClientRect->right - ClientRect->left !=
Window->ClientRect.right - Window->ClientRect.left) ||
(ClientRect->bottom - ClientRect->top !=
Window->ClientRect.bottom - Window->ClientRect.top))
{
WinPos->flags &= ~SWP_NOCLIENTSIZE;
}
}
else
{
if (! (WinPos->flags & SWP_NOMOVE)
&& (ClientRect->left != Window->ClientRect.left ||
ClientRect->top != Window->ClientRect.top))
{
WinPos->flags &= ~SWP_NOCLIENTMOVE;
}
}
return wvrFlags;
}
static
BOOL FASTCALL
co_WinPosDoWinPosChanging(PWINDOW_OBJECT Window,
PWINDOWPOS WinPos,
PRECT WindowRect,
PRECT ClientRect)
{
INT X, Y;
ASSERT_REFS_CO(Window);
if (!(WinPos->flags & SWP_NOSENDCHANGING))
{
co_IntPostOrSendMessage(Window->hSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
}
*WindowRect = Window->WindowRect;
*ClientRect = Window->ClientRect;
if (!(WinPos->flags & SWP_NOSIZE))
{
WindowRect->right = WindowRect->left + WinPos->cx;
WindowRect->bottom = WindowRect->top + WinPos->cy;
}
if (!(WinPos->flags & SWP_NOMOVE))
{
PWINDOW_OBJECT Parent;
X = WinPos->x;
Y = WinPos->y;
Parent = Window->Parent;
if ((0 != (Window->Style & WS_CHILD)) && Parent)
{
X += Parent->ClientRect.left;
Y += Parent->ClientRect.top;
}
WindowRect->left = X;
WindowRect->top = Y;
WindowRect->right += X - Window->WindowRect.left;
WindowRect->bottom += Y - Window->WindowRect.top;
IntGdiOffsetRect(ClientRect,
X - Window->WindowRect.left,
Y - Window->WindowRect.top);
}
WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
return TRUE;
}
/*
* Fix Z order taking into account owned popups -
* basically we need to maintain them above the window that owns them
*/
static
HWND FASTCALL
WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
{
HWND *List = NULL;
HWND Owner = UserGetWindow(hWnd, GW_OWNER);
LONG Style = UserGetWindowLong(hWnd, GWL_STYLE, FALSE);
PWINDOW_OBJECT DesktopWindow, ChildObject;
int i;
if ((Style & WS_POPUP) && Owner)
{
/* Make sure this popup stays above the owner */
HWND hWndLocalPrev = HWND_TOPMOST;
if (hWndInsertAfter != HWND_TOPMOST)
{
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
List = IntWinListChildren(DesktopWindow);
if (List != NULL)
{
for (i = 0; List[i]; i++)
{
if (List[i] == Owner)
break;
if (HWND_TOP == hWndInsertAfter)
{
ChildObject = UserGetWindowObject(List[i]);
if (NULL != ChildObject)
{
if (0 == (ChildObject->ExStyle & WS_EX_TOPMOST))
{
break;
}
}
}
if (List[i] != hWnd)
hWndLocalPrev = List[i];
if (hWndLocalPrev == hWndInsertAfter)
break;
}
hWndInsertAfter = hWndLocalPrev;
}
}
}
else if (Style & WS_CHILD)
{
return hWndInsertAfter;
}
if (!List)
{
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
List = IntWinListChildren(DesktopWindow);
}
if (List != NULL)
{
for (i = 0; List[i]; i++)
{
PWINDOW_OBJECT Wnd;
if (List[i] == hWnd)
break;
if (!(Wnd = UserGetWindowObject(List[i])))
continue;
if ((Wnd->Style & WS_POPUP) &&
UserGetWindow(List[i], GW_OWNER) == hWnd)
{
USER_REFERENCE_ENTRY Ref;
UserRefObjectCo(Wnd, &Ref);
co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
UserDerefObjectCo(Wnd);
hWndInsertAfter = List[i];
}
}
ExFreePool(List);
}
return hWndInsertAfter;
}
/***********************************************************************
* WinPosInternalMoveWindow
*
* Update WindowRect and ClientRect of Window and all of its children
* We keep both WindowRect and ClientRect in screen coordinates internally
*/
static
VOID FASTCALL
WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
{
PWINDOW_OBJECT Child;
Window->WindowRect.left += MoveX;
Window->WindowRect.right += MoveX;
Window->WindowRect.top += MoveY;
Window->WindowRect.bottom += MoveY;
Window->ClientRect.left += MoveX;
Window->ClientRect.right += MoveX;
Window->ClientRect.top += MoveY;
Window->ClientRect.bottom += MoveY;
for(Child = Window->FirstChild; Child; Child = Child->NextSibling)
{
WinPosInternalMoveWindow(Child, MoveX, MoveY);
}
}
/*
* WinPosFixupSWPFlags
*
* Fix redundant flags and values in the WINDOWPOS structure.
*/
static
BOOL FASTCALL
WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
{
if (Window->Style & WS_VISIBLE)
{
WinPos->flags &= ~SWP_SHOWWINDOW;
}
else
{
WinPos->flags &= ~SWP_HIDEWINDOW;
if (!(WinPos->flags & SWP_SHOWWINDOW))
WinPos->flags |= SWP_NOREDRAW;
}
WinPos->cx = max(WinPos->cx, 0);
WinPos->cy = max(WinPos->cy, 0);
/* Check for right size */
if (Window->WindowRect.right - Window->WindowRect.left == WinPos->cx &&
Window->WindowRect.bottom - Window->WindowRect.top == WinPos->cy)
{
WinPos->flags |= SWP_NOSIZE;
}
/* Check for right position */
if (Window->WindowRect.left == WinPos->x &&
Window->WindowRect.top == WinPos->y)
{
WinPos->flags |= SWP_NOMOVE;
}
if (WinPos->hwnd == UserGetForegroundWindow())
{
WinPos->flags |= SWP_NOACTIVATE; /* Already active */
}
else
if ((Window->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
{
/* Bring to the top when activating */
if (!(WinPos->flags & SWP_NOACTIVATE))
{
WinPos->flags &= ~SWP_NOZORDER;
WinPos->hwndInsertAfter = (0 != (Window->ExStyle & WS_EX_TOPMOST) ?
HWND_TOPMOST : HWND_TOP);
return TRUE;
}
}
/* Check hwndInsertAfter */
if (!(WinPos->flags & SWP_NOZORDER))
{
/* Fix sign extension */
if (WinPos->hwndInsertAfter == (HWND)0xffff)
{
WinPos->hwndInsertAfter = HWND_TOPMOST;
}
else if (WinPos->hwndInsertAfter == (HWND)0xfffe)
{
WinPos->hwndInsertAfter = HWND_NOTOPMOST;
}
if (WinPos->hwndInsertAfter == HWND_NOTOPMOST)
{
WinPos->hwndInsertAfter = HWND_TOP;
}
else if (HWND_TOP == WinPos->hwndInsertAfter
&& 0 != (Window->ExStyle & WS_EX_TOPMOST))
{
/* Keep it topmost when it's already topmost */
WinPos->hwndInsertAfter = HWND_TOPMOST;
}
/* hwndInsertAfter must be a sibling of the window */
if (HWND_TOPMOST != WinPos->hwndInsertAfter
&& HWND_TOP != WinPos->hwndInsertAfter
&& HWND_NOTOPMOST != WinPos->hwndInsertAfter
&& HWND_BOTTOM != WinPos->hwndInsertAfter)
{
PWINDOW_OBJECT InsAfterWnd, Parent = Window->Parent;
InsAfterWnd = UserGetWindowObject(WinPos->hwndInsertAfter);
if (InsAfterWnd && UserGetAncestor(InsAfterWnd, GA_PARENT) != Parent)
{
return FALSE;
}
else
{
/*
* We don't need to change the Z order of hwnd if it's already
* inserted after hwndInsertAfter or when inserting hwnd after
* itself.
*/
if ((WinPos->hwnd == WinPos->hwndInsertAfter) ||
(WinPos->hwnd == UserGetWindow(WinPos->hwndInsertAfter, GW_HWNDNEXT)))
{
WinPos->flags |= SWP_NOZORDER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -