diff --git a/reactos/include/win32k/ntuser.h b/reactos/include/win32k/ntuser.h index b73cef82de3..7b3e224ead9 100644 --- a/reactos/include/win32k/ntuser.h +++ b/reactos/include/win32k/ntuser.h @@ -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 diff --git a/reactos/lib/user32/windows/paint.c b/reactos/lib/user32/windows/paint.c index 31f793a4d8b..207770c7e32 100644 --- a/reactos/lib/user32/windows/paint.c +++ b/reactos/lib/user32/windows/paint.c @@ -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); } diff --git a/reactos/subsys/win32k/ntuser/vis.c b/reactos/subsys/win32k/ntuser/vis.c index cb97fe8f918..4f7b736b4a9 100644 --- a/reactos/subsys/win32k/ntuser/vis.c +++ b/reactos/subsys/win32k/ntuser/vis.c @@ -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; } diff --git a/reactos/subsys/win32k/ntuser/windc.c b/reactos/subsys/win32k/ntuser/windc.c index 684f99796cf..c96812ec591 100644 --- a/reactos/subsys/win32k/ntuser/windc.c +++ b/reactos/subsys/win32k/ntuser/windc.c @@ -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); } diff --git a/reactos/subsys/win32k/ntuser/window.c b/reactos/subsys/win32k/ntuser/window.c index d3a712dcc09..b1033d2d020 100644 --- a/reactos/subsys/win32k/ntuser/window.c +++ b/reactos/subsys/win32k/ntuser/window.c @@ -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; } diff --git a/reactos/subsys/win32k/ntuser/winpos.c b/reactos/subsys/win32k/ntuser/winpos.c index c120edda7f9..31856982a38 100644 --- a/reactos/subsys/win32k/ntuser/winpos.c +++ b/reactos/subsys/win32k/ntuser/winpos.c @@ -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) { diff --git a/reactos/subsys/win32k/objects/region.c b/reactos/subsys/win32k/objects/region.c index 6e3fc35b901..3df445d4eb1 100644 --- a/reactos/subsys/win32k/objects/region.c +++ b/reactos/subsys/win32k/objects/region.c @@ -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 #include @@ -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)){