mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +00:00
[Win32SS]
- Implement suspended window support, see CORE-10078. svn path=/trunk/; revision=69633
This commit is contained in:
parent
2d28dcf37d
commit
d86d39947c
7 changed files with 180 additions and 20 deletions
|
@ -1094,7 +1094,7 @@ IntDefWindowProc(
|
||||||
|
|
||||||
case WM_NCCALCSIZE:
|
case WM_NCCALCSIZE:
|
||||||
{
|
{
|
||||||
return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam );
|
return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam, FALSE );
|
||||||
}
|
}
|
||||||
|
|
||||||
case WM_NCACTIVATE:
|
case WM_NCACTIVATE:
|
||||||
|
|
|
@ -1058,6 +1058,13 @@ co_MsqSendMessage(PTHREADINFO ptirec,
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsThreadSuspended(ptirec))
|
||||||
|
{
|
||||||
|
ERR("Sending to Suspended Thread Msg %lx\n",Msg);
|
||||||
|
if (uResult) *uResult = -1;
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
// Should we do the same for No Wait?
|
// Should we do the same for No Wait?
|
||||||
if ( HookMessage == MSQ_NORMAL )
|
if ( HookMessage == MSQ_NORMAL )
|
||||||
{
|
{
|
||||||
|
@ -2037,7 +2044,28 @@ MsqIsHung(PTHREADINFO pti)
|
||||||
LARGE_INTEGER LargeTickCount;
|
LARGE_INTEGER LargeTickCount;
|
||||||
|
|
||||||
KeQueryTickCount(&LargeTickCount);
|
KeQueryTickCount(&LargeTickCount);
|
||||||
return ((LargeTickCount.u.LowPart - pti->timeLast) > MSQ_HUNG);
|
|
||||||
|
if ((LargeTickCount.u.LowPart - pti->timeLast) > MSQ_HUNG &&
|
||||||
|
!(pti->pcti->fsWakeMask & QS_INPUT) &&
|
||||||
|
!PsGetThreadFreezeCount(pti->pEThread) &&
|
||||||
|
!(pti->ppi->W32PF_flags & W32PF_APPSTARTING))
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL FASTCALL
|
||||||
|
IsThreadSuspended(PTHREADINFO pti)
|
||||||
|
{
|
||||||
|
if (pti->pEThread)
|
||||||
|
{
|
||||||
|
BOOL Ret = TRUE;
|
||||||
|
ObReferenceObject(pti->pEThread);
|
||||||
|
if (!(pti->pEThread->Tcb.SuspendCount) && !PsGetThreadFreezeCount(pti->pEThread)) Ret = FALSE;
|
||||||
|
ObDereferenceObject(pti->pEThread);
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
|
|
|
@ -251,6 +251,7 @@ VOID FASTCALL MsqWakeQueue(PTHREADINFO,DWORD,BOOL);
|
||||||
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO,UINT);
|
VOID FASTCALL ClearMsgBitsMask(PTHREADINFO,UINT);
|
||||||
BOOL FASTCALL IntCallMsgFilter(LPMSG,INT);
|
BOOL FASTCALL IntCallMsgFilter(LPMSG,INT);
|
||||||
WPARAM FASTCALL MsqGetDownKeyState(PUSER_MESSAGE_QUEUE);
|
WPARAM FASTCALL MsqGetDownKeyState(PUSER_MESSAGE_QUEUE);
|
||||||
|
BOOL FASTCALL IsThreadSuspended(PTHREADINFO);
|
||||||
|
|
||||||
int UserShowCursor(BOOL bShow);
|
int UserShowCursor(BOOL bShow);
|
||||||
PCURICON_OBJECT
|
PCURICON_OBJECT
|
||||||
|
|
|
@ -477,7 +477,12 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
|
||||||
UserDrawMovingFrame( hdc, &newRect, thickframe );
|
UserDrawMovingFrame( hdc, &newRect, thickframe );
|
||||||
else
|
else
|
||||||
{ // Moving the whole window now!
|
{ // Moving the whole window now!
|
||||||
PWND pwndTemp;
|
HRGN hrgnNew;
|
||||||
|
HRGN hrgnOrig = GreCreateRectRgnIndirect(&pwnd->rcWindow);
|
||||||
|
|
||||||
|
if (pwnd->hrgnClip != NULL)
|
||||||
|
NtGdiCombineRgn(hrgnOrig, hrgnOrig, pwnd->hrgnClip, RGN_AND);
|
||||||
|
|
||||||
//// This causes the mdi child window to jump up when it is moved.
|
//// This causes the mdi child window to jump up when it is moved.
|
||||||
//IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
|
//IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
|
||||||
co_WinPosSetWindowPos( pwnd,
|
co_WinPosSetWindowPos( pwnd,
|
||||||
|
@ -488,18 +493,29 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
|
||||||
newRect.bottom - newRect.top,
|
newRect.bottom - newRect.top,
|
||||||
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
|
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 );
|
||||||
|
|
||||||
// Update all the windows after the move or size, including this window.
|
hrgnNew = GreCreateRectRgnIndirect(&pwnd->rcWindow);
|
||||||
for ( pwndTemp = pwnd->head.rpdesk->pDeskInfo->spwnd->spwndChild;
|
if (pwnd->hrgnClip != NULL)
|
||||||
pwndTemp;
|
NtGdiCombineRgn(hrgnNew, hrgnNew, pwnd->hrgnClip, RGN_AND);
|
||||||
pwndTemp = pwndTemp->spwndNext )
|
|
||||||
|
if (hrgnNew)
|
||||||
{
|
{
|
||||||
RECTL rect;
|
if (hrgnOrig)
|
||||||
// Only the windows that overlap will be redrawn.
|
NtGdiCombineRgn(hrgnOrig, hrgnOrig, hrgnNew, RGN_DIFF);
|
||||||
if (RECTL_bIntersectRect( &rect, &pwnd->rcWindow, &pwndTemp->rcWindow ))
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (hrgnOrig)
|
||||||
{
|
{
|
||||||
co_UserRedrawWindow( pwndTemp, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN);
|
GreDeleteObject(hrgnOrig);
|
||||||
|
hrgnOrig = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update all the windows after the move or size, including this window.
|
||||||
|
UpdateThreadWindows(UserGetDesktopWindow()->spwndChild, pti, hrgnOrig);
|
||||||
|
|
||||||
|
if (hrgnOrig) GreDeleteObject(hrgnOrig);
|
||||||
|
if (hrgnNew) GreDeleteObject(hrgnNew);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sizingRect = newRect;
|
sizingRect = newRect;
|
||||||
|
@ -1163,7 +1179,7 @@ NC_DoNCPaint(PWND pWnd, HDC hDC, INT Flags)
|
||||||
{
|
{
|
||||||
TempRect = CurrentRect;
|
TempRect = CurrentRect;
|
||||||
TempRect.bottom = TempRect.top + menu->cyMenu;
|
TempRect.bottom = TempRect.top + menu->cyMenu;
|
||||||
CurrentRect.top += MENU_DrawMenuBar(hDC, &TempRect, pWnd, FALSE);
|
if (!(Flags & DC_NOSENDMSG)) CurrentRect.top += MENU_DrawMenuBar(hDC, &TempRect, pWnd, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExStyle & WS_EX_CLIENTEDGE)
|
if (ExStyle & WS_EX_CLIENTEDGE)
|
||||||
|
@ -1214,7 +1230,7 @@ NC_DoNCPaint(PWND pWnd, HDC hDC, INT Flags)
|
||||||
return 0; // For WM_NCPAINT message, return 0.
|
return 0; // For WM_NCPAINT message, return 0.
|
||||||
}
|
}
|
||||||
|
|
||||||
LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect )
|
LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect, BOOL Suspended )
|
||||||
{
|
{
|
||||||
LRESULT Result = 0;
|
LRESULT Result = 0;
|
||||||
SIZE WindowBorders;
|
SIZE WindowBorders;
|
||||||
|
@ -1277,7 +1293,7 @@ LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect )
|
||||||
CliRect.right -= OrigRect.left;
|
CliRect.right -= OrigRect.left;
|
||||||
CliRect.left -= OrigRect.left;
|
CliRect.left -= OrigRect.left;
|
||||||
CliRect.top -= OrigRect.top;
|
CliRect.top -= OrigRect.top;
|
||||||
Rect->top += MENU_DrawMenuBar(hDC, &CliRect, Wnd, TRUE);
|
if (!Suspended) Rect->top += MENU_DrawMenuBar(hDC, &CliRect, Wnd, TRUE);
|
||||||
UserReleaseDC(Wnd, hDC, FALSE);
|
UserReleaseDC(Wnd, hDC, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,7 +510,7 @@ co_IntUpdateWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
|
||||||
{
|
{
|
||||||
HWND hWnd = Wnd->head.h;
|
HWND hWnd = Wnd->head.h;
|
||||||
|
|
||||||
if ((Wnd->hrgnUpdate != NULL || Wnd->state & WNDS_INTERNALPAINT))
|
if ( Wnd->hrgnUpdate != NULL || Wnd->state & WNDS_INTERNALPAINT )
|
||||||
{
|
{
|
||||||
if (Wnd->hrgnUpdate)
|
if (Wnd->hrgnUpdate)
|
||||||
{
|
{
|
||||||
|
@ -1004,6 +1004,106 @@ co_UserRedrawWindow(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
PaintSuspendedWindow(PWND pwnd, HRGN hrgnOrig)
|
||||||
|
{
|
||||||
|
if (pwnd->hrgnUpdate)
|
||||||
|
{
|
||||||
|
HDC hDC;
|
||||||
|
INT Flags = DC_NC|DC_NOSENDMSG;
|
||||||
|
HRGN hrgnTemp;
|
||||||
|
RECT Rect;
|
||||||
|
INT type;
|
||||||
|
PREGION prgn;
|
||||||
|
|
||||||
|
if (pwnd->hrgnUpdate > HRGN_WINDOW)
|
||||||
|
{
|
||||||
|
hrgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
|
||||||
|
type = NtGdiCombineRgn( hrgnTemp, pwnd->hrgnUpdate, 0, RGN_COPY);
|
||||||
|
if (type == ERROR)
|
||||||
|
{
|
||||||
|
GreDeleteObject(hrgnTemp);
|
||||||
|
hrgnTemp = HRGN_WINDOW;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hrgnTemp = GreCreateRectRgnIndirect(&pwnd->rcWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( hrgnOrig &&
|
||||||
|
hrgnTemp > HRGN_WINDOW &&
|
||||||
|
NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnOrig, RGN_AND) == NULLREGION)
|
||||||
|
{
|
||||||
|
GreDeleteObject(hrgnTemp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
hDC = UserGetDCEx(pwnd, hrgnTemp, DCX_WINDOW|DCX_INTERSECTRGN|DCX_USESTYLE|DCX_KEEPCLIPRGN);
|
||||||
|
|
||||||
|
Rect = pwnd->rcWindow;
|
||||||
|
RECTL_vOffsetRect(&Rect, -pwnd->rcWindow.left, -pwnd->rcWindow.top);
|
||||||
|
|
||||||
|
// Clear out client area!
|
||||||
|
FillRect(hDC, &Rect, IntGetSysColorBrush(COLOR_WINDOW));
|
||||||
|
|
||||||
|
NC_DoNCPaint(pwnd, hDC, Flags); // Redraw without MENUs.
|
||||||
|
|
||||||
|
UserReleaseDC(pwnd, hDC, FALSE);
|
||||||
|
|
||||||
|
prgn = REGION_LockRgn(hrgnTemp);
|
||||||
|
IntInvalidateWindows(pwnd, prgn, RDW_INVALIDATE | RDW_FRAME | RDW_ERASE | RDW_ALLCHILDREN);
|
||||||
|
REGION_UnlockRgn(prgn);
|
||||||
|
|
||||||
|
// Set updates for this window.
|
||||||
|
pwnd->state |= WNDS_SENDNCPAINT|WNDS_SENDERASEBACKGROUND|WNDS_UPDATEDIRTY;
|
||||||
|
|
||||||
|
// DCX_KEEPCLIPRGN is set. Check it anyway.
|
||||||
|
if (hrgnTemp > HRGN_WINDOW && GreIsHandleValid(hrgnTemp)) GreDeleteObject(hrgnTemp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
UpdateTheadChildren(PWND pWnd, HRGN hRgn)
|
||||||
|
{
|
||||||
|
PaintSuspendedWindow( pWnd, hRgn );
|
||||||
|
|
||||||
|
if (!(pWnd->style & WS_CLIPCHILDREN))
|
||||||
|
return;
|
||||||
|
|
||||||
|
pWnd = pWnd->spwndChild; // invalidate children if any.
|
||||||
|
while (pWnd)
|
||||||
|
{
|
||||||
|
UpdateTheadChildren( pWnd, hRgn );
|
||||||
|
pWnd = pWnd->spwndNext;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID FASTCALL
|
||||||
|
UpdateThreadWindows(PWND pWnd, PTHREADINFO pti, HRGN hRgn)
|
||||||
|
{
|
||||||
|
PWND pwndTemp;
|
||||||
|
|
||||||
|
for ( pwndTemp = pWnd;
|
||||||
|
pwndTemp;
|
||||||
|
pwndTemp = pwndTemp->spwndNext )
|
||||||
|
{
|
||||||
|
if (pwndTemp->head.pti == pti)
|
||||||
|
{
|
||||||
|
UserUpdateWindows(pwndTemp, RDW_ALLCHILDREN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (IsThreadSuspended(pwndTemp->head.pti))
|
||||||
|
{
|
||||||
|
UpdateTheadChildren(pwndTemp, hRgn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
UserUpdateWindows(pwndTemp, RDW_ALLCHILDREN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BOOL FASTCALL
|
BOOL FASTCALL
|
||||||
IntIsWindowDirty(PWND Wnd)
|
IntIsWindowDirty(PWND Wnd)
|
||||||
{
|
{
|
||||||
|
@ -1631,7 +1731,7 @@ co_UserGetUpdateRgn(PWND Window, HRGN hRgn, BOOL bErase)
|
||||||
{
|
{
|
||||||
if (hrgnTemp) GreDeleteObject(hrgnTemp);
|
if (hrgnTemp) GreDeleteObject(hrgnTemp);
|
||||||
NtGdiSetRectRgn(hRgn, 0, 0, 0, 0);
|
NtGdiSetRectRgn(hRgn, 0, 0, 0, 0);
|
||||||
return NULLREGION;
|
return RegionType;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Window != UserGetDesktopWindow()) // Window->fnid == FNID_DESKTOP
|
if (Window != UserGetDesktopWindow()) // Window->fnid == FNID_DESKTOP
|
||||||
|
@ -1684,9 +1784,23 @@ co_UserGetUpdateRect(PWND Window, PRECT pRect, BOOL bErase)
|
||||||
|
|
||||||
if (IntIntersectWithParents(Window, pRect))
|
if (IntIntersectWithParents(Window, pRect))
|
||||||
{
|
{
|
||||||
RECTL_vOffsetRect(pRect,
|
if (Window != UserGetDesktopWindow()) // Window->fnid == FNID_DESKTOP
|
||||||
-Window->rcClient.left,
|
{
|
||||||
-Window->rcClient.top);
|
RECTL_vOffsetRect(pRect,
|
||||||
|
-Window->rcClient.left,
|
||||||
|
-Window->rcClient.top);
|
||||||
|
}
|
||||||
|
if (Window->pcls->style & CS_OWNDC)
|
||||||
|
{
|
||||||
|
HDC hdc;
|
||||||
|
//DWORD layout;
|
||||||
|
hdc = UserGetDCEx(Window, NULL, DCX_USESTYLE);
|
||||||
|
//layout = NtGdiSetLayout(hdc, -1, 0);
|
||||||
|
//IntMapWindowPoints( 0, Window, (LPPOINT)pRect, 2 );
|
||||||
|
GreDPtoLP( hdc, (LPPOINT)pRect, 2 );
|
||||||
|
//NtGdiSetLayout(hdc, -1, layout);
|
||||||
|
UserReleaseDC(Window, hdc, FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,4 +35,5 @@ BOOL FASTCALL IntFlashWindowEx(PWND,PFLASHWINFO);
|
||||||
BOOL FASTCALL IntIntersectWithParents(PWND, RECTL *);
|
BOOL FASTCALL IntIntersectWithParents(PWND, RECTL *);
|
||||||
BOOL FASTCALL IntIsWindowDrawable(PWND);
|
BOOL FASTCALL IntIsWindowDrawable(PWND);
|
||||||
BOOL UserDrawCaption(PWND,HDC,RECTL*,HFONT,HICON,const PUNICODE_STRING,UINT);
|
BOOL UserDrawCaption(PWND,HDC,RECTL*,HFONT,HICON,const PUNICODE_STRING,UINT);
|
||||||
|
VOID FASTCALL UpdateThreadWindows(PWND,PTHREADINFO,HRGN);
|
||||||
|
|
||||||
|
|
|
@ -131,7 +131,7 @@ VOID FASTCALL DefWndDoSizeMove(PWND pwnd, WORD wParam);
|
||||||
LRESULT NC_DoNCPaint(PWND,HDC,INT);
|
LRESULT NC_DoNCPaint(PWND,HDC,INT);
|
||||||
void FASTCALL NC_GetSysPopupPos(PWND, RECT *);
|
void FASTCALL NC_GetSysPopupPos(PWND, RECT *);
|
||||||
LRESULT NC_HandleNCActivate( PWND Wnd, WPARAM wParam, LPARAM lParam );
|
LRESULT NC_HandleNCActivate( PWND Wnd, WPARAM wParam, LPARAM lParam );
|
||||||
LRESULT NC_HandleNCCalcSize( PWND wnd, WPARAM wparam, RECTL *winRect );
|
LRESULT NC_HandleNCCalcSize( PWND wnd, WPARAM wparam, RECTL *winRect, BOOL Suspended );
|
||||||
VOID NC_DrawFrame( HDC hDC, RECT *CurrentRect, BOOL Active, DWORD Style, DWORD ExStyle);
|
VOID NC_DrawFrame( HDC hDC, RECT *CurrentRect, BOOL Active, DWORD Style, DWORD ExStyle);
|
||||||
VOID UserDrawCaptionBar( PWND pWnd, HDC hDC, INT Flags);
|
VOID UserDrawCaptionBar( PWND pWnd, HDC hDC, INT Flags);
|
||||||
void UserGetInsideRectNC(PWND Wnd, RECT *rect);
|
void UserGetInsideRectNC(PWND Wnd, RECT *rect);
|
||||||
|
|
Loading…
Reference in a new issue