Implemented SetWindowRgn() and added support for window regions

svn path=/trunk/; revision=8848
This commit is contained in:
Thomas Bluemel 2004-03-23 16:32:20 +00:00
parent 93f83462c0
commit e207cba272
7 changed files with 121 additions and 41 deletions

View file

@ -1425,12 +1425,12 @@ STDCALL NtUserSetWindowPos(
UINT uFlags UINT uFlags
); );
DWORD INT
STDCALL STDCALL
NtUserSetWindowRgn( NtUserSetWindowRgn(
DWORD Unknown0, HWND hWnd,
DWORD Unknown1, HRGN hRgn,
DWORD Unknown2); BOOL bRedraw);
DWORD DWORD
STDCALL STDCALL

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: paint.c,v 1.23 2004/03/23 11:20:58 gvg Exp $ /* $Id: paint.c,v 1.24 2004/03/23 16:32:20 weiden Exp $
* *
* PROJECT: ReactOS user32.dll * PROJECT: ReactOS user32.dll
* FILE: lib/user32/windows/paint.c * FILE: lib/user32/windows/paint.c
@ -191,7 +191,7 @@ RedrawWindow(
/* /*
* @unimplemented * @implemented
*/ */
BOOL STDCALL BOOL STDCALL
ScrollDC(HDC hDC, int dx, int dy, CONST RECT *lprcScroll, CONST RECT *lprcClip, ScrollDC(HDC hDC, int dx, int dy, CONST RECT *lprcScroll, CONST RECT *lprcClip,
@ -203,7 +203,7 @@ ScrollDC(HDC hDC, int dx, int dy, CONST RECT *lprcScroll, CONST RECT *lprcClip,
/* /*
* @unimplemented * @implemented
*/ */
int int
STDCALL STDCALL
@ -212,8 +212,7 @@ SetWindowRgn(
HRGN hRgn, HRGN hRgn,
BOOL bRedraw) BOOL bRedraw)
{ {
UNIMPLEMENTED; return (int)NtUserSetWindowRgn(hWnd, hRgn, bRedraw);
return 0;
} }

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.23 2004/03/14 20:31:55 gvg Exp $ * $Id: vis.c,v 1.24 2004/03/23 16:32:20 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -52,17 +52,28 @@ VIS_ComputeVisibleRegion(
if (ClientArea) if (ClientArea)
{ {
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); if(!(ClipRgn = VIS_ComputeVisibleRegion(Window, FALSE, ClipChildren, ClipSiblings)))
LeftOffset = Window->ClientRect.left; {
TopOffset = Window->ClientRect.top; return NULL;
} }
else if(!(VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect)))
{ {
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); NtGdiDeleteObject(VisRgn);
LeftOffset = Window->WindowRect.left; return NULL;
TopOffset = Window->WindowRect.top; }
LeftOffset = Window->ClientRect.left - Window->WindowRect.left;
TopOffset = Window->ClientRect.top - Window->WindowRect.top;
NtGdiOffsetRgn(VisRgn, -Window->WindowRect.left, -Window->WindowRect.top);
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_AND);
NtGdiDeleteObject(ClipRgn);
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
return VisRgn;
} }
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
LeftOffset = Window->WindowRect.left;
TopOffset = Window->WindowRect.top;
/* /*
* Walk through all perent windows and for each clip the visble region * Walk through all perent windows and for each clip the visble region
* to the parent's client area and exclude all siblings that are over * to the parent's client area and exclude all siblings that are over
@ -92,6 +103,13 @@ VIS_ComputeVisibleRegion(
if (CurrentSibling->Style & WS_VISIBLE) if (CurrentSibling->Style & WS_VISIBLE)
{ {
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentSibling->WindowRect); ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentSibling->WindowRect);
/* Combine it with the window region if available */
if(CurrentSibling->WindowRegion)
{
NtGdiOffsetRgn(ClipRgn, -CurrentSibling->WindowRect.left, -CurrentSibling->WindowRect.top);
NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentSibling->WindowRegion, RGN_AND);
NtGdiOffsetRgn(ClipRgn, CurrentSibling->WindowRect.left, CurrentSibling->WindowRect.top);
}
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
NtGdiDeleteObject(ClipRgn); NtGdiDeleteObject(ClipRgn);
} }
@ -114,6 +132,13 @@ VIS_ComputeVisibleRegion(
if (CurrentWindow->Style & WS_VISIBLE) if (CurrentWindow->Style & WS_VISIBLE)
{ {
ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->WindowRect); ClipRgn = UnsafeIntCreateRectRgnIndirect(&CurrentWindow->WindowRect);
/* Combine it with the window region if available */
if(CurrentWindow->WindowRegion)
{
NtGdiOffsetRgn(ClipRgn, -CurrentWindow->WindowRect.left, -CurrentWindow->WindowRect.top);
NtGdiCombineRgn(ClipRgn, ClipRgn, CurrentWindow->WindowRegion, RGN_AND);
NtGdiOffsetRgn(ClipRgn, CurrentWindow->WindowRect.left, CurrentWindow->WindowRect.top);
}
NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF); NtGdiCombineRgn(VisRgn, VisRgn, ClipRgn, RGN_DIFF);
NtGdiDeleteObject(ClipRgn); NtGdiDeleteObject(ClipRgn);
} }
@ -121,9 +146,16 @@ VIS_ComputeVisibleRegion(
} }
IntUnLockRelatives(Window); IntUnLockRelatives(Window);
} }
if(Window->WindowRegion)
{
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
return VisRgn;
}
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset); NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
return VisRgn; return VisRgn;
} }

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: windc.c,v 1.59 2004/02/24 01:30:57 weiden Exp $ /* $Id: windc.c,v 1.60 2004/03/23 16:32:20 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -485,6 +485,8 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
if (Dce->hClipRgn && Window->UpdateRegion) if (Dce->hClipRgn && Window->UpdateRegion)
{ {
NtGdiCombineRgn(Dce->hClipRgn, Window->UpdateRegion, NULL, RGN_COPY); NtGdiCombineRgn(Dce->hClipRgn, Window->UpdateRegion, NULL, RGN_COPY);
if(Window->WindowRegion)
NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND);
if (!(Flags & DCX_WINDOW)) if (!(Flags & DCX_WINDOW))
{ {
NtGdiOffsetRgn(Dce->hClipRgn, NtGdiOffsetRgn(Dce->hClipRgn,
@ -500,14 +502,25 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
if (!(Flags & DCX_WINDOW)) if (!(Flags & DCX_WINDOW))
{ {
Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect); Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
NtGdiOffsetRgn(Dce->hClipRgn, -Window->ClientRect.left, if(Window->WindowRegion)
-Window->ClientRect.top); {
NtGdiOffsetRgn(Dce->hClipRgn, -Window->WindowRect.left, -Window->WindowRect.top);
NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND);
NtGdiOffsetRgn(Dce->hClipRgn, -(Window->ClientRect.left - Window->WindowRect.left),
-(Window->ClientRect.top - Window->WindowRect.top));
}
else
{
NtGdiOffsetRgn(Dce->hClipRgn, -Window->ClientRect.left, -Window->ClientRect.top);
}
} }
else else
{ {
Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect); Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
NtGdiOffsetRgn(Dce->hClipRgn, -Window->WindowRect.left, NtGdiOffsetRgn(Dce->hClipRgn, -Window->WindowRect.left,
-Window->WindowRect.top); -Window->WindowRect.top);
if(Window->WindowRegion)
NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND);
} }
} }
else if (NULL != ClipRegion) else if (NULL != ClipRegion)
@ -515,7 +528,10 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0); Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
if (Dce->hClipRgn) if (Dce->hClipRgn)
{ {
NtGdiCombineRgn(Dce->hClipRgn, ClipRegion, NULL, RGN_COPY); if(Window->WindowRegion)
NtGdiCombineRgn(Dce->hClipRgn, ClipRegion, Window->WindowRegion, RGN_AND);
else
NtGdiCombineRgn(Dce->hClipRgn, ClipRegion, NULL, RGN_COPY);
} }
NtGdiDeleteObject(ClipRegion); NtGdiDeleteObject(ClipRegion);
} }

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.199 2004/03/13 23:12:19 gvg Exp $ /* $Id: window.c,v 1.200 2004/03/23 16:32:20 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -417,6 +417,11 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
ObmDereferenceObject(Window->Class); ObmDereferenceObject(Window->Class);
Window->Class = NULL; Window->Class = NULL;
if(Window->WindowRegion)
{
NtGdiDeleteObject(Window->WindowRegion);
}
IntReleaseWindowObject(Window); IntReleaseWindowObject(Window);
return 0; return 0;
@ -3390,16 +3395,42 @@ NtUserSetWindowPos(
/* /*
* @unimplemented * @implemented
*/ */
DWORD STDCALL INT STDCALL
NtUserSetWindowRgn(DWORD Unknown0, NtUserSetWindowRgn(
DWORD Unknown1, HWND hWnd,
DWORD Unknown2) HRGN hRgn,
BOOL bRedraw)
{ {
UNIMPLEMENTED PWINDOW_OBJECT WindowObject;
return 0; WindowObject = IntGetWindowObject(hWnd);
if (WindowObject == NULL)
{
SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
return 0;
}
/* FIXME - Verify if hRgn is a valid handle!!!!
Propably make this operation thread-safe, but maybe it's not necessary */
if(WindowObject->WindowRegion)
{
/* Delete no longer needed region handle */
NtGdiDeleteObject(WindowObject->WindowRegion);
}
WindowObject->WindowRegion = hRgn;
/* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
if(bRedraw)
{
IntRedrawWindow(WindowObject, NULL, NULL, RDW_INVALIDATE);
}
IntReleaseWindowObject(WindowObject);
return (INT)hRgn;
} }

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.102 2004/03/22 20:14:29 weiden Exp $ /* $Id: winpos.c,v 1.103 2004/03/23 16:32:20 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -1337,8 +1337,10 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, BOOL SendHitTestMessage, POINT *Po
(Point->x >= Current->WindowRect.left && (Point->x >= Current->WindowRect.left &&
Point->x < Current->WindowRect.right && Point->x < Current->WindowRect.right &&
Point->y >= Current->WindowRect.top && Point->y >= Current->WindowRect.top &&
Point->y < Current->WindowRect.bottom)) Point->y < Current->WindowRect.bottom) &&
/* FIXME - check if Point is in window region */ (!Current->WindowRegion || NtGdiPtInRegion(Current->WindowRegion,
(INT)(Point->x - Current->WindowRect.left), (INT)(Point->y - Current->WindowRect.top)))
)
{ {
if(*Window) if(*Window)
{ {

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: region.c,v 1.43 2004/03/22 20:14:29 weiden Exp $ */ /* $Id: region.c,v 1.44 2004/03/23 16:32:20 weiden Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
#include <windows.h> #include <windows.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
@ -2051,10 +2051,10 @@ NtGdiPtInRegion(HRGN hRgn,
{ {
PROSRGNDATA rgn; PROSRGNDATA rgn;
ULONG i; ULONG i;
if( (rgn = RGNDATA_LockRgn(hRgn) ) ) if(!(rgn = RGNDATA_LockRgn(hRgn) ) )
return FALSE; return FALSE;
if(rgn->rdh.nCount > 0 && INRECT(rgn->rdh.rcBound, X, Y)){ if(rgn->rdh.nCount > 0 && INRECT(rgn->rdh.rcBound, X, Y)){
for(i = 0; i < rgn->rdh.nCount; i++) { for(i = 0; i < rgn->rdh.nCount; i++) {
if(INRECT(*(PRECT)&rgn->Buffer[i], X, Y)){ if(INRECT(*(PRECT)&rgn->Buffer[i], X, Y)){