mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 10:01:43 +00:00
[NtUser]
- Fix bug 6751, 7228 and others, Validate link windows, not relink them per say. - Stop spurious window handle errors. This fixes all of the DeferWinPos handle errors. svn path=/trunk/; revision=57068
This commit is contained in:
parent
59de552e2a
commit
02f891a26d
5 changed files with 122 additions and 18 deletions
|
@ -203,6 +203,20 @@ HANDLE UserAllocHandle(PUSER_HANDLE_TABLE ht, PVOID object, USER_OBJECT_TYPE typ
|
|||
return entry_to_handle(ht, entry );
|
||||
}
|
||||
|
||||
/* return a pointer to a user object from its handle without setting an error */
|
||||
PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type )
|
||||
{
|
||||
PUSER_HANDLE_ENTRY entry;
|
||||
|
||||
ASSERT(ht);
|
||||
|
||||
if (!(entry = handle_to_entry(ht, handle )) || entry->type != type)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return entry->ptr;
|
||||
}
|
||||
|
||||
/* return a pointer to a user object from its handle */
|
||||
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type )
|
||||
{
|
||||
|
|
|
@ -36,6 +36,7 @@ BOOL FASTCALL UserDereferenceObject(PVOID obj);
|
|||
PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, struct _DESKTOP* pDesktop, HANDLE* h,USER_OBJECT_TYPE type , ULONG size);
|
||||
BOOL FASTCALL UserDeleteObject(HANDLE h, USER_OBJECT_TYPE type );
|
||||
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type );
|
||||
PVOID UserGetObjectNoErr(PUSER_HANDLE_TABLE, HANDLE, USER_OBJECT_TYPE);
|
||||
BOOL FASTCALL UserCreateHandleTable(VOID);
|
||||
BOOL FASTCALL UserObjectInDestroy(HANDLE);
|
||||
|
||||
|
|
|
@ -86,6 +86,12 @@ PWND FASTCALL VerifyWnd(PWND pWnd)
|
|||
return pWnd;
|
||||
}
|
||||
|
||||
PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
|
||||
{
|
||||
if (hWnd) return (PWND)UserGetObjectNoErr(gHandleTable, hWnd, otWindow);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Temp HACK */
|
||||
PWND FASTCALL UserGetWindowObject(HWND hWnd)
|
||||
{
|
||||
|
|
|
@ -34,7 +34,7 @@ extern ATOM AtomFlashWndState;
|
|||
#define IntGetWndProcessId(WndObj) \
|
||||
PsGetProcessId(WndObj->head.pti->ppi->peProcess)
|
||||
|
||||
|
||||
PWND FASTCALL ValidateHwndNoErr(HWND);
|
||||
BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam);
|
||||
BOOL FASTCALL IntIsWindow(HWND hWnd);
|
||||
HWND* FASTCALL IntWinListChildren(PWND Window);
|
||||
|
|
|
@ -28,12 +28,14 @@ DBG_DEFAULT_CHANNEL(UserWinpos);
|
|||
#define PLACE_MAX 0x0002
|
||||
#define PLACE_RECT 0x0004
|
||||
|
||||
VOID FASTCALL IntLinkWindow(PWND Wnd,PWND WndInsertAfter);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOL FASTCALL
|
||||
IntGetClientOrigin(PWND Window OPTIONAL, LPPOINT Point)
|
||||
{
|
||||
Window = Window ? Window : UserGetWindowObject(IntGetDesktopWindow());
|
||||
Window = Window ? Window : UserGetDesktopWindow();
|
||||
if (Window == NULL)
|
||||
{
|
||||
Point->x = Point->y = 0;
|
||||
|
@ -1091,6 +1093,10 @@ co_WinPosDoWinPosChanging(PWND Window,
|
|||
/*
|
||||
* Fix Z order taking into account owned popups -
|
||||
* basically we need to maintain them above the window that owns them
|
||||
*
|
||||
* FIXME: hide/show owned popups when owner visibility changes.
|
||||
*
|
||||
* ReactOS: See bug 6751 and 7228.
|
||||
*/
|
||||
static
|
||||
HWND FASTCALL
|
||||
|
@ -1123,7 +1129,7 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
|
|||
break;
|
||||
if (HWND_TOP == hWndInsertAfter)
|
||||
{
|
||||
ChildObject = UserGetWindowObject(List[i]);
|
||||
ChildObject = ValidateHwndNoErr(List[i]);
|
||||
if (NULL != ChildObject)
|
||||
{
|
||||
if (0 == (ChildObject->ExStyle & WS_EX_TOPMOST))
|
||||
|
@ -1148,7 +1154,7 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
|
|||
|
||||
if (!List)
|
||||
{
|
||||
DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
|
||||
DesktopWindow = UserGetDesktopWindow();
|
||||
List = IntWinListChildren(DesktopWindow);
|
||||
}
|
||||
if (List != NULL)
|
||||
|
@ -1160,7 +1166,7 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
|
|||
if (List[i] == Window->head.h)
|
||||
break;
|
||||
|
||||
if (!(Wnd = UserGetWindowObject(List[i])))
|
||||
if (!(Wnd = ValidateHwndNoErr(List[i])))
|
||||
continue;
|
||||
|
||||
if (Wnd->style & WS_POPUP && Wnd->spwndOwner == Window)
|
||||
|
@ -1169,7 +1175,7 @@ WinPosDoOwnedPopups(PWND Window, HWND hWndInsertAfter)
|
|||
UserRefObjectCo(Wnd, &Ref);
|
||||
|
||||
co_WinPosSetWindowPos(Wnd, hWndInsertAfter, 0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING);
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_NOSENDCHANGING| SWP_DEFERERASE);
|
||||
|
||||
UserDerefObjectCo(Wnd);
|
||||
|
||||
|
@ -1281,6 +1287,9 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
|
|||
|
||||
if (WinPos->hwndInsertAfter == HWND_NOTOPMOST)
|
||||
{
|
||||
if (!(Wnd->ExStyle & WS_EX_TOPMOST))
|
||||
WinPos->flags |= SWP_NOZORDER;
|
||||
|
||||
WinPos->hwndInsertAfter = HWND_TOP;
|
||||
}
|
||||
else if (HWND_TOP == WinPos->hwndInsertAfter
|
||||
|
@ -1298,7 +1307,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
|
|||
{
|
||||
PWND InsAfterWnd;
|
||||
|
||||
InsAfterWnd = UserGetWindowObject(WinPos->hwndInsertAfter);
|
||||
InsAfterWnd = ValidateHwndNoErr(WinPos->hwndInsertAfter);
|
||||
if(!InsAfterWnd)
|
||||
{
|
||||
return TRUE;
|
||||
|
@ -1361,6 +1370,7 @@ co_WinPosSetWindowPos(
|
|||
RECTL CopyRect;
|
||||
PWND Ancestor;
|
||||
BOOL bPointerInWindow;
|
||||
BOOL bNoTopMost;
|
||||
|
||||
ASSERT_REFS_CO(Window);
|
||||
|
||||
|
@ -1388,9 +1398,13 @@ co_WinPosSetWindowPos(
|
|||
|
||||
co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
|
||||
|
||||
// HWND_NOTOPMOST is redirected in WinPosFixupFlags.
|
||||
bNoTopMost = WndInsertAfter == HWND_NOTOPMOST;
|
||||
|
||||
/* Does the window still exist? */
|
||||
if (!IntIsWindow(WinPos.hwnd))
|
||||
{
|
||||
TRACE("WinPosSetWindowPos: Invalid handle 0x%p!\n",WinPos.hwnd);
|
||||
EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -1403,8 +1417,7 @@ co_WinPosSetWindowPos(
|
|||
}
|
||||
|
||||
Ancestor = UserGetAncestor(Window, GA_PARENT);
|
||||
if ( (WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
|
||||
SWP_NOZORDER &&
|
||||
if ( (WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) != SWP_NOZORDER &&
|
||||
Ancestor && Ancestor->head.h == IntGetDesktopWindow() )
|
||||
{
|
||||
WinPos.hwndInsertAfter = WinPosDoOwnedPopups(Window, WinPos.hwndInsertAfter);
|
||||
|
@ -1440,12 +1453,72 @@ co_WinPosSetWindowPos(
|
|||
|
||||
WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect);
|
||||
|
||||
TRACE("co_WinPosDoNCCALCSize returned %d\n", WvrFlags);
|
||||
TRACE("co_WinPosDoNCCALCSize returned %d\n", WvrFlags);
|
||||
|
||||
/* Relink windows. (also take into account shell window in hwndShellWindow) */
|
||||
/* Validate link windows. (also take into account shell window in hwndShellWindow) */
|
||||
if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow())
|
||||
{
|
||||
IntLinkHwnd(Window, WndInsertAfter);
|
||||
//// Fix bug 6751 & 7228 see WinPosDoOwnedPopups wine Fixme.
|
||||
PWND ParentWindow;
|
||||
PWND Sibling;
|
||||
PWND InsertAfterWindow;
|
||||
|
||||
if ((ParentWindow = Window->spwndParent)) // Must have a Parent window!
|
||||
{
|
||||
if (WinPos.hwndInsertAfter == HWND_TOPMOST)
|
||||
{
|
||||
InsertAfterWindow = NULL;
|
||||
}
|
||||
else if ( WinPos.hwndInsertAfter == HWND_TOP )
|
||||
{
|
||||
InsertAfterWindow = NULL;
|
||||
|
||||
Sibling = ParentWindow->spwndChild;
|
||||
|
||||
while ( Sibling && Sibling->ExStyle & WS_EX_TOPMOST )
|
||||
{
|
||||
InsertAfterWindow = Sibling;
|
||||
Sibling = Sibling->spwndNext;
|
||||
}
|
||||
}
|
||||
else if (WinPos.hwndInsertAfter == HWND_BOTTOM)
|
||||
{
|
||||
if (ParentWindow->spwndChild)
|
||||
{
|
||||
InsertAfterWindow = ParentWindow->spwndChild;
|
||||
|
||||
if(InsertAfterWindow)
|
||||
{
|
||||
while (InsertAfterWindow->spwndNext)
|
||||
InsertAfterWindow = InsertAfterWindow->spwndNext;
|
||||
}
|
||||
}
|
||||
else
|
||||
InsertAfterWindow = NULL;
|
||||
}
|
||||
else
|
||||
InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter);
|
||||
/* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
|
||||
the last window */
|
||||
if (InsertAfterWindow != Window)
|
||||
{
|
||||
IntUnlinkWindow(Window);
|
||||
IntLinkWindow(Window, InsertAfterWindow);
|
||||
}
|
||||
|
||||
if ( ( WinPos.hwndInsertAfter == HWND_TOPMOST ||
|
||||
( Window->ExStyle & WS_EX_TOPMOST && Window->spwndPrev && Window->spwndPrev->ExStyle & WS_EX_TOPMOST ) ||
|
||||
( Window->spwndNext && Window->spwndNext->ExStyle & WS_EX_TOPMOST ) ) &&
|
||||
!bNoTopMost )
|
||||
{
|
||||
Window->ExStyle |= WS_EX_TOPMOST;
|
||||
}
|
||||
else
|
||||
{
|
||||
Window->ExStyle &= ~ WS_EX_TOPMOST;
|
||||
}
|
||||
}
|
||||
////
|
||||
}
|
||||
|
||||
OldWindowRect = Window->rcWindow;
|
||||
|
@ -1476,6 +1549,7 @@ co_WinPosSetWindowPos(
|
|||
Window->rcWindow = NewWindowRect;
|
||||
Window->rcClient = NewClientRect;
|
||||
|
||||
/* erase parent when hiding or resizing child */
|
||||
if (WinPos.flags & SWP_HIDEWINDOW)
|
||||
{
|
||||
/* Clear the update region */
|
||||
|
@ -1487,14 +1561,16 @@ co_WinPosSetWindowPos(
|
|||
if (Window->spwndParent == UserGetDesktopWindow())
|
||||
co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM)Window->head.h);
|
||||
|
||||
Window->style &= ~WS_VISIBLE;
|
||||
Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE );
|
||||
IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
|
||||
}
|
||||
else if (WinPos.flags & SWP_SHOWWINDOW)
|
||||
{
|
||||
if (Window->spwndParent == UserGetDesktopWindow())
|
||||
co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Window->head.h);
|
||||
|
||||
Window->style |= WS_VISIBLE;
|
||||
Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 );
|
||||
IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
|
||||
}
|
||||
|
||||
if (Window->hrgnUpdate != NULL && Window->hrgnUpdate != HRGN_WINDOW)
|
||||
|
@ -1504,7 +1580,7 @@ co_WinPosSetWindowPos(
|
|||
NewWindowRect.top - OldWindowRect.top);
|
||||
}
|
||||
|
||||
DceResetActiveDCEs(Window);
|
||||
DceResetActiveDCEs(Window); // For WS_VISIBLE changes.
|
||||
|
||||
if (!(WinPos.flags & SWP_NOREDRAW))
|
||||
{
|
||||
|
@ -1724,6 +1800,10 @@ co_WinPosSetWindowPos(
|
|||
}
|
||||
}
|
||||
|
||||
/* And last, send the WM_WINDOWPOSCHANGED message */
|
||||
|
||||
TRACE("\tstatus flags = %04x\n", WinPos.flags & SWP_AGG_STATUSFLAGS);
|
||||
|
||||
if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
|
||||
{
|
||||
/* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
|
||||
|
@ -1739,7 +1819,7 @@ co_WinPosSetWindowPos(
|
|||
if ( WinPos.flags & SWP_FRAMECHANGED || WinPos.flags & SWP_STATECHANGED ||
|
||||
!(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) )
|
||||
{
|
||||
PWND pWnd = UserGetWindowObject(WinPos.hwnd);
|
||||
PWND pWnd = ValidateHwndNoErr(WinPos.hwnd);
|
||||
if (pWnd)
|
||||
IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
|
||||
}
|
||||
|
@ -2297,7 +2377,7 @@ BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp, BOOL sAsync )
|
|||
winpos->pos.hwnd, winpos->pos.hwndInsertAfter, winpos->pos.x, winpos->pos.y,
|
||||
winpos->pos.cx, winpos->pos.cy, winpos->pos.flags);
|
||||
|
||||
pwnd = (PWND)UserGetObject(gHandleTable, winpos->pos.hwnd, otWindow);
|
||||
pwnd = ValidateHwndNoErr(winpos->pos.hwnd);
|
||||
if (!pwnd)
|
||||
continue;
|
||||
|
||||
|
@ -2328,6 +2408,10 @@ BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp, BOOL sAsync )
|
|||
winpos->pos.cy,
|
||||
winpos->pos.flags);
|
||||
|
||||
// Hack to pass tests.... Must have some work to do so clear the error.
|
||||
if (res && (winpos->pos.flags & (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER)) == SWP_NOZORDER )
|
||||
EngSetLastError(ERROR_SUCCESS);
|
||||
|
||||
UserDerefObjectCo(pwnd);
|
||||
}
|
||||
ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
|
||||
|
@ -2336,7 +2420,6 @@ BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp, BOOL sAsync )
|
|||
return res;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue