mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[NTUSER] Always reference a window when using it as parent/child etc.
CORE-18811
This commit is contained in:
parent
b3d0591e76
commit
1599d7b794
3 changed files with 80 additions and 32 deletions
|
@ -242,7 +242,7 @@ IntDeactivateWindow(PTHREADINFO pti, HANDLE tid)
|
|||
if ( pti->MessageQueue->spwndActive )
|
||||
{
|
||||
pwndPrev = pti->MessageQueue->spwndActive;
|
||||
ptiPrev = pwndPrev->head.pti;
|
||||
ptiPrev = pwndPrev->head.pti;
|
||||
|
||||
if (!co_IntSendDeactivateMessages(UserHMGetHandle(pwndPrev), 0, TRUE))
|
||||
{
|
||||
|
@ -403,7 +403,7 @@ IntActivateWindow(PWND Wnd, PTHREADINFO pti, HANDLE tid, DWORD Type)
|
|||
{
|
||||
Wnd = pmq->spwndActive; // Use active window from current queue.
|
||||
|
||||
UserRefObjectCo(Wnd, &Ref);
|
||||
UserRefObjectCo(Wnd, &Ref);
|
||||
|
||||
co_IntSendMessage( UserHMGetHandle(Wnd), WM_NCACTIVATE, TRUE, 0);
|
||||
|
||||
|
@ -433,7 +433,7 @@ co_IntMakeWindowActive(PWND Window)
|
|||
{
|
||||
spwndOwner = spwndOwner->spwndOwner;
|
||||
}
|
||||
spwndOwner->spwndLastActive = Window;
|
||||
WndSetLastActive(spwndOwner, Window);
|
||||
return TRUE;
|
||||
}
|
||||
ERR("MakeWindowActive Failed!\n");
|
||||
|
@ -830,7 +830,7 @@ co_IntSetForegroundMessageQueue(
|
|||
MsqPostMessage(ptiPrev, &Msg, FALSE, QS_EVENT, POSTEVENT_DAW, (LONG_PTR)tid);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pumqChg = NULL;
|
||||
if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) )
|
||||
{
|
||||
|
|
|
@ -593,8 +593,6 @@ LRESULT co_UserFreeWindow(PWND Window,
|
|||
Window->style &= ~WS_VISIBLE;
|
||||
Window->head.pti->cVisWindows--;
|
||||
|
||||
WndSetOwner(Window, NULL);
|
||||
|
||||
/* remove the window already at this point from the thread window list so we
|
||||
don't get into trouble when destroying the thread windows while we're still
|
||||
in co_UserFreeWindow() */
|
||||
|
@ -733,6 +731,12 @@ LRESULT co_UserFreeWindow(PWND Window,
|
|||
ASSERT(Window->PropListItems==0);
|
||||
}
|
||||
|
||||
/* Kill any reference to linked windows. Prev & Next are taken care of in IntUnlinkWindow */
|
||||
WndSetOwner(Window, NULL);
|
||||
WndSetParent(Window, NULL);
|
||||
WndSetChild(Window, NULL);
|
||||
WndSetLastActive(Window, NULL);
|
||||
|
||||
UserReferenceObject(Window);
|
||||
UserMarkObjectDestroy(Window);
|
||||
|
||||
|
@ -948,27 +952,27 @@ IntLinkWindow(
|
|||
return;
|
||||
}
|
||||
|
||||
Wnd->spwndPrev = WndInsertAfter;
|
||||
WndSetPrev(Wnd, WndInsertAfter);
|
||||
if (Wnd->spwndPrev)
|
||||
{
|
||||
/* Link after WndInsertAfter */
|
||||
ASSERT(Wnd != WndInsertAfter->spwndNext);
|
||||
Wnd->spwndNext = WndInsertAfter->spwndNext;
|
||||
WndSetNext(Wnd, WndInsertAfter->spwndNext);
|
||||
if (Wnd->spwndNext)
|
||||
Wnd->spwndNext->spwndPrev = Wnd;
|
||||
WndSetPrev(Wnd->spwndNext, Wnd);
|
||||
|
||||
ASSERT(Wnd != Wnd->spwndPrev);
|
||||
Wnd->spwndPrev->spwndNext = Wnd;
|
||||
WndSetNext(Wnd->spwndPrev, Wnd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Link at the top */
|
||||
ASSERT(Wnd != Wnd->spwndParent->spwndChild);
|
||||
Wnd->spwndNext = Wnd->spwndParent->spwndChild;
|
||||
WndSetNext(Wnd, Wnd->spwndParent->spwndChild);
|
||||
if (Wnd->spwndNext)
|
||||
Wnd->spwndNext->spwndPrev = Wnd;
|
||||
WndSetPrev(Wnd->spwndNext, Wnd);
|
||||
|
||||
Wnd->spwndParent->spwndChild = Wnd;
|
||||
WndSetChild(Wnd->spwndParent, Wnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1224,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
|
|||
Wnd->ExStyle2 &= ~WS_EX2_LINKED;
|
||||
|
||||
/* Set the new parent */
|
||||
Wnd->spwndParent = WndNewParent;
|
||||
WndSetParent(Wnd, WndNewParent);
|
||||
|
||||
if ( Wnd->style & WS_CHILD &&
|
||||
Wnd->spwndOwner &&
|
||||
|
@ -1352,15 +1356,16 @@ IntUnlinkWindow(PWND Wnd)
|
|||
ASSERT(Wnd != Wnd->spwndPrev);
|
||||
|
||||
if (Wnd->spwndNext)
|
||||
Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
|
||||
WndSetPrev(Wnd->spwndNext, Wnd->spwndPrev);
|
||||
|
||||
if (Wnd->spwndPrev)
|
||||
Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
|
||||
WndSetNext(Wnd->spwndPrev, Wnd->spwndNext);
|
||||
|
||||
if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
|
||||
Wnd->spwndParent->spwndChild = Wnd->spwndNext;
|
||||
WndSetChild(Wnd->spwndParent, Wnd->spwndNext);
|
||||
|
||||
Wnd->spwndPrev = Wnd->spwndNext = NULL;
|
||||
WndSetPrev(Wnd, NULL);
|
||||
WndSetNext(Wnd, NULL);
|
||||
}
|
||||
|
||||
// Win: ExpandWindowList
|
||||
|
@ -1876,10 +1881,10 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
|
|||
* Fill out the structure describing it.
|
||||
*/
|
||||
/* Remember, pWnd->head is setup in object.c ... */
|
||||
pWnd->spwndParent = ParentWindow;
|
||||
WndSetParent(pWnd, ParentWindow);
|
||||
WndSetOwner(pWnd, OwnerWindow);
|
||||
pWnd->fnid = 0;
|
||||
pWnd->spwndLastActive = pWnd;
|
||||
WndSetLastActive(pWnd, pWnd);
|
||||
// Ramp up compatible version sets.
|
||||
if ( dwVer >= WINVER_WIN31 )
|
||||
{
|
||||
|
@ -2932,7 +2937,7 @@ BOOLEAN co_UserDestroyWindow(PVOID Object)
|
|||
pwndTemp = pwndTemp->spwndOwner;
|
||||
|
||||
if (pwndTemp->spwndLastActive == Window)
|
||||
pwndTemp->spwndLastActive = Window->spwndOwner;
|
||||
WndSetLastActive(pwndTemp, Window->spwndOwner);
|
||||
}
|
||||
|
||||
if (Window->spwndParent && IntIsWindow(UserHMGetHandle(Window)))
|
||||
|
|
|
@ -125,23 +125,66 @@ BOOL FASTCALL IntBroadcastImeShowStatusChange(PWND pImeWnd, BOOL bShow);
|
|||
VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd);
|
||||
VOID FASTCALL IntCheckImeShowStatusInThread(PWND pImeWnd);
|
||||
|
||||
static inline
|
||||
VOID
|
||||
ReplaceWndPtr(_Inout_ PWND* ppwnd, _In_opt_ PWND pwndNew)
|
||||
{
|
||||
/* First reference the new one */
|
||||
if (pwndNew != NULL)
|
||||
{
|
||||
UserReferenceObject(pwndNew);
|
||||
}
|
||||
|
||||
/* Then dereference the previous one */
|
||||
if (*ppwnd != NULL)
|
||||
{
|
||||
UserDereferenceObject(*ppwnd);
|
||||
}
|
||||
|
||||
/* And set */
|
||||
*ppwnd = pwndNew;
|
||||
}
|
||||
|
||||
static inline
|
||||
VOID
|
||||
WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner)
|
||||
{
|
||||
/* First reference the new owner window */
|
||||
if (pwndOwner != NULL)
|
||||
{
|
||||
UserReferenceObject(pwndOwner);
|
||||
}
|
||||
ReplaceWndPtr(&pwnd->spwndOwner, pwndOwner);
|
||||
}
|
||||
|
||||
/* Now dereference the previous owner window */
|
||||
if (pwnd->spwndOwner != NULL)
|
||||
{
|
||||
UserDereferenceObject(pwnd->spwndOwner);
|
||||
}
|
||||
static inline
|
||||
VOID
|
||||
WndSetParent(_Inout_ PWND pwnd, _In_opt_ PWND pwndParent)
|
||||
{
|
||||
ReplaceWndPtr(&pwnd->spwndParent, pwndParent);
|
||||
}
|
||||
|
||||
pwnd->spwndOwner = pwndOwner;
|
||||
static inline
|
||||
VOID
|
||||
WndSetChild(_Inout_ PWND pwnd, _In_opt_ PWND pwndChild)
|
||||
{
|
||||
ReplaceWndPtr(&pwnd->spwndChild, pwndChild);
|
||||
}
|
||||
|
||||
static inline
|
||||
VOID
|
||||
WndSetNext(_Inout_ PWND pwnd, _In_opt_ PWND pwndNext)
|
||||
{
|
||||
ReplaceWndPtr(&pwnd->spwndNext, pwndNext);
|
||||
}
|
||||
|
||||
static inline
|
||||
VOID
|
||||
WndSetPrev(_Inout_ PWND pwnd, _In_opt_ PWND pwndPrev)
|
||||
{
|
||||
ReplaceWndPtr(&pwnd->spwndPrev, pwndPrev);
|
||||
}
|
||||
|
||||
static inline
|
||||
VOID
|
||||
WndSetLastActive(_Inout_ PWND pwnd, _In_opt_ PWND pwndLastActive)
|
||||
{
|
||||
ReplaceWndPtr(&pwnd->spwndLastActive, pwndLastActive);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue