mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +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 )
|
if ( pti->MessageQueue->spwndActive )
|
||||||
{
|
{
|
||||||
pwndPrev = pti->MessageQueue->spwndActive;
|
pwndPrev = pti->MessageQueue->spwndActive;
|
||||||
ptiPrev = pwndPrev->head.pti;
|
ptiPrev = pwndPrev->head.pti;
|
||||||
|
|
||||||
if (!co_IntSendDeactivateMessages(UserHMGetHandle(pwndPrev), 0, TRUE))
|
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.
|
Wnd = pmq->spwndActive; // Use active window from current queue.
|
||||||
|
|
||||||
UserRefObjectCo(Wnd, &Ref);
|
UserRefObjectCo(Wnd, &Ref);
|
||||||
|
|
||||||
co_IntSendMessage( UserHMGetHandle(Wnd), WM_NCACTIVATE, TRUE, 0);
|
co_IntSendMessage( UserHMGetHandle(Wnd), WM_NCACTIVATE, TRUE, 0);
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ co_IntMakeWindowActive(PWND Window)
|
||||||
{
|
{
|
||||||
spwndOwner = spwndOwner->spwndOwner;
|
spwndOwner = spwndOwner->spwndOwner;
|
||||||
}
|
}
|
||||||
spwndOwner->spwndLastActive = Window;
|
WndSetLastActive(spwndOwner, Window);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
ERR("MakeWindowActive Failed!\n");
|
ERR("MakeWindowActive Failed!\n");
|
||||||
|
@ -830,7 +830,7 @@ co_IntSetForegroundMessageQueue(
|
||||||
MsqPostMessage(ptiPrev, &Msg, FALSE, QS_EVENT, POSTEVENT_DAW, (LONG_PTR)tid);
|
MsqPostMessage(ptiPrev, &Msg, FALSE, QS_EVENT, POSTEVENT_DAW, (LONG_PTR)tid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pumqChg = NULL;
|
pumqChg = NULL;
|
||||||
if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) )
|
if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) )
|
||||||
{
|
{
|
||||||
|
|
|
@ -593,8 +593,6 @@ LRESULT co_UserFreeWindow(PWND Window,
|
||||||
Window->style &= ~WS_VISIBLE;
|
Window->style &= ~WS_VISIBLE;
|
||||||
Window->head.pti->cVisWindows--;
|
Window->head.pti->cVisWindows--;
|
||||||
|
|
||||||
WndSetOwner(Window, NULL);
|
|
||||||
|
|
||||||
/* remove the window already at this point from the thread window list so we
|
/* 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
|
don't get into trouble when destroying the thread windows while we're still
|
||||||
in co_UserFreeWindow() */
|
in co_UserFreeWindow() */
|
||||||
|
@ -733,6 +731,12 @@ LRESULT co_UserFreeWindow(PWND Window,
|
||||||
ASSERT(Window->PropListItems==0);
|
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);
|
UserReferenceObject(Window);
|
||||||
UserMarkObjectDestroy(Window);
|
UserMarkObjectDestroy(Window);
|
||||||
|
|
||||||
|
@ -948,27 +952,27 @@ IntLinkWindow(
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Wnd->spwndPrev = WndInsertAfter;
|
WndSetPrev(Wnd, WndInsertAfter);
|
||||||
if (Wnd->spwndPrev)
|
if (Wnd->spwndPrev)
|
||||||
{
|
{
|
||||||
/* Link after WndInsertAfter */
|
/* Link after WndInsertAfter */
|
||||||
ASSERT(Wnd != WndInsertAfter->spwndNext);
|
ASSERT(Wnd != WndInsertAfter->spwndNext);
|
||||||
Wnd->spwndNext = WndInsertAfter->spwndNext;
|
WndSetNext(Wnd, WndInsertAfter->spwndNext);
|
||||||
if (Wnd->spwndNext)
|
if (Wnd->spwndNext)
|
||||||
Wnd->spwndNext->spwndPrev = Wnd;
|
WndSetPrev(Wnd->spwndNext, Wnd);
|
||||||
|
|
||||||
ASSERT(Wnd != Wnd->spwndPrev);
|
ASSERT(Wnd != Wnd->spwndPrev);
|
||||||
Wnd->spwndPrev->spwndNext = Wnd;
|
WndSetNext(Wnd->spwndPrev, Wnd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Link at the top */
|
/* Link at the top */
|
||||||
ASSERT(Wnd != Wnd->spwndParent->spwndChild);
|
ASSERT(Wnd != Wnd->spwndParent->spwndChild);
|
||||||
Wnd->spwndNext = Wnd->spwndParent->spwndChild;
|
WndSetNext(Wnd, Wnd->spwndParent->spwndChild);
|
||||||
if (Wnd->spwndNext)
|
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;
|
Wnd->ExStyle2 &= ~WS_EX2_LINKED;
|
||||||
|
|
||||||
/* Set the new parent */
|
/* Set the new parent */
|
||||||
Wnd->spwndParent = WndNewParent;
|
WndSetParent(Wnd, WndNewParent);
|
||||||
|
|
||||||
if ( Wnd->style & WS_CHILD &&
|
if ( Wnd->style & WS_CHILD &&
|
||||||
Wnd->spwndOwner &&
|
Wnd->spwndOwner &&
|
||||||
|
@ -1352,15 +1356,16 @@ IntUnlinkWindow(PWND Wnd)
|
||||||
ASSERT(Wnd != Wnd->spwndPrev);
|
ASSERT(Wnd != Wnd->spwndPrev);
|
||||||
|
|
||||||
if (Wnd->spwndNext)
|
if (Wnd->spwndNext)
|
||||||
Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
|
WndSetPrev(Wnd->spwndNext, Wnd->spwndPrev);
|
||||||
|
|
||||||
if (Wnd->spwndPrev)
|
if (Wnd->spwndPrev)
|
||||||
Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
|
WndSetNext(Wnd->spwndPrev, Wnd->spwndNext);
|
||||||
|
|
||||||
if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
|
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
|
// Win: ExpandWindowList
|
||||||
|
@ -1876,10 +1881,10 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
|
||||||
* Fill out the structure describing it.
|
* Fill out the structure describing it.
|
||||||
*/
|
*/
|
||||||
/* Remember, pWnd->head is setup in object.c ... */
|
/* Remember, pWnd->head is setup in object.c ... */
|
||||||
pWnd->spwndParent = ParentWindow;
|
WndSetParent(pWnd, ParentWindow);
|
||||||
WndSetOwner(pWnd, OwnerWindow);
|
WndSetOwner(pWnd, OwnerWindow);
|
||||||
pWnd->fnid = 0;
|
pWnd->fnid = 0;
|
||||||
pWnd->spwndLastActive = pWnd;
|
WndSetLastActive(pWnd, pWnd);
|
||||||
// Ramp up compatible version sets.
|
// Ramp up compatible version sets.
|
||||||
if ( dwVer >= WINVER_WIN31 )
|
if ( dwVer >= WINVER_WIN31 )
|
||||||
{
|
{
|
||||||
|
@ -2932,7 +2937,7 @@ BOOLEAN co_UserDestroyWindow(PVOID Object)
|
||||||
pwndTemp = pwndTemp->spwndOwner;
|
pwndTemp = pwndTemp->spwndOwner;
|
||||||
|
|
||||||
if (pwndTemp->spwndLastActive == Window)
|
if (pwndTemp->spwndLastActive == Window)
|
||||||
pwndTemp->spwndLastActive = Window->spwndOwner;
|
WndSetLastActive(pwndTemp, Window->spwndOwner);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Window->spwndParent && IntIsWindow(UserHMGetHandle(Window)))
|
if (Window->spwndParent && IntIsWindow(UserHMGetHandle(Window)))
|
||||||
|
|
|
@ -125,23 +125,66 @@ BOOL FASTCALL IntBroadcastImeShowStatusChange(PWND pImeWnd, BOOL bShow);
|
||||||
VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd);
|
VOID FASTCALL IntNotifyImeShowStatus(PWND pImeWnd);
|
||||||
VOID FASTCALL IntCheckImeShowStatusInThread(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
|
static inline
|
||||||
VOID
|
VOID
|
||||||
WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner)
|
WndSetOwner(_Inout_ PWND pwnd, _In_opt_ PWND pwndOwner)
|
||||||
{
|
{
|
||||||
/* First reference the new owner window */
|
ReplaceWndPtr(&pwnd->spwndOwner, pwndOwner);
|
||||||
if (pwndOwner != NULL)
|
}
|
||||||
{
|
|
||||||
UserReferenceObject(pwndOwner);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now dereference the previous owner window */
|
static inline
|
||||||
if (pwnd->spwndOwner != NULL)
|
VOID
|
||||||
{
|
WndSetParent(_Inout_ PWND pwnd, _In_opt_ PWND pwndParent)
|
||||||
UserDereferenceObject(pwnd->spwndOwner);
|
{
|
||||||
}
|
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 */
|
/* EOF */
|
||||||
|
|
Loading…
Reference in a new issue