- Painting bugfixes.

svn path=/trunk/; revision=6725
This commit is contained in:
Filip Navara 2003-11-20 09:18:49 +00:00
parent 669a79e12b
commit 06c149f1f1
4 changed files with 381 additions and 343 deletions

View file

@ -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
* PROJECT: ReactOS Win32k subsystem
@ -21,7 +21,7 @@ VIS_ComputeVisibleRegion(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
VOID FASTCALL
VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
HRGN UncoveredRgn, BOOL Redraw);
HRGN UncoveredRgn);
VOID FASTCALL
VIS_RepaintDesktop(HWND Desktop, HRGN RepaintRgn);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* PROJECT: ReactOS kernel
@ -251,7 +251,7 @@ GetUncoveredArea(HRGN Uncovered, PWINDOW_OBJECT Parent, PWINDOW_OBJECT TargetChi
VOID FASTCALL
VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
HRGN NewlyExposed, BOOL Redraw)
HRGN NewlyExposed)
{
PWINDOW_OBJECT DesktopWindow;
PWINDOW_OBJECT Parent;
@ -304,8 +304,7 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
NtGdiOffsetRgn(DirtyRgn, -Sibling->ClientRect.left, -Sibling->ClientRect.top);
IntRedrawWindow(Sibling, NULL, DirtyRgn,
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
RDW_ALLCHILDREN |
(Redraw ? RDW_ERASENOW | RDW_UPDATENOW : 0));
RDW_ALLCHILDREN);
}
Covered = UnsafeIntCreateRectRgnIndirect(&Sibling->WindowRect);
NtGdiCombineRgn(Uncovered, Uncovered, Covered, RGN_DIFF);
@ -333,8 +332,7 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
-Parent->ClientRect.top);
IntRedrawWindow(Parent, NULL, DirtyRgn,
RDW_INVALIDATE | RDW_FRAME | RDW_ERASE |
RDW_NOCHILDREN |
(Redraw ? RDW_ERASENOW | RDW_UPDATENOW : 0));
RDW_NOCHILDREN);
}
NtGdiDeleteObject(ExposedWindow);
NtGdiDeleteObject(DirtyRgn);

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* 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
* PROJECT: ReactOS kernel
@ -675,7 +675,7 @@ IntInitDesktopWindow(ULONG Width, ULONG Height)
DesktopWindow->ClientRect = DesktopWindow->WindowRect;
DesktopRgn = UnsafeIntCreateRectRgnIndirect(&(DesktopWindow->WindowRect));
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, DesktopWindow, DesktopRgn, TRUE);
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, DesktopWindow, DesktopRgn);
NtGdiDeleteObject(DesktopRgn);
IntReleaseWindowObject(DesktopWindow);
}
@ -817,7 +817,7 @@ IntSetFocusWindow(HWND hWnd)
if (hWnd != (HWND)0)
{
WindowObject = IntGetWindowObject(hWnd);
if (!WindowObject)
if (!WindowObject || IntIsDesktopWindow(WindowObject))
{
DPRINT("Bad window handle 0x%x\n", hWnd);
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
@ -1811,18 +1811,19 @@ NtUserDestroyWindow(HWND Wnd)
}
/* Recursively destroy owned windows */
#if 0 /* FIXME */
#if 1 /* FIXME */
if (! isChild)
{
for (;;)
{
int i;
BOOL GotOne = FALSE;
HWND *Children;
HWND *ChildHandle;
PWINDOW_OBJECT Child;
PWINDOW_OBJECT Child, Desktop;
Children = IntWinListChildren(IntGetWindowObject(IntGetDesktopWindow());
Desktop = IntGetWindowObject(IntGetDesktopWindow());
Children = IntWinListChildren(Desktop);
IntReleaseWindowObject(Desktop);
if (Children)
{
for (ChildHandle = Children; *ChildHandle; ++ChildHandle)

View file

@ -16,7 +16,7 @@
* 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.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
* PROJECT: ReactOS kernel
@ -605,6 +605,109 @@ WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
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 */
BOOLEAN STDCALL
@ -612,7 +715,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
INT cy, UINT flags)
{
PWINDOW_OBJECT Window;
NTSTATUS Status;
WINDOWPOS WinPos;
RECT NewWindowRect;
RECT NewClientRect;
@ -623,7 +725,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
HRGN CopyRgn = NULL;
ULONG WvrFlags = 0;
RECT OldWindowRect, OldClientRect;
UINT FlagsEx = 0;
int RgnType;
HDC Dc;
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. */
/* 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;
}
else
Window = IntGetWindowObject(Wnd);
if (!Window)
{
/*
* Don't need to change the Zorder of hwnd if it's already inserted
* after hwndInsertAfter or when inserting hwnd after itself.
*/
if (Wnd == WndInsertAfter ||
Wnd == NtUserGetWindow(WndInsertAfter, GW_HWNDNEXT))
{
flags |= SWP_NOZORDER;
}
}
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE;
}
WinPos.hwnd = Wnd;
@ -719,55 +752,57 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
WinPos.cx = cx;
WinPos.cy = cy;
WinPos.flags = flags;
if (0 != (Window->Style & WS_CHILD))
if (Window->Style & WS_CHILD)
{
WinPos.x -= Window->Parent->ClientRect.left;
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);
/* Does the window still exist? */
if (!IntIsWindow(WinPos.hwnd))
{
/* FIXME: SetLastWin32Error */
return FALSE;
}
if ((WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
SWP_NOZORDER &&
NtUserGetAncestor(WinPos.hwnd, GA_PARENT) ==
PsGetWin32Thread()->Desktop->DesktopWindow)
NtUserGetAncestor(WinPos.hwnd, GA_PARENT) == IntGetDesktopWindow())
{
WinPos.hwndInsertAfter = WinPosDoOwnedPopups(WinPos.hwnd, WinPos.hwndInsertAfter);
}
/* FIXME: Adjust flags based on WndInsertAfter */
/* 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))
{
if (Window->Style & WS_CLIPCHILDREN)
{
VisBefore = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, TRUE);
}
else
{
VisBefore = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, FALSE);
}
if (NULLREGION == UnsafeIntGetRgnBox(VisBefore, &TempRect))
VisBefore = VIS_ComputeVisibleRegion(
PsGetWin32Thread()->Desktop, Window, FALSE,
Window->Style & WS_CLIPCHILDREN, Window->Style & WS_CLIPSIBLINGS);
if (UnsafeIntGetRgnBox(VisBefore, &TempRect) == NULLREGION)
{
NtGdiDeleteObject(VisBefore);
VisBefore = NULL;
}
}
WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect,
&NewClientRect);
WvrFlags = WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect);
/*
* FIXME: Relink windows. (also take into account shell window in hwndShellWindow)
*/
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwndInsertAfter != WinPos.hwnd &&
WinPos.hwnd != NtUserGetShellWindow())
/* Relink windows. (also take into account shell window in hwndShellWindow) */
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != NtUserGetShellWindow())
{
PWINDOW_OBJECT ParentWindow;
PWINDOW_OBJECT InsertAfterWindow;
@ -795,7 +830,19 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
OldWindowRect = Window->WindowRect;
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))
{
@ -803,58 +850,71 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
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;
}
else if (WinPos.flags & SWP_HIDEWINDOW)
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;
}
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
{
VisAfter = VIS_ComputeVisibleRegion(PsGetWin32Thread()->Desktop,
Window, FALSE, FALSE, FALSE);
Window->Style |= WS_VISIBLE;
}
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);
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 (NULL != VisBefore && NULL != VisAfter && ! (WinPos.flags & SWP_NOCOPYBITS)
&& ((WinPos.flags & SWP_NOSIZE)
|| ! (Window->Class->style & (CS_HREDRAW | CS_VREDRAW))))
/*
* 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) || !(Window->Class->style & (CS_HREDRAW | CS_VREDRAW))))
{
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)
&& ERROR != RgnType && NULLREGION != RgnType)
/*
* 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;
@ -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. */
if ((HRGN) 1 == Window->UpdateRegion)
{
/* 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)
if (Window->UpdateRegion != NULL)
{
NtGdiCombineRgn(CopyRgn, CopyRgn, Window->UpdateRegion, 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 */
UnsafeIntGetRgnBox(CopyRgn, &CopyRect);
if (NtGdiIsEmptyRect(&CopyRect))
/*
* 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)
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 */
/*
* 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,
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);
@ -914,81 +971,63 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
}
/* 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);
RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
if (ERROR != RgnType && NULLREGION != RgnType)
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 |
((flags & SWP_NOREDRAW) ? 0 : RDW_ERASENOW | RDW_UPDATENOW));
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
NtGdiDeleteObject(DirtyRgn);
}
else
{
IntRedrawWindow(Window, NULL, NULL,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE |
RDW_ALLCHILDREN |
((flags & SWP_NOREDRAW) ? 0 : RDW_ERASENOW | RDW_UPDATENOW));
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
}
}
if (NULL != CopyRgn)
if (CopyRgn != NULL)
{
NtGdiDeleteObject(CopyRgn);
}
}
/* Expose what was covered before but not covered anymore */
if (NULL != VisBefore)
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 (NULL != VisAfter)
{
if (VisAfter != NULL)
RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
}
else
{
RgnType = SIMPLEREGION;
}
if (ERROR != RgnType && NULLREGION != RgnType)
if (RgnType != ERROR && RgnType != NULLREGION)
{
VIS_WindowLayoutChanged(PsGetWin32Thread()->Desktop, Window,
ExposedRgn, !(flags & SWP_NOREDRAW));
ExposedRgn);
}
NtGdiDeleteObject(ExposedRgn);
NtGdiDeleteObject(VisBefore);
}
if (NULL != VisAfter)
if (VisAfter != NULL)
{
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);
return(TRUE);
return TRUE;
}
LRESULT STDCALL