- More painting bugfixes.

svn path=/trunk/; revision=6737
This commit is contained in:
Filip Navara 2003-11-21 17:01:16 +00:00
parent b14e35b6ac
commit 967fd54cdd
8 changed files with 180 additions and 131 deletions

View file

@ -10,7 +10,7 @@
BOOL FASTCALL BOOL FASTCALL
IntRedrawWindow(PWINDOW_OBJECT Wnd, const RECT* UpdateRect, HRGN UpdateRgn, ULONG Flags); IntRedrawWindow(PWINDOW_OBJECT Wnd, const RECT* UpdateRect, HRGN UpdateRgn, ULONG Flags);
BOOL FASTCALL BOOL FASTCALL
IntGetPaintMessage(PWINDOW_OBJECT Window, PW32THREAD Thread, MSG *Message); IntGetPaintMessage(PWINDOW_OBJECT Window, PW32THREAD Thread, MSG *Message, BOOL Remove);
BOOL STDCALL BOOL STDCALL
NtUserValidateRgn(HWND hWnd, HRGN hRgn); NtUserValidateRgn(HWND hWnd, HRGN hRgn);

View file

@ -88,7 +88,6 @@ typedef struct _WINDOW_OBJECT
#define WINDOWOBJECT_NEED_ERASEBKGND (0x00000002) #define WINDOWOBJECT_NEED_ERASEBKGND (0x00000002)
#define WINDOWOBJECT_NEED_NCPAINT (0x00000004) #define WINDOWOBJECT_NEED_NCPAINT (0x00000004)
#define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008) #define WINDOWOBJECT_NEED_INTERNALPAINT (0x00000008)
#define WINDOWOBJECT_MAPPING (0x00000010)
#define WINDOWOBJECT_RESTOREMAX (0x00000020) #define WINDOWOBJECT_RESTOREMAX (0x00000020)
inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT WindowObject); inline BOOL IntIsDesktopWindow(PWINDOW_OBJECT WindowObject);

View file

@ -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: message.c,v 1.33 2003/11/19 13:19:40 weiden Exp $ /* $Id: message.c,v 1.34 2003/11/21 17:01:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -203,12 +203,9 @@ IntPeekMessage(LPMSG Msg,
; ;
/* Check for paint messages. */ /* Check for paint messages. */
if (ThreadQueue->PaintPosted) if (IntGetPaintMessage(Wnd, PsGetWin32Thread(), Msg, RemoveMessages))
{ {
if (IntGetPaintMessage(Wnd, PsGetWin32Thread(), Msg)) return TRUE;
{
return TRUE;
}
} }
return FALSE; return FALSE;

View file

@ -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: msgqueue.c,v 1.32 2003/11/21 16:36:26 weiden Exp $ /* $Id: msgqueue.c,v 1.33 2003/11/21 17:01:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -819,6 +819,8 @@ MsqInitializeMessageQueue(struct _ETHREAD *Thread, PUSER_MESSAGE_QUEUE MessageQu
KeInitializeEvent(&MessageQueue->NewMessages, SynchronizationEvent, FALSE); KeInitializeEvent(&MessageQueue->NewMessages, SynchronizationEvent, FALSE);
MessageQueue->QueueStatus = 0; MessageQueue->QueueStatus = 0;
MessageQueue->FocusWindow = NULL; MessageQueue->FocusWindow = NULL;
MessageQueue->PaintPosted = FALSE;
MessageQueue->PaintCount = 0;
} }
VOID FASTCALL VOID FASTCALL

View file

@ -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: painting.c,v 1.36 2003/11/20 21:21:29 navaraf Exp $ * $Id: painting.c,v 1.37 2003/11/21 17:01:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -60,6 +60,40 @@
/* PRIVATE FUNCTIONS **********************************************************/ /* PRIVATE FUNCTIONS **********************************************************/
VOID FASTCALL
IntValidateParent(PWINDOW_OBJECT Child)
{
HWND Parent;
PWINDOW_OBJECT ParentWindow;
Parent = NtUserGetAncestor(Child->Self, GA_PARENT);
while (Parent && Parent != IntGetDesktopWindow())
{
ParentWindow = IntGetWindowObject(Parent);
if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN))
{
if (ParentWindow->UpdateRegion != 0)
{
INT OffsetX, OffsetY;
/*
* We must offset the child region by the offset of the
* child rect in the parent.
*/
OffsetX = Child->WindowRect.left - ParentWindow->WindowRect.left;
OffsetY = Child->WindowRect.top - ParentWindow->WindowRect.top;
NtGdiOffsetRgn(Child->UpdateRegion, OffsetX, OffsetY );
NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion,
Child->UpdateRegion, RGN_DIFF);
/* FIXME: If the resulting region is empty, remove fake posted paint message */
NtGdiOffsetRgn(Child->UpdateRegion, -OffsetX, -OffsetY);
}
}
IntReleaseWindowObject(ParentWindow);
Parent = NtUserGetAncestor(Parent, GA_PARENT);
}
}
/* /*
* IntGetNCUpdateRegion * IntGetNCUpdateRegion
* *
@ -72,17 +106,16 @@
* Remarks * Remarks
* This function also marks the nonclient update region of window * This function also marks the nonclient update region of window
* as valid, clears the WINDOWOBJECT_NEED_NCPAINT flag and removes * as valid, clears the WINDOWOBJECT_NEED_NCPAINT flag and removes
* the fake paint message from message queue. * the fake paint message from message queue if the Remove is set
* to TRUE.
*/ */
HRGN FASTCALL HRGN FASTCALL
IntGetNCUpdateRegion(PWINDOW_OBJECT Window) IntGetNCUpdateRegion(PWINDOW_OBJECT Window, BOOL Remove)
{ {
HRGN WindowRgn; HRGN WindowRgn;
HRGN NonclientRgn; HRGN NonclientRgn;
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
MsqDecPaintCountQueue(Window->MessageQueue);
WindowRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); WindowRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
NtGdiOffsetRgn(WindowRgn, NtGdiOffsetRgn(WindowRgn,
-Window->WindowRect.left, -Window->WindowRect.left,
@ -94,11 +127,16 @@ IntGetNCUpdateRegion(PWINDOW_OBJECT Window)
NtGdiDeleteObject(NonclientRgn); NtGdiDeleteObject(NonclientRgn);
NonclientRgn = NULL; NonclientRgn = NULL;
} }
if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion, if (Remove)
WindowRgn, RGN_AND) == NULLREGION)
{ {
NtGdiDeleteObject(Window->UpdateRegion); if (NtGdiCombineRgn(Window->UpdateRegion, Window->UpdateRegion,
Window->UpdateRegion = NULL; WindowRgn, RGN_AND) == NULLREGION)
{
NtGdiDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL;
}
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
MsqDecPaintCountQueue(Window->MessageQueue);
} }
return NonclientRgn; return NonclientRgn;
@ -165,7 +203,7 @@ IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags)
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
{ {
NtUserSendMessage(hWnd, WM_NCPAINT, (WPARAM)IntGetNCUpdateRegion(Window), 0); NtUserSendMessage(hWnd, WM_NCPAINT, (WPARAM)IntGetNCUpdateRegion(Window, TRUE), 0);
} }
if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND) if (Window->Flags & WINDOWOBJECT_NEED_ERASEBKGND)
@ -244,12 +282,9 @@ VOID FASTCALL
IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags) IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
{ {
INT RgnType; INT RgnType;
BOOL HadPaintMessage, HadNCPaintMessage;
BOOL HasPaintMessage, HasNCPaintMessage;
if (!(Window->Style & WS_VISIBLE))
{
return;
}
/* /*
* Clip the given region with window rectangle (or region) * Clip the given region with window rectangle (or region)
*/ */
@ -264,6 +299,7 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
-Window->WindowRect.left, -Window->WindowRect.left,
-Window->WindowRect.top); -Window->WindowRect.top);
RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND); RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);
NtGdiDeleteObject(hRgnWindow);
} }
#ifdef TODO #ifdef TODO
else else
@ -272,38 +308,19 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
} }
#endif #endif
if (RgnType == NULLREGION)
{
return;
}
/* /*
* Remove fake posted paint messages from window message queue * Save current state of pending updates
*/ */
#ifndef DESKTOP_IN_CSRSS HadPaintMessage = Window->UpdateRegion != NULL ||
if (!IntIsDesktopWindow(Window)) Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
{ HadNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT;
#endif
if (Window->UpdateRegion != NULL ||
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
{
MsqDecPaintCountQueue(Window->MessageQueue);
}
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
{
MsqDecPaintCountQueue(Window->MessageQueue);
}
#ifndef DESKTOP_IN_CSRSS
}
#endif
/* /*
* Update the region and flags * Update the region and flags
*/ */
if (Flags & RDW_INVALIDATE) if (Flags & RDW_INVALIDATE && RgnType != NULLREGION)
{ {
if (Window->UpdateRegion == NULL) if (Window->UpdateRegion == NULL)
{ {
@ -325,7 +342,7 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
Flags |= RDW_FRAME; Flags |= RDW_FRAME;
} }
if (Flags & RDW_VALIDATE) if (Flags & RDW_VALIDATE && RgnType != NULLREGION)
{ {
if (Window->UpdateRegion != NULL) if (Window->UpdateRegion != NULL)
{ {
@ -337,6 +354,8 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
} }
} }
if (Window->UpdateRegion == NULL)
Window->Flags &= ~WINDOWOBJECT_NEED_ERASEBKGND;
if (Flags & RDW_NOFRAME) if (Flags & RDW_NOFRAME)
Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT; Window->Flags &= ~WINDOWOBJECT_NEED_NCPAINT;
if (Flags & RDW_NOERASE) if (Flags & RDW_NOERASE)
@ -354,22 +373,31 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
} }
/* /*
* Fake post paint messages to window message queue * Fake post paint messages to window message queue if needed
*/ */
#ifndef DESKTOP_IN_CSRSS #ifndef DESKTOP_IN_CSRSS
if (!IntIsDesktopWindow(Window)) if (Window->MessageQueue)
{
#endif #endif
if (Window->UpdateRegion != NULL || {
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) HasPaintMessage = Window->UpdateRegion != NULL ||
Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT;
HasNCPaintMessage = Window->Flags & WINDOWOBJECT_NEED_NCPAINT;
if (HasPaintMessage != HadPaintMessage)
{ {
MsqIncPaintCountQueue(Window->MessageQueue); if (HadPaintMessage)
MsqDecPaintCountQueue(Window->MessageQueue);
else
MsqIncPaintCountQueue(Window->MessageQueue);
} }
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) if (HasNCPaintMessage != HadNCPaintMessage)
{ {
MsqIncPaintCountQueue(Window->MessageQueue); if (HadNCPaintMessage)
MsqDecPaintCountQueue(Window->MessageQueue);
else
MsqIncPaintCountQueue(Window->MessageQueue);
} }
#ifndef DESKTOP_IN_CSRSS #ifndef DESKTOP_IN_CSRSS
} }
@ -389,14 +417,18 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
{ {
for (phWnd = List; *phWnd; ++phWnd) for (phWnd = List; *phWnd; ++phWnd)
{ {
HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
Child = IntGetWindowObject(*phWnd); Child = IntGetWindowObject(*phWnd);
NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY); if ((Child->Style & (WS_VISIBLE | WS_MINIMIZE)) == WS_VISIBLE)
NtGdiOffsetRgn(hRgnTemp, {
Window->WindowRect.left - Child->WindowRect.left, HRGN hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
Window->WindowRect.top - Child->WindowRect.top); Child = IntGetWindowObject(*phWnd);
IntInvalidateWindows(Child, hRgnTemp, Flags); NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
NtGdiDeleteObject(hRgnTemp); NtGdiOffsetRgn(hRgnTemp,
Window->WindowRect.left - Child->WindowRect.left,
Window->WindowRect.top - Child->WindowRect.top);
IntInvalidateWindows(Child, hRgnTemp, Flags);
NtGdiDeleteObject(hRgnTemp);
}
IntReleaseWindowObject(Child); IntReleaseWindowObject(Child);
} }
ExFreePool(List); ExFreePool(List);
@ -404,37 +436,24 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
} }
} }
VOID FASTCALL /*
IntValidateParent(PWINDOW_OBJECT Child) * IntIsWindowDrawable
*
* Remarks
* Window is drawable when it is visible, all parents are not
* minimized, and it is itself not minimized.
*/
BOOL FASTCALL
IntIsWindowDrawable(PWINDOW_OBJECT Window)
{ {
HWND Parent; for (; Window; Window = Window->Parent)
PWINDOW_OBJECT ParentWindow;
Parent = NtUserGetAncestor(Child->Self, GA_PARENT);
while (Parent && Parent != IntGetDesktopWindow())
{ {
ParentWindow = IntGetWindowObject(Parent); if ((Window->Style & (WS_VISIBLE | WS_MINIMIZE)) != WS_VISIBLE)
if (ParentWindow && !(ParentWindow->Style & WS_CLIPCHILDREN)) return FALSE;
{
if (ParentWindow->UpdateRegion != 0)
{
INT OffsetX, OffsetY;
/*
* We must offset the child region by the offset of the
* child rect in the parent.
*/
OffsetX = Child->WindowRect.left - ParentWindow->WindowRect.left;
OffsetY = Child->WindowRect.top - ParentWindow->WindowRect.top;
NtGdiOffsetRgn(Child->UpdateRegion, OffsetX, OffsetY );
NtGdiCombineRgn(ParentWindow->UpdateRegion, ParentWindow->UpdateRegion,
Child->UpdateRegion, RGN_DIFF);
NtGdiOffsetRgn(Child->UpdateRegion, -OffsetX, -OffsetY);
}
}
IntReleaseWindowObject(ParentWindow);
Parent = NtUserGetAncestor(Parent, GA_PARENT);
} }
return TRUE;
} }
/* /*
@ -455,7 +474,9 @@ IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
* Validation of passed parameters. * Validation of passed parameters.
*/ */
if ((Flags & (RDW_VALIDATE | RDW_INVALIDATE)) == (RDW_VALIDATE | RDW_INVALIDATE)) if (!IntIsWindowDrawable(Window) ||
(Flags & (RDW_VALIDATE | RDW_INVALIDATE)) ==
(RDW_VALIDATE | RDW_INVALIDATE))
{ {
return FALSE; return FALSE;
} }
@ -514,7 +535,7 @@ IntRedrawWindow(PWINDOW_OBJECT Window, const RECT* UpdateRect, HRGN UpdateRgn,
* Validate parent covered by region. * Validate parent covered by region.
*/ */
if (Window->UpdateRegion != NULL && Flags & RDW_UPDATENOW) if (Window->UpdateRegion != NULL && Flags & (RDW_ERASENOW | RDW_VALIDATE))
{ {
IntValidateParent(Window); IntValidateParent(Window);
} }
@ -557,6 +578,10 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
CurrentEntry = CurrentEntry->Flink) CurrentEntry = CurrentEntry->Flink)
{ {
Window = CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, ThreadListEntry); Window = CONTAINING_RECORD(CurrentEntry, WINDOW_OBJECT, ThreadListEntry);
if (Window->Parent != NULL && !IntIsDesktopWindow(Window->Parent))
{
continue;
}
if (Window->Style & WS_VISIBLE) if (Window->Style & WS_VISIBLE)
{ {
hFoundWnd = IntFindWindowToRepaint(Window->Self, Thread); hFoundWnd = IntFindWindowToRepaint(Window->Self, Thread);
@ -586,7 +611,6 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
ExAcquireFastMutex(&Window->ChildrenListLock); ExAcquireFastMutex(&Window->ChildrenListLock);
#if 0
for (Child = Window->FirstChild; Child; Child = Child->NextSibling) for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
{ {
if (Child->Style & WS_VISIBLE && if (Child->Style & WS_VISIBLE &&
@ -601,7 +625,6 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
if (hFoundWnd == NULL) if (hFoundWnd == NULL)
{ {
#endif
for (Child = Window->FirstChild; Child; Child = Child->NextSibling) for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
{ {
if (Child->Style & WS_VISIBLE) if (Child->Style & WS_VISIBLE)
@ -611,9 +634,7 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
break; break;
} }
} }
#if 0
} }
#endif
ExReleaseFastMutex(&Window->ChildrenListLock); ExReleaseFastMutex(&Window->ChildrenListLock);
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
@ -623,9 +644,14 @@ IntFindWindowToRepaint(HWND hWnd, PW32THREAD Thread)
} }
BOOL FASTCALL BOOL FASTCALL
IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message) IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message,
BOOL Remove)
{ {
PWINDOW_OBJECT Window; PWINDOW_OBJECT Window;
PUSER_MESSAGE_QUEUE MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
if (!MessageQueue->PaintPosted)
return FALSE;
if (Wnd) if (Wnd)
Message->hwnd = IntFindWindowToRepaint(Wnd->Self, PsGetWin32Thread()); Message->hwnd = IntFindWindowToRepaint(Wnd->Self, PsGetWin32Thread());
@ -634,15 +660,7 @@ IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message)
if (Message->hwnd == NULL) if (Message->hwnd == NULL)
{ {
PUSER_MESSAGE_QUEUE MessageQueue;
DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n"); DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
ExAcquireFastMutex(&MessageQueue->Lock);
DPRINT1("Current paint count: %d\n", MessageQueue->PaintCount);
MessageQueue->PaintCount = 0;
MessageQueue->PaintPosted = FALSE;
ExReleaseFastMutex(&MessageQueue->Lock);
return FALSE; return FALSE;
} }
@ -652,13 +670,13 @@ IntGetPaintMessage(PWINDOW_OBJECT Wnd, PW32THREAD Thread, MSG *Message)
if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT) if (Window->Flags & WINDOWOBJECT_NEED_NCPAINT)
{ {
Message->message = WM_NCPAINT; Message->message = WM_NCPAINT;
Message->wParam = (WPARAM)IntGetNCUpdateRegion(Window); Message->wParam = (WPARAM)IntGetNCUpdateRegion(Window, Remove);
Message->lParam = 0; Message->lParam = 0;
} else } else
{ {
Message->message = WM_PAINT; Message->message = WM_PAINT;
Message->wParam = Message->lParam = 0; Message->wParam = Message->lParam = 0;
if (Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT) if (Remove && Window->Flags & WINDOWOBJECT_NEED_INTERNALPAINT)
{ {
Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT; Window->Flags &= ~WINDOWOBJECT_NEED_INTERNALPAINT;
if (Window->UpdateRegion == NULL) if (Window->UpdateRegion == NULL)
@ -715,9 +733,11 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* lPs)
return NULL; return NULL;
} }
/* IntRedrawWindow(Window, NULL, 0, RDW_NOINTERNALPAINT | RDW_VALIDATE | RDW_NOCHILDREN);*/
if (Window->UpdateRegion != NULL) if (Window->UpdateRegion != NULL)
{ {
MsqDecPaintCountQueue(Window->MessageQueue); MsqDecPaintCountQueue(Window->MessageQueue);
IntValidateParent(Window);
NtGdiDeleteObject(Window->UpdateRegion); NtGdiDeleteObject(Window->UpdateRegion);
Window->UpdateRegion = NULL; Window->UpdateRegion = NULL;
} }
@ -892,7 +912,7 @@ NtUserRedrawWindow(HWND hWnd, CONST RECT *lprcUpdate, HRGN hrgnUpdate,
NTSTATUS Status; NTSTATUS Status;
PWINDOW_OBJECT Wnd; PWINDOW_OBJECT Wnd;
if (!(Wnd = IntGetWindowObject(hWnd))) if (!(Wnd = IntGetWindowObject(hWnd ? hWnd : IntGetDesktopWindow())))
{ {
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE); SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return FALSE; return FALSE;

View file

@ -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.10 2003/11/20 09:18:49 navaraf Exp $ * $Id: vis.c,v 1.11 2003/11/21 17:01:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -301,7 +301,9 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND); RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND);
if (NULLREGION != RgnType && ERROR != RgnType) if (NULLREGION != RgnType && ERROR != RgnType)
{ {
NtGdiOffsetRgn(DirtyRgn, -Sibling->ClientRect.left, -Sibling->ClientRect.top); NtGdiOffsetRgn(DirtyRgn,
Sibling->WindowRect.left - Sibling->ClientRect.left,
Sibling->WindowRect.top - 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);
@ -328,8 +330,9 @@ VIS_WindowLayoutChanged(PDESKTOP_OBJECT Desktop, PWINDOW_OBJECT Window,
RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND); RgnType = NtGdiCombineRgn(DirtyRgn, DirtyRgn, ExposedWindow, RGN_AND);
if (NULLREGION != RgnType && ERROR != RgnType) if (NULLREGION != RgnType && ERROR != RgnType)
{ {
NtGdiOffsetRgn(DirtyRgn, -Parent->ClientRect.left, NtGdiOffsetRgn(DirtyRgn,
-Parent->ClientRect.top); Parent->WindowRect.left - Parent->ClientRect.left,
Parent->WindowRect.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);

View file

@ -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.140 2003/11/20 21:21:29 navaraf Exp $ /* $Id: window.c,v 1.141 2003/11/21 17:01:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1809,7 +1809,7 @@ NtUserDestroyWindow(HWND Wnd)
} }
/* Recursively destroy owned windows */ /* Recursively destroy owned windows */
#if 1 /* FIXME */ #if 0 /* FIXME */
if (! isChild) if (! isChild)
{ {
for (;;) for (;;)

View file

@ -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.44 2003/11/20 21:21:29 navaraf Exp $ /* $Id: winpos.c,v 1.45 2003/11/21 17:01:16 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -745,14 +745,6 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
return FALSE; return FALSE;
} }
if (Window->Flags & WINDOWOBJECT_MAPPING)
{
/* FIXME: SetLastWin32Error */
return FALSE;
}
Window->Flags |= WINDOWOBJECT_MAPPING;
WinPos.hwnd = Wnd; WinPos.hwnd = Wnd;
WinPos.hwndInsertAfter = WndInsertAfter; WinPos.hwndInsertAfter = WndInsertAfter;
WinPos.x = x; WinPos.x = x;
@ -869,7 +861,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN); RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
Window->Style &= ~WS_VISIBLE; Window->Style &= ~WS_VISIBLE;
} }
else else if (WinPos.flags & SWP_SHOWWINDOW)
{ {
Window->Style |= WS_VISIBLE; Window->Style |= WS_VISIBLE;
} }
@ -987,7 +979,7 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
} }
else else
{ {
IntRedrawWindow(Window, NULL, NULL, IntRedrawWindow(Window, NULL, 0,
RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
} }
} }
@ -1025,15 +1017,12 @@ WinPosSetWindowPos(HWND Wnd, HWND WndInsertAfter, INT x, INT y, INT cx,
if (!(WinPos.flags & SWP_NOREDRAW)) if (!(WinPos.flags & SWP_NOREDRAW))
{ {
/* FIXME: Call IntRedrawWindow to erase *all* touched windows. */
IntRedrawWindow(Window, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW); IntRedrawWindow(Window, NULL, 0, RDW_ALLCHILDREN | RDW_ERASENOW);
} }
/* FIXME: Check some conditions before doing this. */ /* FIXME: Check some conditions before doing this. */
IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos); IntSendWINDOWPOSCHANGEDMessage(WinPos.hwnd, &WinPos);
Window->Flags &= ~WINDOWOBJECT_MAPPING;
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
return TRUE; return TRUE;
@ -1055,7 +1044,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
UINT Swp = 0; UINT Swp = 0;
RECT NewPos; RECT NewPos;
BOOLEAN ShowFlag; BOOLEAN ShowFlag;
HRGN VisibleRgn; // HRGN VisibleRgn;
Status = Status =
ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable, ObmReferenceObjectByHandle(PsGetWin32Process()->WindowStation->HandleTable,
@ -1153,6 +1142,44 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
*/ */
} }
#if 1
/* We can't activate a child window */
if ((Window->Style & WS_CHILD) &&
!(Window->ExStyle & WS_EX_MDICHILD))
{
Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
}
WinPosSetWindowPos(Window->Self, HWND_TOP, NewPos.left, NewPos.top,
NewPos.right, NewPos.bottom, LOWORD(Swp));
if (Cmd == SW_HIDE)
{
/* 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 == 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);
}
#else
if (Window->Style & WS_CHILD && if (Window->Style & WS_CHILD &&
!IntIsWindowVisible(Window->Parent->Self) && !IntIsWindowVisible(Window->Parent->Self) &&
(Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE)) (Swp & (SWP_NOSIZE | SWP_NOMOVE)) == (SWP_NOSIZE | SWP_NOMOVE))
@ -1203,6 +1230,7 @@ WinPosShowWindow(HWND Wnd, INT Cmd)
WinPosShowIconTitle(Window, TRUE); WinPosShowIconTitle(Window, TRUE);
} }
} }
#endif
if (Window->Flags & WINDOWOBJECT_NEED_SIZE) if (Window->Flags & WINDOWOBJECT_NEED_SIZE)
{ {