mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
[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.
This commit is contained in:
parent
0bcf43482b
commit
2161dd85dc
1 changed files with 80 additions and 4 deletions
|
@ -1653,6 +1653,68 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
|
||||||
return TRUE;
|
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 */
|
/* x and y are always screen relative */
|
||||||
BOOLEAN FASTCALL
|
BOOLEAN FASTCALL
|
||||||
co_WinPosSetWindowPos(
|
co_WinPosSetWindowPos(
|
||||||
|
@ -1862,6 +1924,14 @@ co_WinPosSetWindowPos(
|
||||||
|
|
||||||
DceResetActiveDCEs(Window); // For WS_VISIBLE changes.
|
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))
|
if (!(WinPos.flags & SWP_NOREDRAW))
|
||||||
{
|
{
|
||||||
/* Determine the new visible region */
|
/* Determine the new visible region */
|
||||||
|
@ -2018,7 +2088,7 @@ co_WinPosSetWindowPos(
|
||||||
IntInvalidateWindows( Window, DirtyRgn, RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
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 &&
|
if ( !PosChanged &&
|
||||||
!(WinPos.flags & SWP_DEFERERASE) &&
|
!(WinPos.flags & SWP_DEFERERASE) &&
|
||||||
|
@ -2035,7 +2105,13 @@ co_WinPosSetWindowPos(
|
||||||
|
|
||||||
if ( !(pwnd->style & WS_CHILD) )
|
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;
|
PWND Parent = Window->spwndParent;
|
||||||
if ( !(Window->style & WS_CHILD) && (Parent) && (Parent->style & WS_CLIPCHILDREN))
|
if ( !(Window->style & WS_CHILD) && (Parent) && (Parent->style & WS_CLIPCHILDREN))
|
||||||
{
|
{
|
||||||
TRACE("SWP_FRAMECHANGED Parent WS_CLIPCHILDREN\n");
|
TRACE("SWP_FRAMECHANGED Parent %p WS_CLIPCHILDREN %p\n",Parent,Window);
|
||||||
UserSyncAndPaintWindows( Parent, RDW_CLIPCHILDREN);
|
UserSyncAndPaintWindows( Parent, RDW_CLIPCHILDREN); // NC should redraw here, see NC HACK fix.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue