mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 18:35:41 +00:00
- Painting bugfixes.
svn path=/trunk/; revision=6725
This commit is contained in:
parent
669a79e12b
commit
06c149f1f1
4 changed files with 381 additions and 343 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: vis.h,v 1.3 2003/11/19 09:10:35 navaraf Exp $
|
/* $Id: vis.h,v 1.4 2003/11/20 09:18:49 navaraf Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS Win32k subsystem
|
* PROJECT: ReactOS Win32k subsystem
|
||||||
|
@ -21,7 +21,7 @@ VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
||||||
HRGN UncoveredRgn, BOOL Redraw);
|
HRGN UncoveredRgn);
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
VIS_RepaintDesktop(HWND Desktop, HRGN RepaintRgn);
|
VIS_RepaintDesktop(HWND Desktop, HRGN RepaintRgn);
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*
|
*
|
||||||
* $Id: vis.c,v 1.9 2003/11/19 09:10:36 navaraf Exp $
|
* $Id: vis.c,v 1.10 2003/11/20 09:18:49 navaraf Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -251,7 +251,7 @@ GetUncoveredArea(HRGN Uncovered, PWINDOW_OBJECT Parent, PWINDOW_OBJECT TargetChi
|
||||||
|
|
||||||
VOID FASTCALL
|
VOID FASTCALL
|
||||||
VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
||||||
HRGN NewlyExposed, BOOL Redraw)
|
HRGN NewlyExposed)
|
||||||
{
|
{
|
||||||
PWINDOW_OBJECT DesktopWindow;
|
PWINDOW_OBJECT DesktopWindow;
|
||||||
PWINDOW_OBJECT Parent;
|
PWINDOW_OBJECT Parent;
|
||||||
|
@ -304,8 +304,7 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
||||||
NtGdiOffsetRgn(DirtyRgn, -Sibling->ClientRect.left, -Sibling->ClientRect.top);
|
NtGdiOffsetRgn(DirtyRgn, -Sibling->ClientRect.left, -Sibling->ClientRect.top);
|
||||||
IntRedrawWindow(Sibling, NULL, DirtyRgn,
|
IntRedrawWindow(Sibling, NULL, DirtyRgn,
|
||||||
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
|
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
|
||||||
RDW_ALLCHILDREN |
|
RDW_ALLCHILDREN);
|
||||||
(Redraw ? RDW_ERASENOW | RDW_UPDATENOW : 0));
|
|
||||||
}
|
}
|
||||||
Covered = UnsafeIntCreateRectRgnIndirect(&Sibling->WindowRect);
|
Covered = UnsafeIntCreateRectRgnIndirect(&Sibling->WindowRect);
|
||||||
NtGdiCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF);
|
NtGdiCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF);
|
||||||
|
@ -333,8 +332,7 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
|
||||||
-Parent->ClientRect.top);
|
-Parent->ClientRect.top);
|
||||||
IntRedrawWindow(Parent, NULL, DirtyRgn,
|
IntRedrawWindow(Parent, NULL, DirtyRgn,
|
||||||
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
|
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
|
||||||
RDW_NOCHILDREN |
|
RDW_NOCHILDREN);
|
||||||
(Redraw ? RDW_ERASENOW | RDW_UPDATENOW : 0));
|
|
||||||
}
|
}
|
||||||
NtGdiDeleteObject(ExposedWindow);
|
NtGdiDeleteObject(ExposedWindow);
|
||||||
NtGdiDeleteObject(DirtyRgn);
|
NtGdiDeleteObject(DirtyRgn);
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: window.c,v 1.137 2003/11/19 09:10:36 navaraf Exp $
|
/* $Id: window.c,v 1.138 2003/11/20 09:18:49 navaraf Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -675,7 +675,7 @@ IntInitDesktopWindow(ULONG Width, ULONG Height)
|
||||||
DesktopWindow->ClientRect = DesktopWindow->WindowRect;
|
DesktopWindow->ClientRect = DesktopWindow->WindowRect;
|
||||||
|
|
||||||
DesktopRgn = UnsafeIntCreateRectRgnIndirect(&(DesktopWindow->WindowRect));
|
DesktopRgn = UnsafeIntCreateRectRgnIndirect(&(DesktopWindow->WindowRect));
|
||||||
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, DesktopWindow, DesktopRgn, TRUE);
|
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, DesktopWindow, DesktopRgn);
|
||||||
NtGdiDeleteObject(DesktopRgn);
|
NtGdiDeleteObject(DesktopRgn);
|
||||||
IntReleaseWindowObject(DesktopWindow);
|
IntReleaseWindowObject(DesktopWindow);
|
||||||
}
|
}
|
||||||
|
@ -817,7 +817,7 @@ IntSetFocusWindow(HWND hWnd)
|
||||||
if (hWnd != (HWND)0)
|
if (hWnd != (HWND)0)
|
||||||
{
|
{
|
||||||
WindowObject = IntGetWindowObject(hWnd);
|
WindowObject = IntGetWindowObject(hWnd);
|
||||||
if (!WindowObject)
|
if (!WindowObject || IntIsDesktopWindow(WindowObject))
|
||||||
{
|
{
|
||||||
DPRINT("Bad window handle 0x%x\n", hWnd);
|
DPRINT("Bad window handle 0x%x\n", hWnd);
|
||||||
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||||
|
@ -1811,18 +1811,19 @@ NtUserDestroyWindow(HWND Wnd)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Recursively destroy owned windows */
|
/* Recursively destroy owned windows */
|
||||||
#if 0 /* FIXME */
|
#if 1 /* FIXME */
|
||||||
if (! isChild)
|
if (! isChild)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
BOOL GotOne = FALSE;
|
BOOL GotOne = FALSE;
|
||||||
HWND *Children;
|
HWND *Children;
|
||||||
HWND *ChildHandle;
|
HWND *ChildHandle;
|
||||||
PWINDOW_OBJECT Child;
|
PWINDOW_OBJECT Child, Desktop;
|
||||||
|
|
||||||
Children = IntWinListChildren(IntGetWindowObject(IntGetDesktopWindow());
|
Desktop = IntGetWindowObject(IntGetDesktopWindow());
|
||||||
|
Children = IntWinListChildren(Desktop);
|
||||||
|
IntReleaseWindowObject(Desktop);
|
||||||
if (Children)
|
if (Children)
|
||||||
{
|
{
|
||||||
for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
|
for (ChildHandle = Children; *ChildHandle; ++ChildHandle)
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: winpos.c,v 1.42 2003/11/19 09:10:36 navaraf Exp $
|
/* $Id: winpos.c,v 1.43 2003/11/20 09:18:49 navaraf Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -605,6 +605,109 @@ WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
|
||||||
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
|
ExReleaseFastMutexUnsafe(&Window->ChildrenListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WinPosFixupSWPFlags
|
||||||
|
*
|
||||||
|
* Fix redundant flags and values in the WINDOWPOS structure.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: We don't have NtUserGetForegroundWindow yet. */
|
||||||
|
#if 0
|
||||||
|
if (WinPos->hwnd == NtUserGetForegroundWindow())
|
||||||
|
{
|
||||||
|
WinPos->flags |= SWP_NOACTIVATE; /* Already active */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: TOPMOST not supported yet */
|
||||||
|
if ((WinPos->hwndInsertAfter == HWND_TOPMOST) ||
|
||||||
|
(WinPos->hwndInsertAfter == HWND_NOTOPMOST))
|
||||||
|
{
|
||||||
|
WinPos->hwndInsertAfter = 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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* x and y are always screen relative */
|
/* x and y are always screen relative */
|
||||||
BOOLEAN STDCALL
|
BOOLEAN STDCALL
|
||||||
|
@ -612,7 +715,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
INT cy, UINT flags)
|
INT cy, UINT flags)
|
||||||
{
|
{
|
||||||
PWINDOW_OBJECT Window;
|
PWINDOW_OBJECT Window;
|
||||||
NTSTATUS Status;
|
|
||||||
WINDOWPOS WinPos;
|
WINDOWPOS WinPos;
|
||||||
RECT NewWindowRect;
|
RECT NewWindowRect;
|
||||||
RECT NewClientRect;
|
RECT NewClientRect;
|
||||||
|
@ -623,7 +725,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
HRGN CopyRgn = NULL;
|
HRGN CopyRgn = NULL;
|
||||||
ULONG WvrFlags = 0;
|
ULONG WvrFlags = 0;
|
||||||
RECT OldWindowRect, OldClientRect;
|
RECT OldWindowRect, OldClientRect;
|
||||||
UINT FlagsEx = 0;
|
|
||||||
int RgnType;
|
int RgnType;
|
||||||
HDC Dc;
|
HDC Dc;
|
||||||
RECT CopyRect;
|
RECT CopyRect;
|
||||||
|
@ -632,84 +733,16 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
/* FIXME: Get current active window from active queue. */
|
/* FIXME: Get current active window from active queue. */
|
||||||
|
|
||||||
/* Check if the window is for a desktop. */
|
/* Check if the window is for a desktop. */
|
||||||
if (Wnd == PsGetWin32Thread()->Desktop->DesktopWindow)
|
if (Wnd == IntGetDesktopWindow())
|
||||||
{
|
{
|
||||||
return(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
cx = max(cx, 0);
|
|
||||||
cy = max(cy, 0);
|
|
||||||
|
|
||||||
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->Flags & 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WndInsertAfter == HWND_TOPMOST || WndInsertAfter == HWND_NOTOPMOST)
|
|
||||||
{
|
|
||||||
WndInsertAfter = HWND_TOP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WndInsertAfter != HWND_TOP && WndInsertAfter != HWND_BOTTOM)
|
|
||||||
{
|
|
||||||
if (NtUserGetAncestor(WndInsertAfter, GA_PARENT) != Window->Parent)
|
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
Window = IntGetWindowObject(Wnd);
|
||||||
|
if (!Window)
|
||||||
{
|
{
|
||||||
/*
|
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
|
||||||
* Don't need to change the Zorder of hwnd if it's already inserted
|
return FALSE;
|
||||||
* after hwndInsertAfter or when inserting hwnd after itself.
|
|
||||||
*/
|
|
||||||
if (Wnd == WndInsertAfter ||
|
|
||||||
Wnd == NtUserGetWindow(WndInsertAfter, GW_HWNDNEXT))
|
|
||||||
{
|
|
||||||
flags |= SWP_NOZORDER;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WinPos.hwnd = Wnd;
|
WinPos.hwnd = Wnd;
|
||||||
|
@ -719,55 +752,57 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
WinPos.cx = cx;
|
WinPos.cx = cx;
|
||||||
WinPos.cy = cy;
|
WinPos.cy = cy;
|
||||||
WinPos.flags = flags;
|
WinPos.flags = flags;
|
||||||
if (0 != (Window->Style & WS_CHILD))
|
if (Window->Style & WS_CHILD)
|
||||||
{
|
{
|
||||||
WinPos.x -= Window->Parent->ClientRect.left;
|
WinPos.x -= Window->Parent->ClientRect.left;
|
||||||
WinPos.y -= Window->Parent->ClientRect.top;
|
WinPos.y -= Window->Parent->ClientRect.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fix up the flags. */
|
||||||
|
if (!WinPosFixupFlags(&WinPos, Window))
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||||
|
IntReleaseWindowObject(Window);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
|
WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
|
||||||
|
|
||||||
|
/* Does the window still exist? */
|
||||||
|
if (!IntIsWindow(WinPos.hwnd))
|
||||||
|
{
|
||||||
|
/* FIXME: SetLastWin32Error */
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if ((WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
|
if ((WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
|
||||||
SWP_NOZORDER &&
|
SWP_NOZORDER &&
|
||||||
NtUserGetAncestor(WinPos.hwnd, GA_PARENT) ==
|
NtUserGetAncestor(WinPos.hwnd, GA_PARENT) == IntGetDesktopWindow())
|
||||||
PsGetWin32Thread()->Desktop->DesktopWindow)
|
|
||||||
{
|
{
|
||||||
WinPos.hwndInsertAfter = WinPosDoOwnedPopups(WinPos.hwnd, WinPos.hwndInsertAfter);
|
WinPos.hwndInsertAfter = WinPosDoOwnedPopups(WinPos.hwnd, WinPos.hwndInsertAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Adjust flags based on WndInsertAfter */
|
|
||||||
|
|
||||||
/* Compute the visible region before the window position is changed */
|
/* Compute the visible region before the window position is changed */
|
||||||
if ((!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
|
if ((!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
|
||||||
WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
|
WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
|
||||||
SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
|
SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
|
||||||
(SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
|
(SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
|
||||||
{
|
{
|
||||||
if (Window->Style & WS_CLIPCHILDREN)
|
VisBefore = VIS_ComputeVisibleRegion(
|
||||||
{
|
PsGetWin32Thread()->Desktop, Window, FALSE,
|
||||||
VisBefore = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
|
Window->Style & WS_CLIPCHILDREN, Window->Style & WS_CLIPSIBLINGS);
|
||||||
Window, FALSE, FALSE, TRUE);
|
|
||||||
}
|
if (UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
|
||||||
else
|
|
||||||
{
|
|
||||||
VisBefore = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
|
|
||||||
Window, FALSE, FALSE, FALSE);
|
|
||||||
}
|
|
||||||
if (NULLREGION == UnsafeIntGetRgnBox(VisBefore, &TempRect))
|
|
||||||
{
|
{
|
||||||
NtGdiDeleteObject(VisBefore);
|
NtGdiDeleteObject(VisBefore);
|
||||||
VisBefore = NULL;
|
VisBefore = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
|
WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect);
|
||||||
&NewClientRect);
|
|
||||||
|
|
||||||
/*
|
/* Relink windows. (also take into account shell window in hwndShellWindow) */
|
||||||
* FIXME: Relink windows. (also take into account shell window in hwndShellWindow)
|
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != NtUserGetShellWindow())
|
||||||
*/
|
|
||||||
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwndInsertAfter != WinPos.hwnd &&
|
|
||||||
WinPos.hwnd != NtUserGetShellWindow())
|
|
||||||
{
|
{
|
||||||
PWINDOW_OBJECT ParentWindow;
|
PWINDOW_OBJECT ParentWindow;
|
||||||
PWINDOW_OBJECT InsertAfterWindow;
|
PWINDOW_OBJECT InsertAfterWindow;
|
||||||
|
@ -795,7 +830,19 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
OldWindowRect = Window->WindowRect;
|
OldWindowRect = Window->WindowRect;
|
||||||
OldClientRect = Window->ClientRect;
|
OldClientRect = Window->ClientRect;
|
||||||
|
|
||||||
/* FIXME: Check for redrawing the whole client rect. */
|
if (OldClientRect.bottom - OldClientRect.top ==
|
||||||
|
NewClientRect.bottom - NewClientRect.top)
|
||||||
|
{
|
||||||
|
WvrFlags &= ~WVR_VREDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OldClientRect.right - OldClientRect.left ==
|
||||||
|
NewClientRect.right - NewClientRect.left)
|
||||||
|
{
|
||||||
|
WvrFlags &= ~WVR_HREDRAW;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Actually do something with WVR_VALIDRECTS */
|
||||||
|
|
||||||
if (!(WinPos.flags & SWP_NOMOVE))
|
if (!(WinPos.flags & SWP_NOMOVE))
|
||||||
{
|
{
|
||||||
|
@ -803,58 +850,71 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
NewWindowRect.left - OldWindowRect.left,
|
NewWindowRect.left - OldWindowRect.left,
|
||||||
NewWindowRect.top - OldWindowRect.top);
|
NewWindowRect.top - OldWindowRect.top);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window->WindowRect = NewWindowRect;
|
Window->WindowRect = NewWindowRect;
|
||||||
Window->ClientRect = NewClientRect;
|
Window->ClientRect = NewClientRect;
|
||||||
|
|
||||||
if (WinPos.flags & SWP_SHOWWINDOW)
|
if (!(WinPos.flags & SWP_SHOWWINDOW) && (WinPos.flags & SWP_HIDEWINDOW))
|
||||||
{
|
|
||||||
Window->Style |= WS_VISIBLE;
|
|
||||||
FlagsEx |= SWP_EX_PAINTSELF;
|
|
||||||
}
|
|
||||||
else if (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;
|
Window->Style &= ~WS_VISIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(WinPos.flags & SWP_NOREDRAW))
|
|
||||||
{
|
|
||||||
/* Determine the new visible region */
|
|
||||||
if (Window->Style & WS_CLIPCHILDREN)
|
|
||||||
{
|
|
||||||
VisAfter = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
|
|
||||||
Window, FALSE, FALSE, TRUE);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VisAfter = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
|
Window->Style |= WS_VISIBLE;
|
||||||
Window, FALSE, FALSE, FALSE);
|
|
||||||
}
|
}
|
||||||
if (NULLREGION == UnsafeIntGetRgnBox(VisAfter, &TempRect))
|
|
||||||
|
#if 0
|
||||||
|
if (WvrFlags & WVR_REDRAW)
|
||||||
|
{
|
||||||
|
IntRedrawWindow(Window, NULL, 0, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!(WinPos.flags & SWP_NOACTIVATE))
|
||||||
|
{
|
||||||
|
WinPosChangeActiveWindow(WinPos.hwnd, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: Check some conditions before doing this. */
|
||||||
|
IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
|
||||||
|
|
||||||
|
/* Determine the new visible region */
|
||||||
|
VisAfter = VIS_ComputeVisibleRegion(
|
||||||
|
PsGetWin32Thread()->Desktop, Window, FALSE,
|
||||||
|
Window->Style & WS_CLIPCHILDREN, Window->Style & WS_CLIPSIBLINGS);
|
||||||
|
|
||||||
|
if (UnsafeIntGetRgnBox(VisAfter, &TempRect) == NULLREGION)
|
||||||
{
|
{
|
||||||
NtGdiDeleteObject(VisAfter);
|
NtGdiDeleteObject(VisAfter);
|
||||||
VisAfter = NULL;
|
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
|
* Determine which pixels can be copied from the old window position
|
||||||
position. Also, check the class style to see if the windows of this
|
* to the new. Those pixels must be visible in both the old and new
|
||||||
class need to be completely repainted on (horizontal/vertical) size
|
* position. Also, check the class style to see if the windows of this
|
||||||
change */
|
* class need to be completely repainted on (horizontal/vertical) size
|
||||||
if (NULL != VisBefore && NULL != VisAfter && ! (WinPos.flags & SWP_NOCOPYBITS)
|
* change.
|
||||||
&& ((WinPos.flags & SWP_NOSIZE)
|
*/
|
||||||
|| ! (Window->Class->style & (CS_HREDRAW | CS_VREDRAW))))
|
if (VisBefore != NULL && VisAfter != NULL && !(WinPos.flags & SWP_NOCOPYBITS) &&
|
||||||
|
((WinPos.flags & SWP_NOSIZE) || !(Window->Class->style & (CS_HREDRAW | CS_VREDRAW))))
|
||||||
{
|
{
|
||||||
CopyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
CopyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||||
RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
|
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,
|
* If this is (also) a window resize, the whole nonclient area
|
||||||
'cause there is no use in copying it (would possibly cause
|
* needs to be repainted. So we limit the copy to the client area,
|
||||||
"flashing" too). However, if the copy region is already empty,
|
* 'cause there is no use in copying it (would possibly cause
|
||||||
we don't have to crop (can't take anything away from an empty
|
* "flashing" too). However, if the copy region is already empty,
|
||||||
region...) */
|
* we don't have to crop (can't take anything away from an empty
|
||||||
if (! (WinPos.flags & SWP_NOSIZE)
|
* region...)
|
||||||
&& ERROR != RgnType && NULLREGION != RgnType)
|
*/
|
||||||
|
if (!(WinPos.flags & SWP_NOSIZE) && RgnType != ERROR &&
|
||||||
|
RgnType != NULLREGION)
|
||||||
{
|
{
|
||||||
RECT ORect = OldClientRect;
|
RECT ORect = OldClientRect;
|
||||||
RECT NRect = NewClientRect;
|
RECT NRect = NewClientRect;
|
||||||
|
@ -865,43 +925,40 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No use in copying bits which are in the update region. */
|
/* No use in copying bits which are in the update region. */
|
||||||
if ((HRGN) 1 == Window->UpdateRegion)
|
if (Window->UpdateRegion != NULL)
|
||||||
{
|
|
||||||
/* The whole window is in the update region. No use
|
|
||||||
copying anything, so set the copy region empty */
|
|
||||||
NtGdiSetRectRgn(CopyRgn, 0, 0, 0, 0);
|
|
||||||
}
|
|
||||||
else if (1 < (DWORD) Window->UpdateRegion)
|
|
||||||
{
|
{
|
||||||
NtGdiCombineRgn(CopyRgn, CopyRgn, Window->UpdateRegion, RGN_DIFF);
|
NtGdiCombineRgn(CopyRgn, CopyRgn, Window->UpdateRegion, RGN_DIFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
/* Now, get the bounding box of the copy region. If it's empty
|
* 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
|
* there's nothing to copy. Also, it's no use copying bits onto
|
||||||
themselves */
|
* themselves.
|
||||||
UnsafeIntGetRgnBox(CopyRgn, &CopyRect);
|
*/
|
||||||
if (NtGdiIsEmptyRect(&CopyRect))
|
if (UnsafeIntGetRgnBox(CopyRgn, &CopyRect) == NULLREGION)
|
||||||
{
|
{
|
||||||
/* Nothing to copy, clean up */
|
/* Nothing to copy, clean up */
|
||||||
NtGdiDeleteObject(CopyRgn);
|
NtGdiDeleteObject(CopyRgn);
|
||||||
CopyRgn = NULL;
|
CopyRgn = NULL;
|
||||||
}
|
}
|
||||||
else if (OldWindowRect.left != NewWindowRect.left
|
else if (OldWindowRect.left != NewWindowRect.left ||
|
||||||
|| OldWindowRect.top != NewWindowRect.top)
|
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
|
* Small trick here: there is no function to bitblt a region. So
|
||||||
of the region and bitblt that. Since nothing outside the clipping
|
* we set the region as the clipping region, take the bounding box
|
||||||
region is copied, this has the effect of bitblt'ing the region.
|
* 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 */
|
* 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);
|
HRGN ClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||||
NtGdiCombineRgn(ClipRgn, CopyRgn, NULL, RGN_COPY);
|
NtGdiCombineRgn(ClipRgn, CopyRgn, NULL, RGN_COPY);
|
||||||
Dc = NtUserGetDCEx(Wnd, ClipRgn, DCX_WINDOW | DCX_CACHE |
|
Dc = NtUserGetDCEx(Wnd, ClipRgn, DCX_WINDOW | DCX_CACHE |
|
||||||
DCX_INTERSECTRGN | DCX_CLIPSIBLINGS);
|
DCX_INTERSECTRGN | DCX_CLIPSIBLINGS);
|
||||||
NtGdiBitBlt(Dc, CopyRect.left, CopyRect.top, CopyRect.right - CopyRect.left,
|
NtGdiBitBlt(Dc,
|
||||||
|
CopyRect.left, CopyRect.top, CopyRect.right - CopyRect.left,
|
||||||
CopyRect.bottom - CopyRect.top, Dc,
|
CopyRect.bottom - CopyRect.top, Dc,
|
||||||
CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
|
CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
|
||||||
CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY);
|
CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY);
|
||||||
|
@ -914,81 +971,63 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We need to redraw what wasn't visible before */
|
/* We need to redraw what wasn't visible before */
|
||||||
if (NULL != VisAfter)
|
if (VisAfter != NULL)
|
||||||
{
|
{
|
||||||
if (NULL != CopyRgn)
|
if (CopyRgn != NULL)
|
||||||
{
|
{
|
||||||
DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||||
RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
|
RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
|
||||||
if (ERROR != RgnType && NULLREGION != RgnType)
|
if (RgnType != ERROR && RgnType != NULLREGION)
|
||||||
{
|
{
|
||||||
NtGdiOffsetRgn(DirtyRgn,
|
NtGdiOffsetRgn(DirtyRgn,
|
||||||
Window->WindowRect.left - Window->ClientRect.left,
|
Window->WindowRect.left - Window->ClientRect.left,
|
||||||
Window->WindowRect.top - Window->ClientRect.top);
|
Window->WindowRect.top - Window->ClientRect.top);
|
||||||
IntRedrawWindow(Window, NULL, DirtyRgn,
|
IntRedrawWindow(Window, NULL, DirtyRgn,
|
||||||
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
|
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||||
RDW_ALLCHILDREN |
|
|
||||||
((flags & SWP_NOREDRAW) ? 0 : RDW_ERASENOW | RDW_UPDATENOW));
|
|
||||||
}
|
}
|
||||||
NtGdiDeleteObject(DirtyRgn);
|
NtGdiDeleteObject(DirtyRgn);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IntRedrawWindow(Window, NULL, NULL,
|
IntRedrawWindow(Window, NULL, NULL,
|
||||||
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
|
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||||
RDW_ALLCHILDREN |
|
|
||||||
((flags & SWP_NOREDRAW) ? 0 : RDW_ERASENOW | RDW_UPDATENOW));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != CopyRgn)
|
if (CopyRgn != NULL)
|
||||||
{
|
{
|
||||||
NtGdiDeleteObject(CopyRgn);
|
NtGdiDeleteObject(CopyRgn);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Expose what was covered before but not covered anymore */
|
/* Expose what was covered before but not covered anymore */
|
||||||
if (NULL != VisBefore)
|
if (VisBefore != NULL)
|
||||||
{
|
{
|
||||||
ExposedRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
ExposedRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||||
NtGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
|
NtGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
|
||||||
NtGdiOffsetRgn(ExposedRgn, OldWindowRect.left - NewWindowRect.left,
|
NtGdiOffsetRgn(ExposedRgn, OldWindowRect.left - NewWindowRect.left,
|
||||||
OldWindowRect.top - NewWindowRect.top);
|
OldWindowRect.top - NewWindowRect.top);
|
||||||
if (NULL != VisAfter)
|
if (VisAfter != NULL)
|
||||||
{
|
|
||||||
RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
|
RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
|
||||||
RgnType = SIMPLEREGION;
|
RgnType = SIMPLEREGION;
|
||||||
}
|
|
||||||
if (ERROR != RgnType && NULLREGION != RgnType)
|
if (RgnType != ERROR && RgnType != NULLREGION)
|
||||||
{
|
{
|
||||||
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window,
|
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window,
|
||||||
ExposedRgn, !(flags & SWP_NOREDRAW));
|
ExposedRgn);
|
||||||
}
|
}
|
||||||
NtGdiDeleteObject(ExposedRgn);
|
NtGdiDeleteObject(ExposedRgn);
|
||||||
|
|
||||||
NtGdiDeleteObject(VisBefore);
|
NtGdiDeleteObject(VisBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NULL != VisAfter)
|
if (VisAfter != NULL)
|
||||||
{
|
{
|
||||||
NtGdiDeleteObject(VisAfter);
|
NtGdiDeleteObject(VisAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Hide or show the claret */
|
|
||||||
|
|
||||||
if (!(flags & SWP_NOACTIVATE))
|
|
||||||
{
|
|
||||||
WinPosChangeActiveWindow(WinPos.hwnd, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* FIXME: Check some conditions before doing this. */
|
|
||||||
IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
|
|
||||||
|
|
||||||
IntReleaseWindowObject(Window);
|
IntReleaseWindowObject(Window);
|
||||||
return(TRUE);
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT STDCALL
|
LRESULT STDCALL
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue