* 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.29 2003/08/29 09:29:11 gvg 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
/* INCLUDES ******************************************************************/
#include <ddk/ntddk.h>
+#include <internal/safe.h>
#include <win32k/win32k.h>
#include <include/object.h>
#include <include/guicheck.h>
#include <include/class.h>
#include <include/error.h>
#include <include/winsta.h>
-#include <windows.h>
+#include <include/desktop.h>
#include <include/winpos.h>
#include <include/rect.h>
#include <include/callback.h>
#include <include/painting.h>
#include <include/dce.h>
#include <include/vis.h>
+#include <include/focus.h>
#define NDEBUG
#include <debug.h>
#define SWP_AGG_STATUSFLAGS \
(SWP_AGG_NOPOSCHANGE | SWP_FRAMECHANGED | SWP_HIDEWINDOW | SWP_SHOWWINDOW)
-ATOM AtomInternalPos = (ATOM) NULL;
-
/* FUNCTIONS *****************************************************************/
#define HAS_DLGFRAME(Style, ExStyle) \
- (((ExStyle) & WS_EX_DLGMODALFRAME) || \
- (((Style) & WS_DLGFRAME) && !((Style) & WS_BORDER)))
+ (((ExStyle) & WS_EX_DLGMODALFRAME) || \
+ (((Style) & WS_DLGFRAME) && (!((Style) & WS_THICKFRAME))))
#define HAS_THICKFRAME(Style, ExStyle) \
- (((Style) & WS_THICKFRAME) && \
- !((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)
+ (((Style) & WS_THICKFRAME) && \
+ (!(((Style) & (WS_DLGFRAME | WS_BORDER)) == WS_DLGFRAME)))
-VOID FASTCALL
-WinPosSetupInternalPos(VOID)
-{
- AtomInternalPos = NtAddAtom(L"SysIP", (ATOM*)(PULONG)&AtomInternalPos);
-}
+#define HAS_THINFRAME(Style, ExStyle) \
+ (((Style) & WS_BORDER) || (!((Style) & (WS_CHILD | WS_POPUP))))
-BOOL STDCALL
-NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
+BOOL FASTCALL
+IntGetClientOrigin(HWND hWnd, LPPOINT Point)
{
PWINDOW_OBJECT WindowObject;
-
+
WindowObject = IntGetWindowObject(hWnd);
if (WindowObject == NULL)
{
Point->x = Point->y = 0;
- return(TRUE);
+ return FALSE;
}
Point->x = WindowObject->ClientRect.left;
Point->y = WindowObject->ClientRect.top;
- return(TRUE);
+
+ IntReleaseWindowObject(WindowObject);
+ return TRUE;
}
-BOOL FASTCALL
-WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
+BOOL STDCALL
+NtUserGetClientOrigin(HWND hWnd, LPPOINT Point)
{
- return FALSE;
+ BOOL Ret;
+ POINT pt;
+ NTSTATUS Status;
+
+ Ret = IntGetClientOrigin(hWnd, &pt);
+
+ Status = MmCopyToCaller(Point, &pt, sizeof(POINT));
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return FALSE;
+ }
+
+ return Ret;
}
-POINT STATIC FASTCALL
-WinPosFindIconPos(HWND hWnd, POINT Pos)
+/*******************************************************************
+ * WinPosActivateOtherWindow
+ *
+ * Activates window other than pWnd.
+ */
+VOID FASTCALL
+WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
{
- POINT point;
- //FIXME
- return point;
+ 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));
+ }
}
-HWND STATIC FASTCALL
-WinPosNtGdiIconTitle(PWINDOW_OBJECT WindowObject)
+VOID STATIC FASTCALL
+WinPosFindIconPos(HWND hWnd, POINT *Pos)
{
- return(NULL);
+ /* FIXME */
}
-BOOL STATIC FASTCALL
-WinPosShowIconTitle(PWINDOW_OBJECT WindowObject, BOOL Show)
+PINTERNALPOS FASTCALL
+WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
{
- PINTERNALPOS InternalPos = (PINTERNALPOS)IntGetProp(WindowObject, AtomInternalPos);
- PWINDOW_OBJECT IconWindow;
- NTSTATUS Status;
-
- if (InternalPos)
+ INT XInc, YInc;
+
+ if (WindowObject->InternalPos == NULL)
{
- HWND hWnd = 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))
- {
- NtUserSendMessage(hWnd, WM_SHOWWINDOW, TRUE, 0);
- WinPosSetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE |
- SWP_NOMOVE | SWP_NOACTIVATE |
- SWP_NOZORDER | SWP_SHOWWINDOW);
- }
- ObmDereferenceObject(IconWindow);
- }
- }
+ RECT WorkArea;
+ PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
+
+ 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->NormalRect = WindowObject->WindowRect;
+ 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)&& !(WindowObject->Style & WS_MINIMIZE))
+ {
+ XInc += NtUserGetSystemMetrics(SM_CXFRAME);
+ YInc += NtUserGetSystemMetrics(SM_CYFRAME);
+ }
+ else if (HAS_THINFRAME(WindowObject->Style, WindowObject->ExStyle))
{
- WinPosShowWindow(hWnd, SW_HIDE);
+ XInc += NtUserGetSystemMetrics(SM_CXBORDER);
+ YInc += NtUserGetSystemMetrics(SM_CYBORDER);
}
- }
- return(FALSE);
-}
-
-PINTERNALPOS STATIC STDCALL
-WinPosInitInternalPos(PWINDOW_OBJECT WindowObject, POINT pt, PRECT RestoreRect)
-{
- PINTERNALPOS InternalPos = (PINTERNALPOS)IntGetProp(WindowObject, AtomInternalPos);
- if (InternalPos == NULL)
- {
- InternalPos =
- ExAllocatePool(NonPagedPool, sizeof(INTERNALPOS));
- IntSetProp(WindowObject, AtomInternalPos, InternalPos);
- InternalPos->IconTitle = 0;
- InternalPos->NormalRect = WindowObject->WindowRect;
- InternalPos->IconPos.x = InternalPos->MaxPos.x = 0xFFFFFFFF;
- InternalPos->IconPos.y = InternalPos->MaxPos.y = 0xFFFFFFFF;
+ }
+ WindowObject->InternalPos->MaxPos.x = WorkArea.left - XInc;
+ WindowObject->InternalPos->MaxPos.y = WorkArea.top - YInc;
+ WindowObject->InternalPos->IconPos.x = WorkArea.left;
+ WindowObject->InternalPos->IconPos.y = WorkArea.bottom - NtUserGetSystemMetrics(SM_CYMINIMIZED);
}
if (WindowObject->Style & WS_MINIMIZE)
{
- InternalPos->IconPos = pt;
+ WindowObject->InternalPos->IconPos = pt;
}
else if (WindowObject->Style & WS_MAXIMIZE)
{
- InternalPos->MaxPos = pt;
+ WindowObject->InternalPos->MaxPos = pt;
}
else if (RestoreRect != NULL)
{
- InternalPos->NormalRect = *RestoreRect;
+ WindowObject->InternalPos->NormalRect = *RestoreRect;
}
- return(InternalPos);
+ return(WindowObject->InternalPos);
}
-UINT STDCALL
+UINT FASTCALL
WinPosMinMaximize(PWINDOW_OBJECT WindowObject, UINT ShowFlag, RECT* NewPos)
{
POINT Size;
{
if (WindowObject->Style & WS_MINIMIZE)
{
- if (!NtUserSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0))
+ if (!IntSendMessage(WindowObject->Self, WM_QUERYOPEN, 0, 0))
{
return(SWP_NOSIZE | SWP_NOMOVE);
}
}
else
{
- WindowObject->Style &= ~WINDOWOBJECT_RESTOREMAX;
+ WindowObject->Flags &= ~WINDOWOBJECT_RESTOREMAX;
}
+ IntRedrawWindow(WindowObject, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
+ RDW_NOINTERNALPAINT);
WindowObject->Style |= WS_MINIMIZE;
- InternalPos->IconPos = WinPosFindIconPos(WindowObject,
- InternalPos->IconPos);
+ WinPosFindIconPos(WindowObject, &InternalPos->IconPos);
NtGdiSetRect(NewPos, InternalPos->IconPos.x, InternalPos->IconPos.y,
- NtUserGetSystemMetrics(SM_CXICON),
- NtUserGetSystemMetrics(SM_CYICON));
+ NtUserGetSystemMetrics(SM_CXMINIMIZED),
+ NtUserGetSystemMetrics(SM_CYMINIMIZED));
SwpFlags |= SWP_NOCOPYBITS;
break;
}
{
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_MINIMIZE;
+ WindowObject->Style |= WS_MAXIMIZE;
NtGdiSetRect(NewPos, InternalPos->MaxPos.x, InternalPos->MaxPos.y,
Size.x, Size.y);
break;
if (WindowObject->Style & WS_MINIMIZE)
{
WindowObject->Style &= ~WS_MINIMIZE;
- WinPosShowIconTitle(WindowObject, FALSE);
if (WindowObject->Flags & WINDOWOBJECT_RESTOREMAX)
{
WinPosGetMinMaxInfo(WindowObject, &Size,
InternalPos->MaxPos.y, Size.x, Size.y);
break;
}
+ else
+ {
+ *NewPos = InternalPos->NormalRect;
+ NewPos->right -= NewPos->left;
+ NewPos->bottom -= NewPos->top;
+ break;
+ }
}
else
{
if (!(WindowObject->Style & WS_MAXIMIZE))
{
- return(-1);
+ return 0;
}
- else
- {
- WindowObject->Style &= ~WS_MAXIMIZE;
- }
+ WindowObject->Style &= ~WS_MAXIMIZE;
*NewPos = InternalPos->NormalRect;
NewPos->right -= NewPos->left;
NewPos->bottom -= NewPos->top;
return(SwpFlags);
}
-UINT STDCALL
-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;
- INTERNALPOS* Pos;
-
+ RECT WorkArea;
+ PDESKTOP_OBJECT Desktop = PsGetWin32Thread()->Desktop; /* Or rather get it from the window? */
+
+ WorkArea = *IntGetDesktopWorkArea(Desktop);
+
/* Get default values. */
- MinMax.ptMaxSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
- MinMax.ptMaxSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
- MinMax.ptMinTrackSize.x = NtUserGetSystemMetrics(SM_CXMINTRACK);
- MinMax.ptMinTrackSize.y = NtUserGetSystemMetrics(SM_CYMINTRACK);
- MinMax.ptMaxTrackSize.x = NtUserGetSystemMetrics(SM_CXSCREEN);
- MinMax.ptMaxTrackSize.y = NtUserGetSystemMetrics(SM_CYSCREEN);
+ 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))
{
XInc += NtUserGetSystemMetrics(SM_CXFRAME);
YInc += NtUserGetSystemMetrics(SM_CYFRAME);
}
- if (Window->Style & WS_BORDER)
+ else if (HAS_THINFRAME(Window->Style, Window->ExStyle))
{
XInc += NtUserGetSystemMetrics(SM_CXBORDER);
YInc += NtUserGetSystemMetrics(SM_CYBORDER);
}
}
- MinMax.ptMaxSize.x += 2 * XInc;
- MinMax.ptMaxSize.y += 2 * YInc;
+ Info->ptMaxSize.x += 2 * XInc;
+ Info->ptMaxSize.y += 2 * YInc;
- Pos = (PINTERNALPOS)IntGetProp(Window, AtomInternalPos);
- if (Pos != NULL)
+ if (Window->InternalPos != NULL)
{
- MinMax.ptMaxPosition = Pos->MaxPos;
+ Info->ptMaxPosition = Window->InternalPos->MaxPos;
}
else
{
- MinMax.ptMaxPosition.x -= XInc;
- MinMax.ptMaxPosition.y -= 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?
}
-BOOL STATIC FASTCALL
-WinPosChangeActiveWindow(HWND hWnd, BOOL MouseMsg)
+LONG STATIC FASTCALL
+WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
+ RECT* WindowRect, RECT* ClientRect)
{
- PWINDOW_OBJECT WindowObject;
+ UINT wvrFlags = 0;
- WindowObject = IntGetWindowObject(hWnd);
- if (WindowObject == NULL)
+ /* Send WM_NCCALCSIZE message to get new client area */
+ if ((WinPos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE)
{
- return FALSE;
- }
+ NCCALCSIZE_PARAMS params;
+ WINDOWPOS winposCopy;
- NtUserSendMessage(hWnd,
- WM_ACTIVATE,
- MAKELONG(MouseMsg ? WA_CLICKACTIVE : WA_CLICKACTIVE,
- (WindowObject->Style & WS_MINIMIZE) ? 1 : 0),
- (LPARAM)IntGetDesktopWindow()); /* FIXME: Previous active window */
+ params.rgrc[0] = *WindowRect;
+ params.rgrc[1] = Window->WindowRect;
+ params.rgrc[2] = Window->ClientRect;
+ if (0 != (Window->Style & WS_CHILD))
+ {
+ NtGdiOffsetRect(&(params.rgrc[0]), - Window->Parent->ClientRect.left,
+ - Window->Parent->ClientRect.top);
+ NtGdiOffsetRect(&(params.rgrc[1]), - Window->Parent->ClientRect.left,
+ - Window->Parent->ClientRect.top);
+ NtGdiOffsetRect(&(params.rgrc[2]), - Window->Parent->ClientRect.left,
+ - Window->Parent->ClientRect.top);
+ }
+ params.lppos = &winposCopy;
+ winposCopy = *WinPos;
- IntReleaseWindowObject(WindowObject);
+ wvrFlags = IntSendMessage(Window->Self, WM_NCCALCSIZE, TRUE, (LPARAM) ¶ms);
- return TRUE;
-}
+ /* 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)
+ {
+ NtGdiOffsetRect(ClientRect, Window->Parent->ClientRect.left,
+ Window->Parent->ClientRect.top);
+ }
+ }
-LONG STATIC STDCALL
-WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
- RECT* WindowRect, RECT* ClientRect)
-{
- return 0; /* FIXME: Calculate non client size */
+ /* 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;
}
-BOOL STDCALL
+BOOL FASTCALL
WinPosDoWinPosChanging(PWINDOW_OBJECT WindowObject,
PWINDOWPOS WinPos,
PRECT WindowRect,
PRECT ClientRect)
{
+ INT X, Y;
+
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))
{
if (!(WinPos->flags & SWP_NOMOVE))
{
- WindowRect->left = WinPos->x;
- WindowRect->top = WinPos->y;
- WindowRect->right += WinPos->x - WindowObject->WindowRect.left;
- WindowRect->bottom += WinPos->y - WindowObject->WindowRect.top;
- NtGdiOffsetRect(ClientRect,
- WinPos->x - WindowObject->WindowRect.left,
- WinPos->y - WindowObject->WindowRect.top);
- }
-
- WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
-
- if (!(WinPos->flags & SWP_NOSIZE) || !(WinPos->flags & SWP_NOMOVE))
- {
- WinPosGetNonClientSize(WindowObject->Self, WindowRect, ClientRect);
- }
-
- return(TRUE);
-}
-
-/***********************************************************************
- * SWP_DoSimpleFrameChanged
- *
- * NOTE: old and new client rect origins are identical, only
- * extents may have changed. Window extents are the same.
- */
-VOID STATIC
-WinPosDoSimpleFrameChanged( PWINDOW_OBJECT wndPtr, RECT* pOldClientRect, WORD swpFlags, UINT uFlags )
-{
- INT i = 0;
- RECT rect;
- HRGN hrgn = 0;
-
- if( !(swpFlags & SWP_NOCLIENTSIZE) )
- {
- /* Client rect changed its position/size, most likely a scrollar
- * was added/removed.
- *
- * FIXME: WVR alignment flags
- */
-
- if( wndPtr->ClientRect.right > pOldClientRect->right ) /* right edge */
+ X = WinPos->x;
+ Y = WinPos->y;
+ if (0 != (WindowObject->Style & WS_CHILD))
{
- i++;
- rect.top = 0;
- rect.bottom = wndPtr->ClientRect.bottom - wndPtr->ClientRect.top;
- rect.right = wndPtr->ClientRect.right - wndPtr->ClientRect.left;
- if(!(uFlags & SWP_EX_NOCOPY))
- rect.left = pOldClientRect->right - wndPtr->ClientRect.left;
- else
- {
- rect.left = 0;
- goto redraw;
- }
- }
-
- if( wndPtr->ClientRect.bottom > pOldClientRect->bottom ) /* bottom edge */
- {
- if( i )
- hrgn = NtGdiCreateRectRgnIndirect( &rect );
- rect.left = 0;
- rect.right = wndPtr->ClientRect.right - wndPtr->ClientRect.left;
- rect.bottom = wndPtr->ClientRect.bottom - wndPtr->ClientRect.top;
- if(!(uFlags & SWP_EX_NOCOPY))
- rect.top = pOldClientRect->bottom - wndPtr->ClientRect.top;
- else
- rect.top = 0;
- if( i++ )
- {
- HRGN hRectRgn = NtGdiCreateRectRgnIndirect(&rect);
- NtGdiCombineRgn(hrgn, hrgn, hRectRgn, RGN_OR);
- NtGdiDeleteObject(hRectRgn);
- }
- }
-
- if( i == 0 && (uFlags & SWP_EX_NOCOPY) ) /* force redraw anyway */
- {
- rect = wndPtr->WindowRect;
- NtGdiOffsetRect( &rect, wndPtr->WindowRect.left - wndPtr->ClientRect.left,
- wndPtr->WindowRect.top - wndPtr->ClientRect.top );
- i++;
+ X += WindowObject->Parent->ClientRect.left;
+ Y += WindowObject->Parent->ClientRect.top;
}
+ WindowRect->left = X;
+ WindowRect->top = Y;
+ WindowRect->right += X - WindowObject->WindowRect.left;
+ WindowRect->bottom += Y - WindowObject->WindowRect.top;
+ NtGdiOffsetRect(ClientRect,
+ X - WindowObject->WindowRect.left,
+ Y - WindowObject->WindowRect.top);
}
- if( i )
- {
-redraw:
- PaintRedrawWindow( wndPtr, &rect, hrgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
- RDW_ERASENOW | RDW_ALLCHILDREN, RDW_EX_TOPFRAME | RDW_EX_USEHRGN );
- }
- else
- {
- PaintUpdateNCRegion(wndPtr, 0, UNC_UPDATE | UNC_ENTIRE);
- }
+ WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
- if( hrgn > (HRGN)1 )
- NtGdiDeleteObject( hrgn );
+ return TRUE;
}
-/***********************************************************************
- * SWP_CopyValidBits
- *
- * Make window look nice without excessive repainting
- *
- * visible and update regions are in window coordinates
- * client and window rectangles are in parent client coordinates
- *
- * Returns: uFlags and a dirty region in *pVisRgn.
+/*
+ * Fix Z order taking into account owned popups -
+ * basically we need to maintain them above the window that owns them
*/
-static UINT WinPosCopyValidBits( PWINDOW_OBJECT Wnd, HRGN* pVisRgn,
- LPRECT lpOldWndRect,
- LPRECT lpOldClientRect, UINT uFlags )
+HWND FASTCALL
+WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
{
- RECT r;
- HRGN newVisRgn, dirtyRgn;
- INT my = COMPLEXREGION;
-
- if( Wnd->UpdateRegion == (HRGN)1 )
- uFlags |= SWP_EX_NOCOPY; /* whole window is invalid, nothing to copy */
-
- newVisRgn = DceGetVisRgn( Wnd->Self, DCX_WINDOW | DCX_CLIPSIBLINGS, 0, 0);
- NtGdiOffsetRgn(newVisRgn, -Wnd->WindowRect.left, -Wnd->WindowRect.top);
- dirtyRgn = NtGdiCreateRectRgn( 0, 0, 0, 0 );
-
- if( !(uFlags & SWP_EX_NOCOPY) ) /* make sure dst region covers only valid bits */
- my = NtGdiCombineRgn( dirtyRgn, newVisRgn, *pVisRgn, RGN_AND );
-
- if( (my == NULLREGION) || (uFlags & SWP_EX_NOCOPY) )
- {
-nocopy:
-
- /* set dirtyRgn to the sum of old and new visible regions
- * in parent client coordinates */
-
- NtGdiOffsetRgn( newVisRgn, Wnd->WindowRect.left, Wnd->WindowRect.top );
- NtGdiOffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
-
- NtGdiCombineRgn(*pVisRgn, *pVisRgn, newVisRgn, RGN_OR );
- }
- else /* copy valid bits to a new location */
- {
- INT dx, dy, ow, oh, nw, nh, ocw, ncw, och, nch;
- HRGN hrgnValid = dirtyRgn; /* non-empty intersection of old and new visible rgns */
-
- /* subtract already invalid region inside Wnd from the dst region */
-
- if( Wnd->UpdateRegion )
- if( NtGdiCombineRgn( hrgnValid, hrgnValid, Wnd->UpdateRegion, RGN_DIFF) == NULLREGION )
- goto nocopy;
-
- /* check if entire window can be copied */
-
- ow = lpOldWndRect->right - lpOldWndRect->left;
- oh = lpOldWndRect->bottom - lpOldWndRect->top;
- nw = Wnd->WindowRect.right - Wnd->WindowRect.left;
- nh = Wnd->WindowRect.bottom - Wnd->WindowRect.top;
-
- ocw = lpOldClientRect->right - lpOldClientRect->left;
- och = lpOldClientRect->bottom - lpOldClientRect->top;
- ncw = Wnd->ClientRect.right - Wnd->ClientRect.left;
- nch = Wnd->ClientRect.bottom - Wnd->ClientRect.top;
-
- if( (ocw != ncw) || (och != nch) ||
- ( ow != nw) || ( oh != nh) ||
- ((lpOldClientRect->top - lpOldWndRect->top) !=
- (Wnd->ClientRect.top - Wnd->WindowRect.top)) ||
- ((lpOldClientRect->left - lpOldWndRect->left) !=
- (Wnd->ClientRect.left - Wnd->WindowRect.left)) )
- {
- if(uFlags & SWP_EX_PAINTSELF)
- {
- /* movement relative to the window itself */
- dx = (Wnd->ClientRect.left - Wnd->WindowRect.left) -
- (lpOldClientRect->left - lpOldWndRect->left) ;
- dy = (Wnd->ClientRect.top - Wnd->WindowRect.top) -
- (lpOldClientRect->top - lpOldWndRect->top) ;
- }
- else
+ HWND *List = NULL;
+ HWND Owner = NtUserGetWindow(hWnd, GW_OWNER);
+ LONG Style = NtUserGetWindowLong(hWnd, GWL_STYLE, FALSE);
+ PWINDOW_OBJECT DesktopWindow;
+ int i;
+
+ if ((Style & WS_POPUP) && Owner)
+ {
+ /* Make sure this popup stays above the owner */
+ HWND hWndLocalPrev = HWND_TOP;
+
+ if (hWndInsertAfter != HWND_TOP)
+ {
+ DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
+ IntReleaseWindowObject(DesktopWindow);
+ if (List != NULL)
{
- /* movement relative to the parent's client area */
- dx = Wnd->ClientRect.left - lpOldClientRect->left;
- dy = Wnd->ClientRect.top - lpOldClientRect->top;
- }
-
- /* restrict valid bits to the common client rect */
-
- r.left = Wnd->ClientRect.left - Wnd->WindowRect.left;
- r.top = Wnd->ClientRect.top - Wnd->WindowRect.top;
- r.right = r.left + min( ocw, ncw );
- r.bottom = r.top + min( och, nch );
-
- REGION_CropRgn( hrgnValid, hrgnValid, &r,
- (uFlags & SWP_EX_PAINTSELF) ? NULL : (POINT*)&(Wnd->WindowRect));
- NtGdiGetRgnBox( hrgnValid, &r );
- if( NtGdiIsEmptyRect( &r ) )
- goto nocopy;
- r = *lpOldClientRect;
- }
- else
- {
- if(uFlags & SWP_EX_PAINTSELF) {
- /*
- * with SWP_EX_PAINTSELF, the window repaints itself. Since a window can't move
- * relative to itself, only the client area can change.
- * if the client rect didn't change, there's nothing to do.
- */
- dx = 0;
- dy = 0;
+ for (i = 0; List[i]; i++)
+ {
+ if (List[i] == Owner) break;
+ if (List[i] != hWnd) hWndLocalPrev = List[i];
+ if (hWndLocalPrev == hWndInsertAfter) break;
+ }
+ hWndInsertAfter = hWndLocalPrev;
}
- else
+ }
+ }
+ else if (Style & WS_CHILD)
+ {
+ return hWndInsertAfter;
+ }
+
+ if (!List)
+ {
+ DesktopWindow = IntGetWindowObject(IntGetDesktopWindow());
+ List = IntWinListChildren(DesktopWindow);
+ IntReleaseWindowObject(DesktopWindow);
+ }
+ if (List != NULL)
+ {
+ for (i = 0; List[i]; i++)
+ {
+ if (List[i] == hWnd)
+ break;
+ if ((NtUserGetWindowLong(List[i], GWL_STYLE, FALSE) & WS_POPUP) &&
+ NtUserGetWindow(List[i], GW_OWNER) == hWnd)
{
- dx = Wnd->WindowRect.left - lpOldWndRect->left;
- dy = Wnd->WindowRect.top - lpOldWndRect->top;
- NtGdiOffsetRgn( hrgnValid, Wnd->WindowRect.left, Wnd->WindowRect.top );
+ WinPosSetWindowPos(List[i], hWndInsertAfter, 0, 0, 0, 0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
+ hWndInsertAfter = List[i];
}
- r = *lpOldWndRect;
- }
-
- if( !(uFlags & SWP_EX_PAINTSELF) )
- {
- /* Move remaining regions to parent coordinates */
- NtGdiOffsetRgn( newVisRgn, Wnd->WindowRect.left, Wnd->WindowRect.top );
- NtGdiOffsetRgn( *pVisRgn, lpOldWndRect->left, lpOldWndRect->top );
- }
- else
- NtGdiOffsetRect( &r, -lpOldWndRect->left, -lpOldWndRect->top );
-
- /* Compute combined dirty region (old + new - valid) */
- NtGdiCombineRgn( *pVisRgn, *pVisRgn, newVisRgn, RGN_OR);
- NtGdiCombineRgn( *pVisRgn, *pVisRgn, hrgnValid, RGN_DIFF);
-
- /* Blt valid bits, r is the rect to copy */
-
- if( dx || dy )
- {
- RECT rClip;
- HDC hDC;
-
- /* get DC and clip rect with drawable rect to avoid superfluous expose events
- from copying clipped areas */
-
- if( uFlags & SWP_EX_PAINTSELF )
- {
- hDC = NtUserGetDCEx( Wnd->Self, hrgnValid, DCX_WINDOW | DCX_CACHE |
- DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
- rClip.right = nw; rClip.bottom = nh;
- }
- else
- {
- hDC = NtUserGetDCEx( Wnd->Parent->Self, hrgnValid, DCX_CACHE |
- DCX_KEEPCLIPRGN | DCX_INTERSECTRGN | DCX_CLIPSIBLINGS );
- rClip.right = Wnd->Parent->ClientRect.right - Wnd->Parent->ClientRect.left;
- rClip.bottom = Wnd->Parent->ClientRect.bottom - Wnd->Parent->ClientRect.top;
- }
- rClip.left = rClip.top = 0;
-
- if( oh > nh ) r.bottom = r.top + nh;
- if( ow < nw ) r.right = r.left + nw;
-
- if( NtGdiIntersectRect( &r, &r, &rClip ) )
- {
- NtGdiBitBlt(hDC, dx + r.left, dy + r.top, r.right - r.left, r.bottom - r.top, hDC, r.left, r.top, SRCCOPY);
-
- /* When you copy the bits without repainting, parent doesn't
- get validated appropriately. Therefore, we have to validate
- the parent with the windows' updated region when the
- parent's update region is not empty. */
-
- if (Wnd->Parent->UpdateRegion != 0 && !(Wnd->Parent->Style & WS_CLIPCHILDREN))
- {
- NtGdiOffsetRect(&r, dx, dy);
- NtUserValidateRect(Wnd->Parent->Self, &r);
- }
- }
- NtUserReleaseDC( (uFlags & SWP_EX_PAINTSELF) ?
- Wnd->Self : Wnd->Parent->Self, hDC);
- }
- }
-
- /* *pVisRgn now points to the invalidated region */
+ }
+ ExFreePool(List);
+ }
- NtGdiDeleteObject(newVisRgn);
- NtGdiDeleteObject(dirtyRgn);
- return uFlags;
+ return hWndInsertAfter;
}
/***********************************************************************
* Update WindowRect and ClientRect of Window and all of its children
* We keep both WindowRect and ClientRect in screen coordinates internally
*/
-static VOID
+VOID STATIC FASTCALL
WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
{
PWINDOW_OBJECT Child;
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
}
+/*
+ * WinPosFixupSWPFlags
+ *
+ * Fix redundant flags and values in the WINDOWPOS structure.
+ */
-BOOLEAN STDCALL
-WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
- INT cy, UINT flags)
+BOOL FASTCALL
+WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
{
- PWINDOW_OBJECT Window;
- NTSTATUS Status;
- WINDOWPOS WinPos;
- RECT NewWindowRect;
- RECT NewClientRect;
- HRGN VisRgn = NULL;
- HRGN VisibleRgn = NULL;
- ULONG WvrFlags = 0;
- RECT OldWindowRect, OldClientRect;
- UINT FlagsEx = 0;
-
- /* FIXME: Get current active window from active queue. */
-
- /* Check if the window is for a desktop. */
- if (Wnd == PsGetWin32Thread()->Desktop->DesktopWindow)
- {
- return(FALSE);
- }
+ 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 == NtUserGetForegroundWindow())
+ {
+ 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 = HWND_TOP;
+ return TRUE;
+ }
+ }
- Status =
- ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
- Wnd,
- otWindow,
- (PVOID*)&Window);
- if (!NT_SUCCESS(Status))
- {
- return(FALSE);
- }
-
- /* Fix up the flags. */
- if (Window->Style & WS_VISIBLE)
- {
- flags &= ~SWP_SHOWWINDOW;
- }
- else
- {
- if (!(flags & SWP_SHOWWINDOW))
- {
- flags |= SWP_NOREDRAW;
- }
- flags &= ~SWP_HIDEWINDOW;
- }
+ /* 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;
+ }
- cx = max(cx, 0);
- cy = max(cy, 0);
+ /* FIXME: TOPMOST not supported yet */
+ if ((WinPos->hwndInsertAfter == HWND_TOPMOST) ||
+ (WinPos->hwndInsertAfter == HWND_NOTOPMOST))
+ {
+ WinPos->hwndInsertAfter = HWND_TOP;
+ }
- if ((Window->WindowRect.right - Window->WindowRect.left) == cx &&
- (Window->WindowRect.bottom - Window->WindowRect.top) == cy)
- {
- flags |= SWP_NOSIZE;
- }
- if (Window->WindowRect.left == x && Window->WindowRect.top == y)
- {
- flags |= SWP_NOMOVE;
- }
- if (Window->Style & WIN_NCACTIVATED)
- {
- flags |= SWP_NOACTIVATE;
- }
- else if ((Window->Style & (WS_POPUP | WS_CHILD)) != WS_CHILD)
- {
- if (!(flags & SWP_NOACTIVATE))
- {
- flags &= ~SWP_NOZORDER;
- WndInsertAfter = HWND_TOP;
- }
- }
+ /* hwndInsertAfter must be a sibling of the window */
+ if ((WinPos->hwndInsertAfter != HWND_TOP) &&
+ (WinPos->hwndInsertAfter != HWND_BOTTOM))
+ {
+ if (NtUserGetAncestor(WinPos->hwndInsertAfter, GA_PARENT) !=
+ Window->Parent->Self)
+ {
+ 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 == NtUserGetWindow(WinPos->hwndInsertAfter, GW_HWNDNEXT)))
+ {
+ WinPos->flags |= SWP_NOZORDER;
+ }
+ }
+ }
+ }
- if (WndInsertAfter == HWND_TOPMOST || WndInsertAfter == HWND_NOTOPMOST)
- {
- WndInsertAfter = HWND_TOP;
- }
+ return TRUE;
+}
- if (WndInsertAfter != HWND_TOP && WndInsertAfter != HWND_BOTTOM)
- {
- /* FIXME: Find the window to insert after. */
- }
+/* x and y are always screen relative */
+BOOLEAN FASTCALL
+WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
+ INT cy, UINT flags)
+{
+ PWINDOW_OBJECT Window;
+ WINDOWPOS WinPos;
+ RECT NewWindowRect;
+ RECT NewClientRect;
+ HRGN VisBefore = NULL;
+ HRGN VisAfter = NULL;
+ HRGN DirtyRgn = NULL;
+ HRGN ExposedRgn = NULL;
+ HRGN CopyRgn = NULL;
+ ULONG WvrFlags = 0;
+ RECT OldWindowRect, OldClientRect;
+ int RgnType;
+ HDC Dc;
+ RECT CopyRect;
+ RECT TempRect;
+
+ /* FIXME: Get current active window from active queue. */
+
+ Window = IntGetWindowObject(Wnd);
+ if (!Window)
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ /*
+ * Only allow CSRSS to mess with the desktop window
+ */
+ if (Wnd == IntGetDesktopWindow() &&
+ Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
+ {
+ return FALSE;
+ }
+
+ WinPos.hwnd = Wnd;
+ WinPos.hwndInsertAfter = WndInsertAfter;
+ WinPos.x = x;
+ WinPos.y = y;
+ WinPos.cx = cx;
+ WinPos.cy = cy;
+ WinPos.flags = flags;
+
+ WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
+
+ /* Fix up the flags. */
+ if (!WinPosFixupFlags(&WinPos, Window))
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ IntReleaseWindowObject(Window);
+ return FALSE;
+ }
- WinPos.hwnd = Wnd;
- WinPos.hwndInsertAfter = WndInsertAfter;
- WinPos.x = x;
- WinPos.y = y;
- WinPos.cx = cx;
- WinPos.cy = cy;
- WinPos.flags = flags;
+ /* Does the window still exist? */
+ if (!IntIsWindow(WinPos.hwnd))
+ {
+ SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+ return FALSE;
+ }
+
+ if ((WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
+ SWP_NOZORDER &&
+ NtUserGetAncestor(WinPos.hwnd, GA_PARENT) == IntGetDesktopWindow())
+ {
+ WinPos.hwndInsertAfter = WinPosDoOwnedPopups(WinPos.hwnd, WinPos.hwndInsertAfter);
+ }
+
+ /* 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)) !=
+ (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
+ {
+ VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
+
+ if (VisBefore != NULL &&
+ UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
+ {
+ NtGdiDeleteObject(VisBefore);
+ VisBefore = NULL;
+ }
+ }
- WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
+ WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect);
- if ((WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
- SWP_NOZORDER)
- {
- /* FIXME: SWP_DoOwnedPopups. */
- }
-
- /* FIXME: Adjust flags based on WndInsertAfter */
+ /* Relink windows. (also take into account shell window in hwndShellWindow) */
+ if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != NtUserGetShellWindow())
+ {
+ PWINDOW_OBJECT ParentWindow;
+ PWINDOW_OBJECT InsertAfterWindow;
- 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))
- {
- if (Window->Style & WS_CLIPCHILDREN)
- {
- VisRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
- Window, FALSE, FALSE, TRUE);
- }
- else
- {
- VisRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
- Window, FALSE, FALSE, FALSE);
- }
- NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top);
- }
+ ParentWindow = Window->Parent;
+ if (ParentWindow)
+ {
+ if (WinPos.hwndInsertAfter == HWND_TOP)
+ InsertAfterWindow = NULL;
+ else if (WinPos.hwndInsertAfter == HWND_BOTTOM)
+ InsertAfterWindow = IntGetWindowObject(ParentWindow->LastChild->Self);
+ else
+ InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter);
+ /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
+ the last window */
+ if (InsertAfterWindow != Window)
+ {
+ ExAcquireFastMutexUnsafe(&ParentWindow->ChildrenListLock);
+ IntUnlinkWindow(Window);
+ IntLinkWindow(Window, ParentWindow, InsertAfterWindow);
+ ExReleaseFastMutexUnsafe(&ParentWindow->ChildrenListLock);
+ }
+ if (InsertAfterWindow != NULL)
+ IntReleaseWindowObject(InsertAfterWindow);
+ }
+ }
- WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
- &NewClientRect);
+ /* FIXME: Reset active DCEs */
- /* FIXME: Relink windows. */
+ OldWindowRect = Window->WindowRect;
+ OldClientRect = Window->ClientRect;
- /* FIXME: Reset active DCEs */
+ if (OldClientRect.bottom - OldClientRect.top ==
+ NewClientRect.bottom - NewClientRect.top)
+ {
+ WvrFlags &= ~WVR_VREDRAW;
+ }
- OldWindowRect = Window->WindowRect;
- OldClientRect = Window->ClientRect;
+ if (OldClientRect.right - OldClientRect.left ==
+ NewClientRect.right - NewClientRect.left)
+ {
+ WvrFlags &= ~WVR_HREDRAW;
+ }
- /* FIXME: Check for redrawing the whole client rect. */
+ /* FIXME: Actually do something with WVR_VALIDRECTS */
- if (! (WinPos.flags & SWP_NOMOVE))
- {
+ if (! (WinPos.flags & SWP_NOMOVE)
+ && (NewWindowRect.left != OldWindowRect.left
+ || NewWindowRect.top != OldWindowRect.top))
+ {
WinPosInternalMoveWindow(Window,
NewWindowRect.left - OldWindowRect.left,
NewWindowRect.top - OldWindowRect.top);
- }
- Window->WindowRect = NewWindowRect;
- Window->ClientRect = NewClientRect;
+ }
- if (WinPos.flags & SWP_SHOWWINDOW)
- {
- Window->Style |= WS_VISIBLE;
- FlagsEx |= SWP_EX_PAINTSELF;
- /* Redraw entire window. */
- VisRgn = (HRGN) 1;
- }
- else if (!(WinPos.flags & SWP_NOREDRAW))
- {
- if (WinPos.flags & SWP_HIDEWINDOW)
- {
- if (VisRgn > (HRGN)1)
- {
- NtGdiOffsetRgn(VisRgn, OldWindowRect.left, OldWindowRect.top);
- }
- else
- {
- VisRgn = 0;
- }
- }
- else
- {
- if ((WinPos.flags & SWP_AGG_NOPOSCHANGE) != SWP_AGG_NOPOSCHANGE)
- {
- if ((WinPos.flags & SWP_AGG_NOGEOMETRYCHANGE) == SWP_AGG_NOGEOMETRYCHANGE)
- {
- FlagsEx |= SWP_EX_PAINTSELF;
- }
- FlagsEx = WinPosCopyValidBits(Window, &VisRgn, &OldWindowRect, &OldClientRect, FlagsEx);
- }
- else
- {
- if (WinPos.flags & SWP_FRAMECHANGED)
- {
- WinPosDoSimpleFrameChanged(Window, &OldClientRect, WinPos.flags, FlagsEx);
- }
- if (VisRgn != 0)
- {
- NtGdiDeleteObject(VisRgn);
- VisRgn = 0;
- }
- }
- }
- }
+ Window->WindowRect = NewWindowRect;
+ Window->ClientRect = NewClientRect;
- if (WinPos.flags & SWP_HIDEWINDOW)
- {
- VisibleRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, Window,
- FALSE, FALSE, FALSE);
+ if (!(WinPos.flags & SWP_SHOWWINDOW) && (WinPos.flags & SWP_HIDEWINDOW))
+ {
+ /* Clear the update region */
+ IntRedrawWindow(Window, NULL, 0, RDW_VALIDATE | RDW_NOFRAME |
+ RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
Window->Style &= ~WS_VISIBLE;
- VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window, VisibleRgn);
- NtGdiDeleteObject(VisibleRgn);
- }
-
- if (! (WinPos.flags & SWP_NOMOVE))
- {
- VisibleRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
- NtGdiCombineRgn(VisibleRgn, VisRgn, VisibleRgn, RGN_DIFF);
- VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window, VisibleRgn);
- NtGdiDeleteObject(VisibleRgn);
- }
+ }
+ else if (WinPos.flags & SWP_SHOWWINDOW)
+ {
+ Window->Style |= WS_VISIBLE;
+ }
+
+ /* Determine the new visible region */
+ VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
+
+ if (VisAfter != NULL &&
+ UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
+ {
+ NtGdiDeleteObject(VisAfter);
+ VisAfter = NULL;
+ }
+
+ /*
+ * Determine which pixels can be copied from the old window position
+ * to the new. Those pixels must be visible in both the old and new
+ * position. Also, check the class style to see if the windows of this
+ * class need to be completely repainted on (horizontal/vertical) size
+ * change.
+ */
+ if (VisBefore != NULL && VisAfter != NULL && !(WinPos.flags & SWP_NOCOPYBITS) &&
+ ((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)))
+ {
+ CopyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
+
+ /*
+ * If this is (also) a window resize, the whole nonclient area
+ * needs to be repainted. So we limit the copy to the client area,
+ * 'cause there is no use in copying it (would possibly cause
+ * "flashing" too). However, if the copy region is already empty,
+ * we don't have to crop (can't take anything away from an empty
+ * region...)
+ */
+ if (!(WinPos.flags & SWP_NOSIZE) && RgnType != ERROR &&
+ RgnType != NULLREGION)
+ {
+ RECT ORect = OldClientRect;
+ RECT NRect = NewClientRect;
+ NtGdiOffsetRect(&ORect, - OldWindowRect.left, - OldWindowRect.top);
+ NtGdiOffsetRect(&NRect, - NewWindowRect.left, - NewWindowRect.top);
+ NtGdiIntersectRect(&CopyRect, &ORect, &NRect);
+ REGION_CropRgn(CopyRgn, CopyRgn, &CopyRect, NULL);
+ }
- /* FIXME: Hide or show the claret */
+ /* No use in copying bits which are in the update region. */
+ if (Window->UpdateRegion != NULL)
+ {
+ 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
+ * there's nothing to copy. Also, it's no use copying bits onto
+ * themselves.
+ */
+ if (UnsafeIntGetRgnBox(CopyRgn, &CopyRect) == NULLREGION)
+ {
+ /* Nothing to copy, clean up */
+ NtGdiDeleteObject(CopyRgn);
+ CopyRgn = NULL;
+ }
+ else if (OldWindowRect.left != NewWindowRect.left ||
+ OldWindowRect.top != NewWindowRect.top)
+ {
+ /*
+ * Small trick here: there is no function to bitblt a region. So
+ * we set the region as the clipping region, take the bounding box
+ * of the region and bitblt that. Since nothing outside the clipping
+ * region is copied, this has the effect of bitblt'ing the region.
+ *
+ * Since NtUserGetDCEx takes ownership of the clip region, we need
+ * 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);
+ NtGdiBitBlt(Dc,
+ CopyRect.left, CopyRect.top, CopyRect.right - CopyRect.left,
+ CopyRect.bottom - CopyRect.top, Dc,
+ CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
+ CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY);
+ NtUserReleaseDC(Wnd, Dc);
+ IntValidateParent(Window, CopyRgn);
+ }
+ }
+ else
+ {
+ CopyRgn = NULL;
+ }
+
+ /* We need to redraw what wasn't visible before */
+ if (VisAfter != NULL)
+ {
+ DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ if (CopyRgn != NULL)
+ {
+ RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
+ }
+ else
+ {
+ 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)
+ {
+ NtGdiDeleteObject(CopyRgn);
+ }
+
+ /* Expose what was covered before but not covered anymore */
+ if (VisBefore != NULL)
+ {
+ ExposedRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+ NtGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
+ NtGdiOffsetRgn(ExposedRgn, OldWindowRect.left - NewWindowRect.left,
+ OldWindowRect.top - NewWindowRect.top);
+ if (VisAfter != NULL)
+ RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
+ else
+ RgnType = SIMPLEREGION;
- if (VisRgn)
- {
- if (!(WinPos.flags & SWP_NOREDRAW))
- {
- if (FlagsEx & SWP_EX_PAINTSELF)
- {
- PaintRedrawWindow(Window, NULL,
- (VisRgn == (HRGN) 1) ? 0 : VisRgn,
- RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
- RDW_ALLCHILDREN | RDW_ERASENOW,
- RDW_EX_XYWINDOW | RDW_EX_USEHRGN);
- }
-#if 0
- else
- {
- PaintRedrawWindow(Window->Parent, NULL,
- (VisRgn == (HRGN) 1) ? 0 : VisRgn,
- RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN |
- RDW_ERASENOW,
- RDW_EX_USEHRGN);
- }
-#endif
- /* FIXME: Redraw the window parent. */
- }
- if ((HRGN) 1 != VisRgn)
- {
- NtGdiDeleteObject(VisRgn);
- }
- }
+ if (RgnType != ERROR && RgnType != NULLREGION)
+ {
+ VIS_WindowLayoutChanged(Window, ExposedRgn);
+ }
+ NtGdiDeleteObject(ExposedRgn);
+ NtGdiDeleteObject(VisBefore);
+ }
+
+ if (VisAfter != NULL)
+ {
+ NtGdiDeleteObject(VisAfter);
+ }
+
+ if (!(WinPos.flags & SWP_NOREDRAW))
+ {
+ IntRedrawWindow(Window, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW);
+ }
+
+ if (!(WinPos.flags & SWP_NOACTIVATE))
+ {
+ if ((Window->Style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+ {
+ IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
+ }
+ else
+ {
+ IntSetForegroundWindow(Window);
+ }
+ }
- if (!(flags & SWP_NOACTIVATE))
- {
- WinPosChangeActiveWindow(WinPos.hwnd, FALSE);
- }
+ if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
+ IntSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
- /* FIXME: Check some conditions before doing this. */
- IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
+ IntReleaseWindowObject(Window);
- ObmDereferenceObject(Window);
- return(TRUE);
+ return TRUE;
}
-LRESULT STDCALL
+LRESULT FASTCALL
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
UINT Swp = 0;
RECT NewPos;
BOOLEAN ShowFlag;
- HRGN VisibleRgn;
+// HRGN VisibleRgn;
Status =
ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
/* 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)
{
- NtUserSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
+ IntSendMessage(Wnd, WM_SHOWWINDOW, ShowFlag, 0);
/*
* FIXME: Need to check the window wasn't destroyed during the
* window procedure.
*/
}
- if (Window->Style & WS_CHILD &&
- !IntIsWindowVisible(Window->Parent->Self) &&
- (Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE))
+ /* We can't activate a child window */
+ if ((Window->Style & WS_CHILD) &&
+ !(Window->ExStyle & WS_EX_MDICHILD))
{
- if (Cmd == SW_HIDE)
- {
- VisibleRgn = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop, Window,
- FALSE, FALSE, FALSE);
- Window->Style &= ~WS_VISIBLE;
- VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window, VisibleRgn);
- NtGdiDeleteObject(VisibleRgn);
- }
- else
- {
- Window->Style |= WS_VISIBLE;
- }
+ Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
- else
+
+ WinPosSetWindowPos(Window->Self, HWND_TOP, NewPos.left, NewPos.top,
+ NewPos.right, NewPos.bottom, LOWORD(Swp));
+
+ if (Cmd == SW_HIDE)
{
- if (Window->Style & WS_CHILD &&
- !(Window->ExStyle & WS_EX_MDICHILD))
- {
- Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
- }
- if (!(Swp & MINMAX_NOSWP))
- {
- WinPosSetWindowPos(Wnd, HWND_TOP, NewPos.left, NewPos.top,
- NewPos.right, NewPos.bottom, LOWORD(Swp));
- if (Cmd == SW_HIDE)
- {
- /* Hide the window. */
- if (Wnd == IntGetActiveWindow())
- {
- WinPosActivateOtherWindow(Window);
- }
- /* Revert focus to parent. */
- if (Wnd == IntGetFocusWindow() ||
- IntIsChildWindow(Wnd, IntGetFocusWindow()))
- {
- IntSetFocusWindow(Window->Parent->Self);
- }
- }
- }
- /* FIXME: Check for window destruction. */
- /* Show title for minimized windows. */
- if (Window->Style & WS_MINIMIZE)
- {
- WinPosShowIconTitle(Window, TRUE);
- }
+ /* 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->Self == NtUserGetActiveWindow())
+ {
+ WinPosActivateOtherWindow(Window);
+ }
+
+ /* Revert focus to parent */
+ if (Wnd == IntGetThreadFocusWindow() ||
+ IntIsChildWindow(Wnd, IntGetThreadFocusWindow()))
+ {
+ NtUserSetFocus(Window->Parent->Self);
+ }
}
+ /* FIXME: Check for window destruction. */
+
if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
{
WPARAM wParam = SIZE_RESTORED;
wParam = SIZE_MINIMIZED;
}
- NtUserSendMessage(Wnd, WM_SIZE, wParam,
- MAKELONG(Window->ClientRect.right -
- Window->ClientRect.left,
- Window->ClientRect.bottom -
- Window->ClientRect.top));
- NtUserSendMessage(Wnd, WM_MOVE, 0,
- MAKELONG(Window->ClientRect.left,
- Window->ClientRect.top));
+ IntSendMessage(Wnd, WM_SIZE, wParam,
+ MAKELONG(Window->ClientRect.right -
+ Window->ClientRect.left,
+ Window->ClientRect.bottom -
+ Window->ClientRect.top));
+ IntSendMessage(Wnd, WM_MOVE, 0,
+ MAKELONG(Window->ClientRect.left,
+ Window->ClientRect.top));
}
/* 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);
}
+*/
ObmDereferenceObject(Window);
return(WasVisible);
Point.y < Window->WindowRect.bottom);
}
-USHORT STATIC STDCALL
+USHORT STATIC FASTCALL
WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, POINT Point,
PWINDOW_OBJECT* Window)
{
(Current->Style & (WS_CHILD | WS_POPUP)) != WS_CHILD) &&
WinPosPtInWindow(Current, Point))
{
+ if(*Window)
+ ObmDereferenceObject(*Window);
+ ObmReferenceObjectByPointer(Current, otWindow);
+
*Window = Current;
+
if (Current->Style & WS_DISABLED)
{
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 &&
return(0);
}
-USHORT STDCALL
+USHORT FASTCALL
WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, POINT WinPoint,
PWINDOW_OBJECT* Window)
{
USHORT HitTest;
*Window = NULL;
+
+ if(!ScopeWin)
+ {
+ DPRINT1("WinPosWindowFromPoint(): ScopeWin == NULL!\n");
+ return(HTERROR);
+ }
if (ScopeWin->Style & WS_DISABLED)
{
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
}
BOOL
-WinPosSetActiveWindow(PWINDOW_OBJECT Window, BOOL Mouse, BOOL ChangeFocus)
+STDCALL
+NtUserGetMinMaxInfo(
+ HWND hwnd,
+ MINMAXINFO *MinMaxInfo,
+ BOOL SendMessage)
{
- PUSER_MESSAGE_QUEUE ActiveQueue;
- HWND PrevActive;
-
- ActiveQueue = IntGetFocusMessageQueue();
- if (ActiveQueue != NULL)
- {
- PrevActive = ActiveQueue->ActiveWindow;
- }
- else
- {
- PrevActive = NULL;
- }
-
- if (Window->Self == IntGetActiveDesktop() || Window->Self == PrevActive)
- {
- return(FALSE);
- }
- if (PrevActive != NULL)
- {
- PWINDOW_OBJECT PrevActiveWindow = IntGetWindowObject(PrevActive);
- WORD Iconised = HIWORD(PrevActiveWindow->Style & WS_MINIMIZE);
- if (!IntSendMessage(PrevActive, WM_NCACTIVATE, FALSE, 0, TRUE))
- {
- /* FIXME: Check if the new window is system modal. */
- return(FALSE);
- }
- IntSendMessage(PrevActive,
- WM_ACTIVATE,
- MAKEWPARAM(WA_INACTIVE, Iconised),
- (LPARAM)Window->Self,
- TRUE);
- /* FIXME: Check if anything changed while processing the message. */
- IntReleaseWindowObject(PrevActiveWindow);
- }
-
- if (Window != NULL)
- {
- Window->MessageQueue->ActiveWindow = Window->Self;
- }
- else if (ActiveQueue != NULL)
- {
- ActiveQueue->ActiveWindow = NULL;
- }
- /* FIXME: Unset this flag for inactive windows */
- //if ((Window->Style) & WS_CHILD) Window->Flags |= WIN_NCACTIVATED;
-
- /* FIXME: Send palette messages. */
-
- /* FIXME: Redraw icon title of previously active window. */
-
- /* FIXME: Bring the window to the top. */
-
- /* FIXME: Send WM_ACTIVATEAPP */
+ POINT Size;
+ PINTERNALPOS InternalPos;
+ PWINDOW_OBJECT Window;
+ MINMAXINFO SafeMinMax;
+ NTSTATUS Status;
- IntSetFocusMessageQueue(Window->MessageQueue);
-
- /* FIXME: Send activate messages. */
-
- /* FIXME: Change focus. */
-
- /* FIXME: Redraw new window icon title. */
-
- return(TRUE);
-}
-
-HWND STDCALL
-NtUserGetActiveWindow(VOID)
-{
- PUSER_MESSAGE_QUEUE ActiveQueue;
-
- ActiveQueue = IntGetFocusMessageQueue();
- if (ActiveQueue == NULL)
+ 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)
{
- return(NULL);
+ WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition,
+ &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
}
- return(ActiveQueue->ActiveWindow);
-}
-
-HWND STDCALL
-NtUserSetActiveWindow(HWND hWnd)
-{
- PWINDOW_OBJECT Window;
- PUSER_MESSAGE_QUEUE ThreadQueue;
- HWND Prev;
-
- Window = IntGetWindowObject(hWnd);
- if (Window == NULL || (Window->Style & (WS_DISABLED | WS_CHILD)))
+ else
{
- IntReleaseWindowObject(Window);
- return(0);
+ WinPosFillMinMaxInfoStruct(Window, &SafeMinMax);
}
- ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
- if (Window->MessageQueue != ThreadQueue)
+ Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
+ if(!NT_SUCCESS(Status))
{
IntReleaseWindowObject(Window);
- return(0);
+ SetLastNtError(Status);
+ return FALSE;
}
- Prev = Window->MessageQueue->ActiveWindow;
- WinPosSetActiveWindow(Window, FALSE, FALSE);
+ IntReleaseWindowObject(Window);
+ return TRUE;
+ }
+
IntReleaseWindowObject(Window);
- return(Prev);
+ return FALSE;
}
-
/* EOF */