* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: winpos.c,v 1.68 2003/12/26 00:58:33 weiden Exp $
+/* $Id: winpos.c,v 1.83 2004/01/21 18:39:24 navaraf Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
VOID FASTCALL
WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
{
- for (;;)
- {
- Window = IntGetParent(Window);
- if (!Window || IntIsDesktopWindow(Window))
- {
- IntSetFocusMessageQueue(NULL);
- return;
- }
- if (IntSetForegroundWindow(Window))
- {
- return;
- }
- }
+ PWINDOW_OBJECT Child;
+ PWINDOW_OBJECT TabooWindow = Window;
+
+ for (;;)
+ {
+ if (NULL == Window || IntIsDesktopWindow(Window))
+ {
+ IntSetFocusMessageQueue(NULL);
+ return;
+ }
+ Window = Window->Parent;
+ ExAcquireFastMutex(&(Window->ChildrenListLock));
+ Child = Window->FirstChild;
+ while (NULL != Child)
+ {
+ if (Child != TabooWindow)
+ {
+ ExReleaseFastMutex(&(Window->ChildrenListLock));
+ if (IntSetForegroundWindow(Child))
+ {
+ return;
+ }
+ ExAcquireFastMutex(&(Window->ChildrenListLock));
+ }
+ Child = Child->NextSibling;
+ }
+ ExReleaseFastMutex(&(Window->ChildrenListLock));
+ }
}
VOID STATIC FASTCALL
/* FIXME */
}
-HWND STATIC FASTCALL
-WinPosNtGdiIconTitle(PWINDOW_OBJECT WindowObject)
-{
- return(NULL);
-}
-
-BOOL STATIC FASTCALL
-WinPosShowIconTitle(PWINDOW_OBJECT WindowObject, BOOL Show)
-{
- PWINDOW_OBJECT IconWindow;
- NTSTATUS Status;
-
- if (WindowObject->InternalPos)
- {
- HWND hWnd = WindowObject->InternalPos->IconTitle;
-
- if (hWnd == NULL)
- {
- hWnd = WinPosNtGdiIconTitle(WindowObject);
- }
- if (Show)
- {
- Status =
- ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->
- HandleTable,
- hWnd,
- otWindow,
- (PVOID*)&IconWindow);
- if (NT_SUCCESS(Status))
- {
- if (!(IconWindow->Style & WS_VISIBLE))
- {
- IntSendMessage(hWnd, WM_SHOWWINDOW, TRUE, 0, TRUE);
- WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE |
- SWP_NOMOVE | SWP_NOACTIVATE |
- SWP_NOZORDER | SWP_SHOWWINDOW);
- }
- ObmDereferenceObject(IconWindow);
- }
- }
- else
- {
- WinPosShowWindow(hWnd, SW_HIDE);
- }
- }
- return(FALSE);
-}
-
PINTERNALPOS FASTCALL
WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
{
RECT WorkArea;
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
- WorkArea = *IntGetDesktopWorkArea(Desktop);
+ if(IntIsDesktopWindow(WindowObject->Parent))
+ WorkArea = *IntGetDesktopWorkArea(Desktop);
+ else
+ WorkArea = WindowObject->Parent->ClientRect;
WindowObject->InternalPos = ExAllocatePool(NonPagedPool, sizeof(INTERNALPOS));
if(!WindowObject->InternalPos)
DPRINT1("Failed to allocate INTERNALPOS structure for window 0x%x\n", WindowObject->Self);
return NULL;
}
- WindowObject->InternalPos->IconTitle = 0;
WindowObject->InternalPos->NormalRect = WindowObject->WindowRect;
- if (HAS_DLGFRAME(WindowObject->Style, WindowObject->ExStyle))
+ if (HAS_DLGFRAME(WindowObject->Style, WindowObject->ExStyle) && !(WindowObject->Style & WS_MINIMIZE))
{
XInc = NtUserGetSystemMetrics(SM_CXDLGFRAME);
YInc = NtUserGetSystemMetrics(SM_CYDLGFRAME);
else
{
XInc = YInc = 0;
- if (HAS_THICKFRAME(WindowObject->Style, WindowObject->ExStyle))
+ if (HAS_THICKFRAME(WindowObject->Style, WindowObject->ExStyle)&& !(WindowObject->Style & WS_MINIMIZE))
{
XInc += NtUserGetSystemMetrics(SM_CXFRAME);
YInc += NtUserGetSystemMetrics(SM_CYFRAME);
{
if (WindowObject->Style & WS_MINIMIZE)
{
- if (!IntSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0, TRUE))
+ if (!IntSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0))
{
return(SWP_NOSIZE | SWP_NOMOVE);
}
{
WindowObject->Flags &= ~WINDOWOBJECT_RESTOREMAX;
}
+ IntRedrawWindow(WindowObject, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
+ RDW_NOINTERNALPAINT);
WindowObject->Style |= WS_MINIMIZE;
WinPosFindIconPos(WindowObject, &InternalPos->IconPos);
NtGdiSetRect(NewPos, InternalPos->IconPos.x, InternalPos->IconPos.y,
{
WinPosGetMinMaxInfo(WindowObject, &Size, &InternalPos->MaxPos,
NULL, NULL);
+ DPRINT1("Maximize: %d,%d %dx%d\n",
+ InternalPos->MaxPos.x, InternalPos->MaxPos.y, Size.x, Size.y);
if (WindowObject->Style & WS_MINIMIZE)
{
- WinPosShowIconTitle(WindowObject, FALSE);
WindowObject->Style &= ~WS_MINIMIZE;
}
WindowObject->Style |= WS_MAXIMIZE;
if (WindowObject->Style & WS_MINIMIZE)
{
WindowObject->Style &= ~WS_MINIMIZE;
- WinPosShowIconTitle(WindowObject, FALSE);
if (WindowObject->Flags & WINDOWOBJECT_RESTOREMAX)
{
WinPosGetMinMaxInfo(WindowObject, &Size,
return(SwpFlags);
}
-UINT FASTCALL
-WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
- POINT* MinTrack, POINT* MaxTrack)
+VOID FASTCALL
+WinPosFillMinMaxInfoStruct(PWINDOW_OBJECT Window, MINMAXINFO *Info)
{
- MINMAXINFO MinMax;
INT XInc, YInc;
RECT WorkArea;
PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
WorkArea = *IntGetDesktopWorkArea(Desktop);
-
+
/* Get default values. */
- MinMax.ptMaxSize.x = WorkArea.right - WorkArea.left;
- MinMax.ptMaxSize.y = WorkArea.bottom - WorkArea.top;
- MinMax.ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
- MinMax.ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
- MinMax.ptMaxTrackSize.x = MinMax.ptMaxSize.x;
- MinMax.ptMaxTrackSize.y = MinMax.ptMaxSize.y;
+ Info->ptMaxSize.x = WorkArea.right - WorkArea.left;
+ Info->ptMaxSize.y = WorkArea.bottom - WorkArea.top;
+ Info->ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
+ Info->ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
+ Info->ptMaxTrackSize.x = Info->ptMaxSize.x;
+ Info->ptMaxTrackSize.y = Info->ptMaxSize.y;
if (HAS_DLGFRAME(Window->Style, Window->ExStyle))
{
YInc += NtUserGetSystemMetrics(SM_CYBORDER);
}
}
- MinMax.ptMaxSize.x += 2 * XInc;
- MinMax.ptMaxSize.y += 2 * YInc;
+ Info->ptMaxSize.x += 2 * XInc;
+ Info->ptMaxSize.y += 2 * YInc;
if (Window->InternalPos != NULL)
{
- MinMax.ptMaxPosition = Window->InternalPos->MaxPos;
+ Info->ptMaxPosition = Window->InternalPos->MaxPos;
}
else
{
- MinMax.ptMaxPosition.x -= WorkArea.left + XInc;
- MinMax.ptMaxPosition.y -= WorkArea.top + YInc;
+ Info->ptMaxPosition.x -= WorkArea.left + XInc;
+ Info->ptMaxPosition.y -= WorkArea.top + YInc;
}
+}
- IntSendMessage(Window->Self, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax, TRUE);
+UINT FASTCALL
+WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
+ POINT* MinTrack, POINT* MaxTrack)
+{
+ MINMAXINFO MinMax;
+
+ WinPosFillMinMaxInfoStruct(Window, &MinMax);
+
+ IntSendMessage(Window->Self, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
MinMax.ptMaxTrackSize.x = max(MinMax.ptMaxTrackSize.x,
MinMax.ptMinTrackSize.x);
return 0; //FIXME: what does it return?
}
-#if 0
-BOOL STATIC FASTCALL
-WinPosChangeActiveWindow(HWND hWnd, BOOL MouseMsg)
-{
- PWINDOW_OBJECT WindowObject;
-
- WindowObject = IntGetWindowObject(hWnd);
- if (WindowObject == NULL)
- {
- return FALSE;
- }
-
-#if 0
- IntSendMessage(hWnd,
- WM_ACTIVATE,
- MAKELONG(MouseMsg ? WA_CLICKACTIVE : WA_CLICKACTIVE,
- (WindowObject->Style & WS_MINIMIZE) ? 1 : 0),
- (LPARAM)IntGetDesktopWindow(), /* FIXME: Previous active window */
- TRUE);
-#endif
- IntSetForegroundWindow(WindowObject);
-
- IntReleaseWindowObject(WindowObject);
-
- return TRUE;
-}
-#endif
-
LONG STATIC FASTCALL
WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
RECT* WindowRect, RECT* ClientRect)
params.lppos = &winposCopy;
winposCopy = *WinPos;
- wvrFlags = IntSendNCCALCSIZEMessage(Window->Self, TRUE, NULL, ¶ms);
+ wvrFlags = IntSendMessage(Window->Self, WM_NCCALCSIZE, TRUE, (LPARAM) ¶ms);
/* If the application send back garbage, ignore it */
if (params.rgrc[0].left <= params.rgrc[0].right &&
if (!(WinPos->flags & SWP_NOSENDCHANGING))
{
- IntSendWINDOWPOSCHANGINGMessage(WindowObject->Self, WinPos);
+ IntSendMessage(WindowObject->Self, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
}
*WindowRect = WindowObject->WindowRect;
- *ClientRect =
- (WindowObject->Style & WS_MINIMIZE) ? WindowObject->WindowRect :
- WindowObject->ClientRect;
+ *ClientRect = WindowObject->ClientRect;
if (!(WinPos->flags & SWP_NOSIZE))
{
HWND FASTCALL
WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
{
-#if 0
- /* FIXME */
- return hWndInsertAfter;
-#endif
HWND *List = NULL;
HWND Owner = NtUserGetWindow(hWnd, GW_OWNER);
LONG Style = NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE);
(WinPos->hwndInsertAfter != HWND_BOTTOM))
{
if (NtUserGetAncestor(WinPos->hwndInsertAfter, GA_PARENT) !=
- Window->Parent)
+ Window->Parent->Self)
{
return FALSE;
}
WinPos.cx = cx;
WinPos.cy = cy;
WinPos.flags = flags;
- if (Window->Style & WS_CHILD)
- {
- WinPos.x -= Window->Parent->ClientRect.left;
- WinPos.y -= Window->Parent->ClientRect.top;
- }
WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
}
/* Compute the visible region before the window position is changed */
- if ((!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
- WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
- SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
+ if (!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
+ (WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+ SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
(SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
{
- VisBefore = VIS_ComputeVisibleRegion(
- PsGetWin32Thread()->Desktop, Window, FALSE, FALSE, TRUE);
+ VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
- if (UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
+ if (VisBefore != NULL &&
+ UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
{
NtGdiDeleteObject(VisBefore);
VisBefore = NULL;
if (WinPos.hwndInsertAfter == HWND_TOP)
InsertAfterWindow = NULL;
else if (WinPos.hwndInsertAfter == HWND_BOTTOM)
- InsertAfterWindow = ParentWindow->LastChild;
+ InsertAfterWindow = IntGetWindowObject(ParentWindow->LastChild->Self);
else
InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter);
/* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
}
/* Determine the new visible region */
- VisAfter = VIS_ComputeVisibleRegion(
- PsGetWin32Thread()->Desktop, Window, FALSE, FALSE, TRUE);
+ VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
- if (UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
+ if (VisAfter != NULL &&
+ UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
{
NtGdiDeleteObject(VisAfter);
VisAfter = NULL;
* we don't have to crop (can't take anything away from an empty
* region...)
*/
- if (!(WinPos.flags & (SWP_NOSIZE | SWP_NOZORDER)) && RgnType != ERROR &&
+ if (!(WinPos.flags & SWP_NOSIZE) && RgnType != ERROR &&
RgnType != NULLREGION)
{
RECT ORect = OldClientRect;
{
NtGdiCombineRgn(CopyRgn, CopyRgn, Window->UpdateRegion, RGN_DIFF);
}
+ if (Window->NCUpdateRegion != NULL)
+ {
+ NtGdiCombineRgn(CopyRgn, CopyRgn, Window->NCUpdateRegion, RGN_DIFF);
+ }
/*
* Now, get the bounding box of the copy region. If it's empty
* to create a copy of CopyRgn and pass that. We need CopyRgn later
*/
HRGN ClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+
NtGdiCombineRgn(ClipRgn, CopyRgn, NULL, RGN_COPY);
Dc = NtUserGetDCEx(Wnd, ClipRgn, DCX_WINDOW | DCX_CACHE |
DCX_INTERSECTRGN | DCX_CLIPSIBLINGS);
CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY);
NtUserReleaseDC(Wnd, Dc);
+ IntValidateParent(Window, CopyRgn);
}
}
else
/* We need to redraw what wasn't visible before */
if (VisAfter != NULL)
{
+ DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
if (CopyRgn != NULL)
{
- DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
- if (RgnType != ERROR && RgnType != NULLREGION)
- {
- NtGdiOffsetRgn(DirtyRgn,
- Window->WindowRect.left - Window->ClientRect.left,
- Window->WindowRect.top - Window->ClientRect.top);
- IntRedrawWindow(Window, NULL, DirtyRgn,
- RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
- }
- NtGdiDeleteObject(DirtyRgn);
}
else
{
- IntRedrawWindow(Window, NULL, 0,
+ RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, 0, RGN_COPY);
+ }
+ if (RgnType != ERROR && RgnType != NULLREGION)
+ {
+ NtGdiOffsetRgn(DirtyRgn,
+ Window->WindowRect.left - Window->ClientRect.left,
+ Window->WindowRect.top - Window->ClientRect.top);
+ IntRedrawWindow(Window, NULL, DirtyRgn,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
+ NtGdiDeleteObject(DirtyRgn);
}
if (CopyRgn != NULL)
if (RgnType != ERROR && RgnType != NULLREGION)
{
- VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window,
- ExposedRgn);
+ VIS_WindowLayoutChanged(Window, ExposedRgn);
}
NtGdiDeleteObject(ExposedRgn);
NtGdiDeleteObject(VisBefore);
{
if ((Window->Style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
{
- IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0, TRUE);
+ IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
}
else
{
}
if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
- IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
+ IntSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
IntReleaseWindowObject(Window);
WinPosGetNonClientSize(HWND Wnd, RECT* WindowRect, RECT* ClientRect)
{
*ClientRect = *WindowRect;
- return(IntSendNCCALCSIZEMessage(Wnd, FALSE, ClientRect, NULL));
+ return(IntSendMessage(Wnd, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect));
}
BOOLEAN FASTCALL
/* Fall through. */
case SW_MINIMIZE:
{
- Swp |= SWP_FRAMECHANGED;
+ Swp |= SWP_FRAMECHANGED | SWP_NOACTIVATE;
if (!(Window->Style & WS_MINIMIZE))
{
Swp |= WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos);
ShowFlag = (Cmd != SW_HIDE);
if (ShowFlag != WasVisible)
{
- IntSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0, TRUE);
+ IntSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
/*
* FIXME: Need to check the window wasn't destroyed during the
* window procedure.
}
/* FIXME: Check for window destruction. */
- /* Show title for minimized windows. */
- if (Window->Style & WS_MINIMIZE)
- {
- WinPosShowIconTitle(Window, TRUE);
- }
if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
{
MAKELONG(Window->ClientRect.right -
Window->ClientRect.left,
Window->ClientRect.bottom -
- Window->ClientRect.top), TRUE);
+ Window->ClientRect.top));
IntSendMessage(Wnd, WM_MOVE, 0,
MAKELONG(Window->ClientRect.left,
- Window->ClientRect.top), TRUE);
+ Window->ClientRect.top));
}
/* Activate the window if activation is not requested and the window is not minimized */
ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
return(HTERROR);
}
- if (Current->Style & WS_MINIMIZE)
- {
- ExReleaseFastMutexUnsafe(&ScopeWin->ChildrenListLock);
- return(HTCAPTION);
- }
if (Point.x >= Current->ClientRect.left &&
Point.x < Current->ClientRect.right &&
Point.y >= Current->ClientRect.top &&
if ((*Window)->MessageQueue == PsGetWin32Thread()->MessageQueue)
{
HitTest = IntSendMessage((*Window)->Self, WM_NCHITTEST, 0,
- MAKELONG(Point.x, Point.y), FALSE);
+ MAKELONG(Point.x, Point.y));
/* FIXME: Check for HTTRANSPARENT here. */
}
else
return(HitTest);
}
+BOOL
+STDCALL
+NtUserGetMinMaxInfo(
+ HWND hwnd,
+ MINMAXINFO *MinMaxInfo,
+ BOOL SendMessage)
+{
+ POINT Size;
+ PINTERNALPOS InternalPos;
+ PWINDOW_OBJECT Window;
+ MINMAXINFO SafeMinMax;
+ NTSTATUS Status;
+
+ Window = IntGetWindowObject(hwnd);
+ if(!Window)
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ Size.x = Window->WindowRect.left;
+ Size.y = Window->WindowRect.top;
+ InternalPos = WinPosInitInternalPos(Window, Size,
+ &Window->WindowRect);
+ if(InternalPos)
+ {
+ if(SendMessage)
+ {
+ WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition,
+ &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
+ }
+ else
+ {
+ WinPosFillMinMaxInfoStruct(Window, &SafeMinMax);
+ }
+ Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
+ if(!NT_SUCCESS(Status))
+ {
+ IntReleaseWindowObject(Window);
+ SetLastNtError(Status);
+ return FALSE;
+ }
+ IntReleaseWindowObject(Window);
+ return TRUE;
+ }
+
+ IntReleaseWindowObject(Window);
+ return FALSE;
+}
+
/* EOF */