[Win32SS]

- Minor fixups to SetParent.
- Add utilities to check thread queue states and verify window object is still alive.

svn path=/trunk/; revision=56688
This commit is contained in:
James Tabor 2012-06-02 03:34:04 +00:00
parent e624236fa1
commit e0d8684a66
6 changed files with 93 additions and 25 deletions

View file

@ -794,6 +794,7 @@ typedef LONG_PTR (NTAPI *PFN_FNID)(PWND, UINT, WPARAM, LPARAM, ULONG_PTR);
#define SRVINFO_APIHOOK 0x0010
#define SRVINFO_METRICS 0x0020
#define SRVINFO_KBDPREF 0x0080
#define NUM_SYSCOLORS 31
@ -2182,7 +2183,8 @@ enum ThreadStateRoutines
THREADSTATE_TASKMANWINDOW,
THREADSTATE_GETMESSAGETIME,
THREADSTATE_GETINPUTSTATE,
THREADSTATE_UPTIMELASTREAD
THREADSTATE_UPTIMELASTREAD,
THREADSTATE_FOREGROUNDTHREAD
};
DWORD_PTR
@ -2522,6 +2524,7 @@ NtUserQueryUserCounters(
#define QUERY_WINDOW_FOCUS 0x03
#define QUERY_WINDOW_ISHUNG 0x04
#define QUERY_WINDOW_REAL_ID 0x05
#define QUERY_WINDOW_FOREGROUND 0x06
DWORD
NTAPI
NtUserQueryWindow(

View file

@ -221,6 +221,10 @@ NtUserGetThreadState(
case THREADSTATE_GETINPUTSTATE:
ret = LOWORD(IntGetQueueStatus(QS_POSTMESSAGE|QS_TIMER|QS_PAINT|QS_SENDMESSAGE|QS_INPUT)) & (QS_KEY | QS_MOUSEBUTTON);
break;
case THREADSTATE_FOREGROUNDTHREAD:
ret = (gpqForeground == GetW32ThreadInfo()->MessageQueue);
break;
}
TRACE("Leave NtUserGetThreadState, ret=%i\n", ret);

View file

@ -422,6 +422,20 @@ UserFreeHandle(PUSER_HANDLE_TABLE ht, HANDLE handle )
return UserDereferenceObject(entry->ptr);
}
BOOL
FASTCALL
UserObjectInDestroy(HANDLE h)
{
PUSER_HANDLE_ENTRY entry;
if (!(entry = handle_to_entry( gHandleTable, h )))
{
SetLastNtError( STATUS_INVALID_HANDLE );
return FALSE;
}
return (entry->flags & HANDLEENTRY_INDESTROY);
}
BOOL
FASTCALL
UserDeleteObject(HANDLE h, USER_OBJECT_TYPE type )

View file

@ -37,6 +37,7 @@ PVOID FASTCALL UserCreateObject(PUSER_HANDLE_TABLE ht, struct _DESKTOP* pDesktop
BOOL FASTCALL UserDeleteObject(HANDLE h, USER_OBJECT_TYPE type );
PVOID UserGetObject(PUSER_HANDLE_TABLE ht, HANDLE handle, USER_OBJECT_TYPE type );
BOOL FASTCALL UserCreateHandleTable(VOID);
BOOL FASTCALL UserObjectInDestroy(HANDLE);
static __inline VOID
UserRefObjectCo(PVOID obj, PUSER_REFERENCE_ENTRY UserReferenceEntry)

View file

@ -59,6 +59,33 @@ PWND FASTCALL IntGetWindowObject(HWND hWnd)
return Window;
}
PWND FASTCALL VerifyWnd(PWND pWnd)
{
HWND hWnd;
UINT State, State2;
if (!pWnd) return NULL;
_SEH2_TRY
{
hWnd = UserHMGetHandle(pWnd);
State = pWnd->state;
State2 = pWnd->state2;
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
_SEH2_YIELD(return NULL);
}
_SEH2_END
if ( UserObjectInDestroy(hWnd) ||
State & WNDS_DESTROYED ||
State2 & WNDS2_INDESTROY )
return NULL;
return pWnd;
}
/* Temp HACK */
PWND FASTCALL UserGetWindowObject(HWND hWnd)
{
@ -144,7 +171,7 @@ IntGetParent(PWND Wnd)
{
if (Wnd->style & WS_POPUP)
{
return Wnd->spwndOwner;
return Wnd->spwndOwner;
}
else if (Wnd->style & WS_CHILD)
{
@ -1039,6 +1066,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
PWND WndOldParent, pWndExam;
BOOL WasVisible;
POINT pt;
int swFlags = SWP_NOSIZE|SWP_NOZORDER;
ASSERT(Wnd);
ASSERT(WndNewParent);
@ -1080,11 +1108,15 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process())
return NULL;
pt.x = Wnd->rcWindow.left;
pt.y = Wnd->rcWindow.top;
WndOldParent = Wnd->spwndParent;
if ( WndOldParent &&
WndOldParent->ExStyle & WS_EX_LAYOUTRTL)
pt.x = Wnd->rcWindow.right;
else
pt.x = Wnd->rcWindow.left;
pt.y = Wnd->rcWindow.top;
if (WndOldParent) UserReferenceObject(WndOldParent); /* Caller must deref */
if (WndNewParent != WndOldParent)
@ -1095,11 +1127,24 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
/* Set the new parent */
Wnd->spwndParent = WndNewParent;
if ( Wnd->style & WS_CHILD &&
Wnd->spwndOwner &&
Wnd->spwndOwner->ExStyle & WS_EX_TOPMOST )
{
ERR("SetParent Top Most from Pop up!\n");
Wnd->ExStyle |= WS_EX_TOPMOST;
}
/* Link the window with its new siblings */
IntLinkHwnd(Wnd, HWND_TOP);
IntLinkHwnd( Wnd,
((0 == (Wnd->ExStyle & WS_EX_TOPMOST) &&
WndNewParent == UserGetDesktopWindow() ) ? HWND_TOP : HWND_TOPMOST ) );
}
if (WndOldParent == UserGetMessageWindow() || WndNewParent == UserGetMessageWindow())
swFlags |= SWP_NOACTIVATE;
IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
/*
* SetParent additionally needs to make hwnd the top window
@ -1108,7 +1153,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
*/
co_WinPosSetWindowPos( Wnd,
(0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
pt.x, pt.y, 0, 0, SWP_NOSIZE );
pt.x, pt.y, 0, 0, swFlags);
if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL);
@ -1156,9 +1201,9 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
UserRefObjectCo(Wnd, &Ref);
UserRefObjectCo(WndParent, &ParentRef);
//ERR("Enter co_IntSetParent\n");
WndOldParent = co_IntSetParent(Wnd, WndParent);
//ERR("Leave co_IntSetParent\n");
UserDerefObjectCo(WndParent);
UserDerefObjectCo(Wnd);
@ -1526,7 +1571,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
* Dialog boxes and message boxes do not inherit layout, so you must
* set the layout explicitly.
*/
if ( Class->fnid != FNID_DIALOG)
if ( Class->fnid != FNID_DIALOG )
{
PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
if (ppi->dwLayout & LAYOUT_RTL)
@ -2077,16 +2122,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
RECTL NewPos;
UINT16 SwFlag;
SwFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
co_WinPosMinMaximize(Window, SwFlag, &NewPos);
SwFlag = ((Window->style & WS_CHILD) || UserGetActiveWindow()) ?
SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
SWP_NOZORDER | SWP_FRAMECHANGED;
UINT SwFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
SwFlag = co_WinPosMinMaximize(Window, SwFlag, &NewPos);
SwFlag |= SWP_NOZORDER|SWP_FRAMECHANGED; /* Frame always gets changed */
if (!(style & WS_VISIBLE) || (style & WS_CHILD) || UserGetActiveWindow()) SwFlag |= SWP_NOACTIVATE;
co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
NewPos.right, NewPos.bottom, SwFlag);
}
@ -2339,6 +2379,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
ASSERT_REFS_CO(Window); // FIXME: Temp HACK?
hWnd = Window->head.h;
ti = PsGetCurrentThreadWin32Thread();
TRACE("co_UserDestroyWindow \n");
@ -2370,9 +2411,9 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
* be destroying.
*/
if (!co_WinPosShowWindow(Window, SW_HIDE))
{
if (UserGetActiveWindow() == Window->head.h)
{
{ // Rule #1.
if (ti->MessageQueue->spwndActive == Window && ti->MessageQueue == IntGetFocusMessageQueue())
{ ERR("DestroyWindow AOW\n");
co_WinPosActivateOtherWindow(Window);
}
}
@ -2381,6 +2422,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
Window->head.pti->MessageQueue->spwndActive = NULL;
if (Window->head.pti->MessageQueue->spwndFocus == Window)
Window->head.pti->MessageQueue->spwndFocus = NULL;
if (Window->head.pti->MessageQueue->spwndActivePrev == Window)
Window->head.pti->MessageQueue->spwndActivePrev = NULL;
if (Window->head.pti->MessageQueue->CaptureWindow == Window->head.h)
Window->head.pti->MessageQueue->CaptureWindow = NULL;
@ -2388,8 +2431,6 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
* Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
*/
ti = PsGetCurrentThreadWin32Thread();
if ((ti != NULL) & (ti->pDeskInfo != NULL))
{
if (ti->pDeskInfo->hShellWindow == hWnd)
@ -3092,7 +3133,7 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
* -- Filip, 01/nov/2003
*/
#if 0
co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
co_WinPosSetWindowPos(WndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
#endif
if (WndListView->ExStyle & WS_EX_TOPMOST)
@ -3518,6 +3559,10 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
Result = (DWORD)pWnd->head.pti->pEThread->Cid.UniqueProcess;
break;
case QUERY_WINDOW_FOREGROUND:
Result = (pWnd->head.pti->MessageQueue == gpqForeground);
break;
default:
Result = (DWORD)NULL;
break;

View file

@ -51,5 +51,6 @@ PWND FASTCALL co_UserCreateWindowEx(CREATESTRUCTW*, PUNICODE_STRING, PLARGE_STRI
BOOL FASTCALL IntEnableWindow(HWND,BOOL);
DWORD FASTCALL GetNCHitEx(PWND,POINT);
ULONG FASTCALL IntSetStyle(PWND,ULONG,ULONG);
PWND FASTCALL VerifyWnd(PWND);
/* EOF */