https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2161dd85dc743462916487...
commit 2161dd85dc743462916487366783389633a5a8f2 Author: jimtabor james.tabor@reactos.org AuthorDate: Mon May 13 11:31:58 2019 -0500 Commit: jimtabor james.tabor@reactos.org CommitDate: Mon May 13 11:31:58 2019 -0500
[NtUser] Fix Paint Messages
This is a HACK for forcing painting of non client areas. Paint code seems very restricted.
See CORE-7166 & CORE-15934. --- win32ss/user/ntuser/winpos.c | 84 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 4 deletions(-)
diff --git a/win32ss/user/ntuser/winpos.c b/win32ss/user/ntuser/winpos.c index 6c54f3c266..0eddff51cc 100644 --- a/win32ss/user/ntuser/winpos.c +++ b/win32ss/user/ntuser/winpos.c @@ -1653,6 +1653,68 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd) return TRUE; }
+// +// This is a NC HACK fix for forcing painting of non client areas. +// Further troubleshooting in painting.c is required to remove this hack. +// See CORE-7166 & CORE-15934 +// +VOID +ForceNCPaintErase(PWND Wnd, HRGN hRgn, PREGION pRgn) +{ + HDC hDC; + PREGION RgnUpdate; + UINT RgnType; + BOOL Create = FALSE; + + if (Wnd->hrgnUpdate == NULL) + { + Wnd->hrgnUpdate = NtGdiCreateRectRgn(0, 0, 0, 0); + IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC); + Create = TRUE; + } + + if (Wnd->hrgnUpdate != HRGN_WINDOW) + { + RgnUpdate = REGION_LockRgn(Wnd->hrgnUpdate); + if (RgnUpdate) + { + RgnType = IntGdiCombineRgn(RgnUpdate, RgnUpdate, pRgn, RGN_OR); + REGION_UnlockRgn(RgnUpdate); + if (RgnType == NULLREGION) + { + IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED); + GreDeleteObject(Wnd->hrgnUpdate); + Wnd->hrgnUpdate = NULL; + Create = FALSE; + } + } + } + + IntSendNCPaint( Wnd, hRgn ); // Region can be deleted by the application. + + if (Wnd->hrgnUpdate) + { + hDC = UserGetDCEx( Wnd, + Wnd->hrgnUpdate, + DCX_CACHE|DCX_USESTYLE|DCX_INTERSECTRGN|DCX_KEEPCLIPRGN); + + Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND); + // Kill the loop, so Clear before we send. + if (!co_IntSendMessage(UserHMGetHandle(Wnd), WM_ERASEBKGND, (WPARAM)hDC, 0)) + { + Wnd->state |= (WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND); + } + UserReleaseDC(Wnd, hDC, FALSE); + } + + if (Create) + { + IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED); + GreDeleteObject(Wnd->hrgnUpdate); + Wnd->hrgnUpdate = NULL; + } +} + /* x and y are always screen relative */ BOOLEAN FASTCALL co_WinPosSetWindowPos( @@ -1862,6 +1924,14 @@ co_WinPosSetWindowPos(
DceResetActiveDCEs(Window); // For WS_VISIBLE changes.
+ // Change or update, set send non-client paint flag. + if ( Window->style & WS_VISIBLE && + (WinPos.flags & SWP_STATECHANGED || (!(Window->state2 & WNDS2_WIN31COMPAT) && WinPos.flags & SWP_NOREDRAW ) ) ) + { + TRACE("Set WNDS_SENDNCPAINT %p\n",Window); + Window->state |= WNDS_SENDNCPAINT; + } + if (!(WinPos.flags & SWP_NOREDRAW)) { /* Determine the new visible region */ @@ -2018,7 +2088,7 @@ co_WinPosSetWindowPos( IntInvalidateWindows( Window, DirtyRgn, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN); } } - else if ( RgnType != ERROR && RgnType == NULLREGION ) // Must be the same. See CORE-7166 & CORE-15934 + else if ( RgnType != ERROR && RgnType == NULLREGION ) // Must be the same. See CORE-7166 & CORE-15934, NC HACK fix. { if ( !PosChanged && !(WinPos.flags & SWP_DEFERERASE) && @@ -2035,7 +2105,13 @@ co_WinPosSetWindowPos(
if ( !(pwnd->style & WS_CHILD) ) { - IntSendNCPaint(pwnd, HRGN_WINDOW); // Paint the whole frame. + HRGN DcRgn = NtGdiCreateRectRgn(0, 0, 0, 0); + PREGION DcRgnObj = REGION_LockRgn(DcRgn); + TRACE("SWP_FRAMECHANGED win %p hRgn %p\n",pwnd, DcRgn); + IntGdiCombineRgn(DcRgnObj, VisBefore, NULL, RGN_COPY); + REGION_UnlockRgn(DcRgnObj); + ForceNCPaintErase(pwnd, DcRgn, DcRgnObj); + GreDeleteObject(DcRgn); } } } @@ -2106,8 +2182,8 @@ co_WinPosSetWindowPos( PWND Parent = Window->spwndParent; if ( !(Window->style & WS_CHILD) && (Parent) && (Parent->style & WS_CLIPCHILDREN)) { - TRACE("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n"); - UserSyncAndPaintWindows( Parent, RDW_CLIPCHILDREN); + TRACE("SWP_FRAMECHANGED Parent %p WS_CLIPCHILDREN %p\n",Parent,Window); + UserSyncAndPaintWindows( Parent, RDW_CLIPCHILDREN); // NC should redraw here, see NC HACK fix. } }