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
);
DWORD
INT
STDCALL
NtUserSetWindowRgn(
DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2);
HWND hWnd,
HRGN hRgn,
BOOL bRedraw);
DWORD
STDCALL

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: 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
* FILE: lib/user32/windows/paint.c
@ -191,7 +191,7 @@ RedrawWindow(
/*
* @unimplemented
* @implemented
*/
BOOL STDCALL
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
STDCALL
@ -212,8 +212,7 @@ SetWindowRgn(
HRGN hRgn,
BOOL bRedraw)
{
UNIMPLEMENTED;
return 0;
return (int)NtUserSetWindowRgn(hWnd, hRgn, bRedraw);
}

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.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
* PROJECT: ReactOS kernel
@ -52,17 +52,28 @@ VIS_ComputeVisibleRegion(
if (ClientArea)
{
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
LeftOffset = Window->ClientRect.left;
TopOffset = Window->ClientRect.top;
}
else
{
VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
LeftOffset = Window->WindowRect.left;
TopOffset = Window->WindowRect.top;
if(!(ClipRgn = VIS_ComputeVisibleRegion(Window, FALSE, ClipChildren, ClipSiblings)))
{
return NULL;
}
if(!(VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect)))
{
NtGdiDeleteObject(VisRgn);
return NULL;
}
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
* to the parent's client area and exclude all siblings that are over
@ -92,6 +103,13 @@ VIS_ComputeVisibleRegion(
if (CurrentSibling->Style & WS_VISIBLE)
{
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);
NtGdiDeleteObject(ClipRgn);
}
@ -114,6 +132,13 @@ VIS_ComputeVisibleRegion(
if (CurrentWindow->Style & WS_VISIBLE)
{
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);
NtGdiDeleteObject(ClipRgn);
}
@ -121,9 +146,16 @@ VIS_ComputeVisibleRegion(
}
IntUnLockRelatives(Window);
}
if(Window->WindowRegion)
{
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
return VisRgn;
}
NtGdiOffsetRgn(VisRgn, -LeftOffset, -TopOffset);
return VisRgn;
}

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: 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
* PROJECT: ReactOS kernel
@ -485,6 +485,8 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
if (Dce->hClipRgn && Window->UpdateRegion)
{
NtGdiCombineRgn(Dce->hClipRgn, Window->UpdateRegion, NULL, RGN_COPY);
if(Window->WindowRegion)
NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND);
if (!(Flags & DCX_WINDOW))
{
NtGdiOffsetRgn(Dce->hClipRgn,
@ -500,14 +502,25 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
if (!(Flags & DCX_WINDOW))
{
Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->ClientRect);
NtGdiOffsetRgn(Dce->hClipRgn, -Window->ClientRect.left,
-Window->ClientRect.top);
if(Window->WindowRegion)
{
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
{
Dce->hClipRgn = UnsafeIntCreateRectRgnIndirect(&Window->WindowRect);
NtGdiOffsetRgn(Dce->hClipRgn, -Window->WindowRect.left,
-Window->WindowRect.top);
if(Window->WindowRegion)
NtGdiCombineRgn(Dce->hClipRgn, Dce->hClipRgn, Window->WindowRegion, RGN_AND);
}
}
else if (NULL != ClipRegion)
@ -515,7 +528,10 @@ NtUserGetDCEx(HWND hWnd, HANDLE ClipRegion, ULONG Flags)
Dce->hClipRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
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);
}

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.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
* PROJECT: ReactOS kernel
@ -417,6 +417,11 @@ static LRESULT IntDestroyWindow(PWINDOW_OBJECT Window,
ObmDereferenceObject(Window->Class);
Window->Class = NULL;
if(Window->WindowRegion)
{
NtGdiDeleteObject(Window->WindowRegion);
}
IntReleaseWindowObject(Window);
return 0;
@ -3390,16 +3395,42 @@ NtUserSetWindowPos(
/*
* @unimplemented
* @implemented
*/
DWORD STDCALL
NtUserSetWindowRgn(DWORD Unknown0,
DWORD Unknown1,
DWORD Unknown2)
INT STDCALL
NtUserSetWindowRgn(
HWND hWnd,
HRGN hRgn,
BOOL bRedraw)
{
UNIMPLEMENTED
return 0;
PWINDOW_OBJECT WindowObject;
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
* 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
* PROJECT: ReactOS kernel
@ -1337,8 +1337,10 @@ WinPosSearchChildren(PWINDOW_OBJECT ScopeWin, BOOL SendHitTestMessage, POINT *Po
(Point->x >= Current->WindowRect.left &&
Point->x < Current->WindowRect.right &&
Point->y >= Current->WindowRect.top &&
Point->y < Current->WindowRect.bottom))
/* FIXME - check if Point is in window region */
Point->y < Current->WindowRect.bottom) &&
(!Current->WindowRegion || NtGdiPtInRegion(Current->WindowRegion,
(INT)(Point->x - Current->WindowRect.left), (INT)(Point->y - Current->WindowRect.top)))
)
{
if(*Window)
{

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: 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
#include <windows.h>
#include <ddk/ntddk.h>
@ -2051,10 +2051,10 @@ NtGdiPtInRegion(HRGN hRgn,
{
PROSRGNDATA rgn;
ULONG i;
if( (rgn = RGNDATA_LockRgn(hRgn) ) )
if(!(rgn = RGNDATA_LockRgn(hRgn) ) )
return FALSE;
if(rgn->rdh.nCount > 0 && INRECT(rgn->rdh.rcBound, X, Y)){
for(i = 0; i < rgn->rdh.nCount; i++) {
if(INRECT(*(PRECT)&rgn->Buffer[i], X, Y)){