Author: jimtabor Date: Sat Oct 1 18:48:02 2016 New Revision: 72880
URL: http://svn.reactos.org/svn/reactos?rev=72880&view=rev Log: [NtUser] - Fix lockup while testing wine test_activateapp (all the tests including the ones commented out). Reordered focus functions to eliminate recursions. Fix ROSTESTS-208.
Modified: trunk/reactos/win32ss/user/ntuser/focus.c trunk/reactos/win32ss/user/ntuser/focus.h trunk/reactos/win32ss/user/ntuser/message.c trunk/reactos/win32ss/user/ntuser/msgqueue.c trunk/reactos/win32ss/user/ntuser/msgqueue.h trunk/reactos/win32ss/user/ntuser/winpos.c
Modified: trunk/reactos/win32ss/user/ntuser/focus.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/focus.c... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/focus.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/focus.c [iso-8859-1] Sat Oct 1 18:48:02 2016 @@ -48,8 +48,25 @@ return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0; }
-BOOL FASTCALL -co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd) +VOID FASTCALL +UpdateShellHook(PWND Window) +{ + if ( Window->spwndParent == UserGetDesktopWindow() && + Window->spwndOwner == NULL && + (!(Window->ExStyle & WS_EX_TOOLWINDOW) || + (Window->ExStyle & WS_EX_APPWINDOW))) + { + // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise. + co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE); + } + else + { + co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, 0, FALSE); + } +} + +BOOL FASTCALL +co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd, BOOL Clear) { USER_REFERENCE_ENTRY RefPrev; PWND WndPrev; @@ -66,7 +83,7 @@ MAKEWPARAM(WA_INACTIVE, (WndPrev->style & WS_MINIMIZE) != 0), (LPARAM)hWnd);
- if (WndPrev) + if (WndPrev && Clear) WndPrev->state &= ~(WNDS_ACTIVEFRAME|WNDS_HASCAPTION); } else @@ -80,19 +97,255 @@ return Ret; }
+// +// Deactivating the foreground message queue. +// +// Release Active, Capture and Focus Windows associated with this message queue. +// +BOOL FASTCALL +IntDeactivateWindow(PTHREADINFO pti, HANDLE tid) +{ + USER_REFERENCE_ENTRY Ref; + PTHREADINFO ptiPrev; + PWND pwndPrev; + BOOL InAAPM = FALSE; + PTHREADINFO ptiCurrent = PsGetCurrentThreadWin32Thread(); + + if ( !pti->MessageQueue->spwndActive ) + { + TRACE("IDAW E : Nothing to do, Active is NULL! pti 0x%p tid 0x%p\n",pti,tid); + return TRUE; + } + + TRACE("IDAW : pti 0x%p tid 0x%p\n",pti,tid); + + if (ptiCurrent != pti) + { + IntReferenceThreadInfo(pti); + IntReferenceThreadInfo(ptiCurrent); + } + + if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) ) + { + pti->TIF_flags |= TIF_INACTIVATEAPPMSG; + InAAPM = TRUE; + } + + // + // Check for Capture and release it. + // + if ( pti->MessageQueue->spwndCapture ) + { + MSG msg; + PWND pwndCapture = pti->MessageQueue->spwndCapture; + + UserRefObjectCo(pwndCapture, &Ref); + co_IntSendMessage(UserHMGetHandle(pwndCapture), WM_CANCELMODE, 0, 0); + UserDerefObjectCo(pwndCapture); + + /* Generate mouse move message */ + msg.message = WM_MOUSEMOVE; + msg.wParam = UserGetMouseButtonsState(); + msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y); + msg.pt = gpsi->ptCursor; + co_MsqInsertMouseMessage(&msg, 0, 0, TRUE); + } + + // + // Check for Active and release it. + // + if ( pti->MessageQueue->spwndActive ) + { + pwndPrev = pti->MessageQueue->spwndActive; + ptiPrev = pwndPrev->head.pti; + + if (!co_IntSendDeactivateMessages(UserHMGetHandle(pwndPrev), 0, TRUE)) + { + if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; + if (ptiCurrent != pti) + { + IntDereferenceThreadInfo(pti); + IntDereferenceThreadInfo(ptiCurrent); + } + return FALSE; + } + + if ( pti->MessageQueue->spwndActive == pwndPrev ) + { + pti->MessageQueue->spwndActivePrev = pwndPrev; + pti->MessageQueue->spwndActive = NULL; + } + + if (ptiPrev->TIF_flags & TIF_INCLEANUP) ptiPrev = NULL; + } + else + { + ptiPrev = pti; + pwndPrev = (PWND)-1; // Avoid zero Active window. + } + + if ( ptiPrev ) + { + HANDLE OldTID = PsGetThreadId(ptiPrev->pEThread); + PWND cWindow; + HWND *List, *phWnd; + + List = IntWinListChildren(UserGetDesktopWindow()); + if ( List ) + { + if ( OldTID ) + { + for (phWnd = List; *phWnd; ++phWnd) + { + cWindow = ValidateHwndNoErr(*phWnd); + if ( cWindow && cWindow->head.pti == ptiPrev ) + { // FALSE if the window is being deactivated, + // ThreadId that owns the window being activated. + //ERR("IDW : WM_ACTIVATEAPP(0) hwnd %p tid Old %p New %p\n",UserHMGetHandle(cWindow),OldTID,tid); + UserRefObjectCo(cWindow, &Ref); + co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)tid); + UserDerefObjectCo(cWindow); + } + } + } + ExFreePoolWithTag(List, USERTAG_WINDOWLIST); + } + } + + // + // Now check for a change (Bounce), if Active same as previous window, release it too. + // + if ( pti->MessageQueue->spwndActive == pwndPrev ) + { + if (!co_IntSendDeactivateMessages(UserHMGetHandle(pwndPrev), 0, FALSE)) + { + if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; + if (ptiCurrent != pti) + { + IntDereferenceThreadInfo(pti); + IntDereferenceThreadInfo(ptiCurrent); + } + return FALSE; + } + + if ( pti->MessageQueue->spwndActive == pwndPrev ) + { + pti->MessageQueue->spwndActivePrev = pwndPrev; + pti->MessageQueue->spwndActive = NULL; + } + } + + // + // Check for Focus and release it. + // + if ( pti->MessageQueue->spwndFocus ) + { + PWND pwndFocus = pti->MessageQueue->spwndFocus; + + // + // Fix win.c:test_SetForegroundWindow:SetActiveWindow(0)! + // + pti->MessageQueue->spwndFocus = NULL; // Null out Focus. + + UserRefObjectCo(pwndFocus, &Ref); + co_IntSendMessage(UserHMGetHandle(pwndFocus), WM_KILLFOCUS, 0, 0); + UserDerefObjectCo(pwndFocus); + } + + if (InAAPM) pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; + if (ptiCurrent != pti) + { + IntDereferenceThreadInfo(pti); + IntDereferenceThreadInfo(ptiCurrent); + } + return TRUE; +} + +// +// Activating another threads foreground window after a switch. +// +VOID FASTCALL +IntActivateWindow(PWND Wnd, PTHREADINFO pti, HANDLE tid, DWORD Type) +{ + USER_REFERENCE_ENTRY Ref; + PUSER_MESSAGE_QUEUE pmq = pti->MessageQueue; + + if (Wnd) + { + Wnd = VerifyWnd(Wnd); + + if (!Wnd) return; + + UserRefObjectCo(Wnd, &Ref); + + if (!gpqForeground) + { + // No foreground queue set. + co_IntSetForegroundMessageQueue( Wnd, pti, (BOOL)Type, 0); + } + else + { + // Same Active and Wnd. + if ( pmq->spwndActive == Wnd ) + { + WPARAM wParam = (Wnd->head.pti->MessageQueue == gpqForeground); + + co_IntSendMessage( UserHMGetHandle(Wnd), WM_NCACTIVATE, wParam, 0); + + if (wParam) + { + UpdateShellHook(Wnd); + + co_WinPosSetWindowPos(Wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + } + } + else // Not the same, set the active Wnd. + { + co_IntSetActiveWindow(Wnd,(BOOL)Type,TRUE,TRUE); + } + } + UserDerefObjectCo(Wnd); + } + else // Handle no Wnd! + { + if ( tid && // TID, + pmq->spwndActive && // Active WND not zero, + gpqForeground == pmq ) // Same message queues. + { + Wnd = pmq->spwndActive; // Use active window from current queue. + + UserRefObjectCo(Wnd, &Ref); + + co_IntSendMessage( UserHMGetHandle(Wnd), WM_NCACTIVATE, TRUE, 0); + + UpdateShellHook(Wnd); + + co_WinPosSetWindowPos(Wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + + UserDerefObjectCo(Wnd); + } + else if (gpqForeground != pmq) + { + // Not the same message queue so clear flags for foreground switching. + pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE; + pti->ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE; + } + } +} + BOOL FASTCALL co_IntMakeWindowActive(PWND Window) { - PWND spwndOwner; - if (VerifyWnd(Window)) - { // Set last active for window and it's owner. - spwndOwner = Window; - while (spwndOwner->spwndOwner) - { - spwndOwner = spwndOwner->spwndOwner; - } - spwndOwner->spwndLastActive = Window; - return TRUE; + PWND spwndOwner; + if (VerifyWnd(Window)) + { // Set last active for window and it's owner. + spwndOwner = Window; + while (spwndOwner->spwndOwner) + { + spwndOwner = spwndOwner->spwndOwner; + } + spwndOwner->spwndLastActive = Window; + return TRUE; } ERR("MakeWindowActive Failed!\n"); return FALSE; @@ -101,7 +354,7 @@ BOOL FASTCALL co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async) { - USER_REFERENCE_ENTRY Ref, RefPrev; + USER_REFERENCE_ENTRY Ref, RefPrev, RefCall; HANDLE OldTID, NewTID; PTHREADINFO pti, ptiOld, ptiNew; BOOL InAAPM = FALSE; @@ -115,6 +368,8 @@ UserRefObjectCo(Window, &Ref);
if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev); + + pti->MessageQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED;
/* Send palette messages */ if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY && @@ -198,8 +453,10 @@ if (cWindow && cWindow->head.pti == ptiOld) { // FALSE if the window is being deactivated, // ThreadId that owns the window being activated. - //ERR("SendActivateMessage Old\n"); - co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID); + //ERR("SAM : WM_ACTIVATEAPP(0) tid Old %p New %p\n",OldTID,NewTID); + UserRefObjectCo(cWindow, &RefCall); + co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID); + UserDerefObjectCo(cWindow); } } ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG; @@ -215,8 +472,10 @@ if (cWindow && cWindow->head.pti == ptiNew) { // TRUE if the window is being activated, // ThreadId that owns the window being deactivated. - //ERR("SendActivateMessage New\n"); - co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID); + //ERR("SAM : WM_ACTIVATEAPP(1) hwnd %p tid New %p Old %p\n",UserHMGetHandle(cWindow),NewTID,OldTID); + UserRefObjectCo(cWindow, &RefCall); + co_IntSendMessage(*phWnd, WM_ACTIVATEAPP, TRUE, (LPARAM)OldTID); + UserDerefObjectCo(cWindow); } } } @@ -243,27 +502,16 @@ co_IntMakeWindowActive(Window);
co_IntSendMessage( UserHMGetHandle(Window), - WM_NCACTIVATE, - (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)), - 0); //(LPARAM)hWndPrev); + WM_NCACTIVATE, + (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)), + 0);
co_IntSendMessage( UserHMGetHandle(Window), WM_ACTIVATE, MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, (Window->style & WS_MINIMIZE) != 0), (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
- if (Window->spwndParent == UserGetDesktopWindow() && - Window->spwndOwner == NULL && - (!(Window->ExStyle & WS_EX_TOOLWINDOW) || - (Window->ExStyle & WS_EX_APPWINDOW))) - { - // FIXME lParam; The value is TRUE if the window is in full-screen mode, or FALSE otherwise. - co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (WPARAM) UserHMGetHandle(Window), FALSE); - } - else - { - co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, 0, FALSE); - } + UpdateShellHook(Window);
Window->state &= ~WNDS_NONCPAINT;
@@ -295,13 +543,12 @@ { if (pWndPrev) { - //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0); co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, (WPARAM)UserHMGetHandle(pWnd), 0); } if (ThreadQueue->spwndFocus == pWnd) { IntNotifyWinEvent(EVENT_OBJECT_FOCUS, pWnd, OBJID_CLIENT, CHILDID_SELF, 0); - //co_IntPostOrSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0); + co_IntSendMessage(UserHMGetHandle(pWnd), WM_SETFOCUS, (WPARAM)(pWndPrev ? UserHMGetHandle(pWndPrev) : NULL), 0); } } @@ -310,46 +557,41 @@ if (pWndPrev) { IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0); - //co_IntPostOrSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0); + co_IntSendMessage(UserHMGetHandle(pWndPrev), WM_KILLFOCUS, 0, 0); } } }
-VOID FASTCALL -FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam) -{ - PTHREADINFO pti; - PUSER_SENT_MESSAGE Message; +BOOL FASTCALL +FindRemoveEventMsg(PTHREADINFO pti, DWORD Event, DWORD EventLast) +{ + PUSER_MESSAGE Message; PLIST_ENTRY Entry; - - if (!Wnd) return; - - pti = Wnd->head.pti; - - Entry = pti->SentMessagesListHead.Flink; - while (Entry != &pti->SentMessagesListHead) - { - // Scan sent queue messages to see if we received async messages. - Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry); + BOOL Ret = FALSE; + + Entry = pti->PostedMessagesListHead.Flink; + while (Entry != &pti->PostedMessagesListHead) + { + // Scan posted queue messages to see if we received async messages. + Message = CONTAINING_RECORD(Entry, USER_MESSAGE, ListEntry); Entry = Entry->Flink;
- if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW && - Message->Msg.hwnd == UserHMGetHandle(Wnd) && - Message->Msg.wParam == wParam) - { - WARN("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd, !!wParam); - RemoveEntryList(&Message->ListEntry); // Purge the entry. + if (Message->dwQEvent == EventLast) + { + ERR("Event D/SAW: Last Activate/Deactivate %d\n", EventLast); + return Ret; + } + + if (Message->dwQEvent == Event) + { + ERR("Event D/SAW: Found one in the Post Msg Queue! Activate/Deactivate %d\n", Event); ClearMsgBitsMask(pti, Message->QS_Flags); - InsertTailList(&usmList, &Message->ListEntry); - /* Notify the sender. */ - if (Message->pkCompletionEvent != NULL) - { - KeSetEvent(Message->pkCompletionEvent, IO_NO_INCREMENT, FALSE); - } - FreeUserMessage(Message); - } - } + MsqDestroyMessage(Message); + Ret = TRUE; + } + } + return Ret; }
BOOL FASTCALL @@ -406,6 +648,151 @@ return FALSE; }
+// +// Switching out foreground message queues. +// +BOOL FASTCALL +co_IntSetForegroundMessageQueue( + _In_opt_ PWND Wnd, + _In_ PTHREADINFO pti, + _In_ BOOL MouseActivate, + _In_ DWORD Type ) +{ + PTHREADINFO ptiChg, ptiPrev; + PUSER_MESSAGE_QUEUE pumq, pumqChg, pumqPrev; + BOOL Removed, Ret = TRUE; + + if (Wnd && !VerifyWnd(Wnd)) + { + return FALSE; + } + + if ( !gptiForeground || gptiForeground->TIF_flags & TIF_INCLEANUP ) + ptiPrev = NULL; + else + ptiPrev = gptiForeground; + + if (Wnd) + { + ptiChg = Wnd->head.pti; + IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); + gptiForeground = Wnd->head.pti; + //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h); + } + else + { + ptiChg = NULL; + IntSetFocusMessageQueue(NULL); + gptiForeground = NULL; + //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n"); + } + + // + // Process the changing out of the message queues. + // + if (gpqForegroundPrev != gpqForeground) + { + pumqPrev = NULL; + if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) ) + { + pumqPrev = ptiPrev->MessageQueue; + } + + pumq = pti ? pti->MessageQueue : NULL; + + // Deactivate the previous message queue. + if (pumqPrev) + { + if ( pumq != pumqPrev ) + { + MSG Msg; + HWND hWndPrev = pumqPrev->spwndActive ? UserHMGetHandle(pumqPrev->spwndActive) : NULL; + HANDLE tid = gptiForeground ? PsGetThreadId(gptiForeground->pEThread) : NULL; // TID from changing Window PTI. + + Msg.message = WM_ASYNC_SETACTIVEWINDOW; + Msg.hwnd = hWndPrev; + Msg.wParam = (WPARAM)pumqPrev->spwndActive; + Msg.lParam = 0; + Msg.time = 0; + //ERR("SFWAMQ : DAW P pti 0x%p tid 0x%p hWndPrev 0x%p\n",ptiPrev,tid,hWndPrev); + MsqPostMessage(ptiPrev, &Msg, FALSE, QS_EVENT, POSTEVENT_DAW, (LONG_PTR)tid); + } + } + + pumqChg = NULL; + if ( ptiChg && !(ptiChg->TIF_flags & TIF_INCLEANUP) ) + { + pumqChg = ptiChg->MessageQueue; + } + + pumq = pti ? pti->MessageQueue : NULL; + + // Activate changing message queue. + if (pumqChg) + { + /* + Henri Verbeet, + What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the + other thread after we already changed the foreground window back to our own + window. + */ + //ERR("SFWAMQ : 1\n"); + Removed = FindRemoveEventMsg(ptiChg, POSTEVENT_DAW, POSTEVENT_NONE); + + if (pumqChg != pumq) + { + MSG Msg; + HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL; + HANDLE tid = ptiPrev ? PsGetThreadId(ptiPrev->pEThread) : NULL; + + if (Removed) pumqChg->QF_flags |= QF_EVENTDEACTIVATEREMOVED; + + Msg.message = WM_ASYNC_SETACTIVEWINDOW; + Msg.hwnd = hWnd; + Msg.wParam = (WPARAM)Wnd; + Msg.lParam = (LPARAM)tid; //// Fixme! Type flags? + Msg.time = 0; + //ERR("SFWAMQ : SAW P pti 0x%p tid 0x%p hWnd 0x%p\n",ptiChg,tid,hWnd); + MsqPostMessage(ptiChg, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)Type|MouseActivate); + } + else // Current message queue same as changed message queue. + { + if (pumq->spwndActive == Wnd) + { + co_IntSendMessage( UserHMGetHandle(Wnd), WM_NCACTIVATE, TRUE, (LPARAM)UserHMGetHandle(Wnd)); + + UpdateShellHook(Wnd); + + co_WinPosSetWindowPos(Wnd, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE); + } + else + { + //ERR("SFWAMQ : SAW I pti 0x%p hWnd 0x%p\n",ptiChg,Wnd->head.h); + Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE/*Type*/, FALSE); + //if (!Ret) ERR("SFWAMQ : ISAW : return error\n"); + return Ret; + } + } + } + + // Handle same message queue after switch out. + pumqPrev = NULL; + if ( ptiPrev && !(ptiPrev->TIF_flags & TIF_INCLEANUP) ) + { + pumqPrev = ptiPrev->MessageQueue; + } + pumq = pti ? pti->MessageQueue : NULL; + + if ( pumqPrev && pumq == pumqPrev ) + { + HANDLE tid = Wnd ? PsGetThreadId(Wnd->head.pti->pEThread) : NULL; + //ERR("SFWAMQ : DAW I pti 0x%p tid 0x%p hWnd 0x%p\n",ptiPrev,tid,Wnd ? Wnd->head.h : 0); + IntDeactivateWindow(pti, tid); + } + } + return Ret; +} + /* MSDN: The system restricts which processes can set the foreground window. A process @@ -424,31 +811,30 @@ BOOL FASTCALL co_IntSetForegroundAndFocusWindow( _In_opt_ PWND Wnd, - _In_ BOOL MouseActivate) + _In_ BOOL MouseActivate, + _In_ BOOL bFlash ) { HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL; - HWND hWndPrev = NULL; - PWND pWndPrev = NULL; PUSER_MESSAGE_QUEUE PrevForegroundQueue; PTHREADINFO pti; - BOOL fgRet = FALSE, Ret = FALSE; + BOOL Ret = FALSE;
if (Wnd) ASSERT_REFS_CO(Wnd);
- //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE")); + TRACE("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop. pti = PsGetCurrentThreadWin32Thread();
- if (PrevForegroundQueue) + if (Wnd && PrevForegroundQueue) { // Same Window Q as foreground just do active. - if (Wnd && Wnd->head.pti->MessageQueue == PrevForegroundQueue) + if (Wnd->head.pti->MessageQueue == PrevForegroundQueue) { //ERR("Same Window Q as foreground just do active.\n"); if (pti->MessageQueue == PrevForegroundQueue) { // Same WQ and TQ go active. //ERR("Same WQ and TQ go active.\n"); - Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); + Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { // Same WQ and it is active. @@ -458,14 +844,21 @@ else { // Same WQ as FG but not the same TQ send active. //ERR("Same WQ as FG but not the same TQ send active.\n"); - co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); + MSG Msg; + PTHREADINFO ptiNew = Wnd->head.pti; + + Msg.message = WM_ASYNC_SETACTIVEWINDOW; + Msg.hwnd = hWnd; + Msg.wParam = (WPARAM)Wnd; + Msg.lParam = 0; + Msg.time = 0; + //ERR("SFAFW 1 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd); + MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate); + Ret = TRUE; } return Ret; } - - hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0; - pWndPrev = PrevForegroundQueue->spwndActive; }
if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) && @@ -474,78 +867,53 @@ ) {
- //ToggleFGActivate(pti); // win.c line 2662 fail - if (Wnd) - { - IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue); - gptiForeground = Wnd->head.pti; - //ERR("Set Foreground pti 0x%p Q 0x%p hWnd 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue,Wnd->head.h); - } - else - { - IntSetFocusMessageQueue(NULL); - gptiForeground = NULL; - //ERR("Set Foreground pti 0x0 Q 0x0 hWnd 0x0\n"); - } -/* - Henri Verbeet, - What happens is that we get the WM_WINE_SETACTIVEWINDOW message sent by the - other thread after we already changed the foreground window back to our own - window. - */ - //ERR("SFAFW: 1\n"); - FindRemoveAsyncMsg(Wnd, 0); // Do this to fix test_SFW todos! - - fgRet = TRUE; - } - - // Fix FG Bounce with regedit. - if (hWndPrev != hWnd ) - { - if (PrevForegroundQueue && - fgRet && - PrevForegroundQueue->spwndActive) - { - //ERR("SFGW: Send NULL to 0x%x\n",hWndPrev); - if (pti->MessageQueue == PrevForegroundQueue) - { - //ERR("SFGW: TI same as Prev TI\n"); - co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE); - } - else if (pWndPrev) - { - //ERR("SFGW Deactivate: TI not same as Prev TI\n"); - // No real reason to wait here. - co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 ); - } - } - } - - if (!Wnd) return FALSE; // Always return false. + ToggleFGActivate(pti); + + return co_IntSetForegroundMessageQueue( Wnd, pti, MouseActivate, 0 ); + } + + if (!Wnd) return FALSE; // No window, always return FALSE. + + //// if (bFlash) FIXME : handle flash!!!
if (pti->MessageQueue == Wnd->head.pti->MessageQueue) { //ERR("Same PQ and WQ go active.\n"); - Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); + Ret = IntUserSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE); + //if (!Ret) ERR("ISFAFW : IUSAW : return error\n"); } else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd) { - //ERR("Same Active and Wnd.\n"); - Ret = TRUE; + TRACE("Same Active and Wnd.\n"); // Leave this for now. } else { //ERR("Activate Not same PQ and WQ and Wnd.\n"); //// CORE-10785 fix hang, ROSTESTS-208 allows test to run. - //// co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); - co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate ); - Ret = TRUE; - } - return Ret && fgRet; -} - -BOOL FASTCALL -co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async) + MSG Msg; + PTHREADINFO ptiNew = Wnd->head.pti; + + Msg.message = WM_ASYNC_SETACTIVEWINDOW; + Msg.hwnd = hWnd; + Msg.wParam = (WPARAM)Wnd; + Msg.lParam = 0; + Msg.time = 0; + //ERR("SFAFW 2 : SAW P pti 0x%p hWnd 0x%p\n",ptiNew,hWnd); + MsqPostMessage(ptiNew, &Msg, FALSE, QS_EVENT, POSTEVENT_SAW, (LONG_PTR)MouseActivate); + } + // Always return FALSE. + return FALSE; +} + +// +// Set the Active Window. +// +BOOL FASTCALL +co_IntSetActiveWindow( + _In_ PWND Wnd, + _In_ BOOL bMouse, + _In_ BOOL bFocus, + _In_ BOOL Async ) { PTHREADINFO pti; PUSER_MESSAGE_QUEUE ThreadQueue; @@ -554,17 +922,9 @@ HWND hWnd = 0; BOOL InAAPM; CBTACTIVATESTRUCT cbt; + //ERR("co_IntSetActiveWindow 1\n"); - if (Wnd) - { - ASSERT_REFS_CO(Wnd); - hWnd = UserHMGetHandle(Wnd); - if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; - if (Wnd == UserGetDesktopWindow()) return FALSE; - //ERR("co_IntSetActiveWindow 1a hWnd 0x%p\n",hWnd); - } - - //ERR("co_IntSetActiveWindow 2\n"); + pti = PsGetCurrentThreadWin32Thread(); ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); @@ -573,15 +933,148 @@
pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
+ if ( !Wnd || Wnd == UserGetDesktopWindow() ) + { + //ERR("ISAW : NULL %p\n",Wnd); + return FALSE; + } + + ASSERT_REFS_CO(Wnd); + hWnd = UserHMGetHandle(Wnd); + //ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd); + + /* check if the specified window can be set in the input data of a given queue */ + if ( ThreadQueue != Wnd->head.pti->MessageQueue ) + { + //ERR("ISAW : Must have the same Message Queue\n"); + return FALSE; + } + + if (!VerifyWnd(Wnd)) + { + //ERR("ISAW : Window is in Destroy!\n"); + return FALSE; + } + + if ( Wnd == pWndChg ) + { + //ERR("ISAW : Nothing to do\n"); + return TRUE; // Fix CORE-8780 and CORE-11979. See CORE-11324 for breakage. + } + + if ( Wnd->state & WNDS_BEINGACTIVATED ) return TRUE; + + /* Call CBT hook chain */ + cbt.fMouse = bMouse; + cbt.hWndActive = hWndPrev; + if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt)) + { + ERR("SetActiveWindow: WH_CBT Call Hook return!\n"); + return FALSE; + } + + ThreadQueue->QF_flags &= ~QF_EVENTDEACTIVATEREMOVED; + + if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED ) + ThreadQueue->spwndActive = NULL; + else + ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive; + + WndPrev = ThreadQueue->spwndActive; // Keep to save changing active. + + if (WndPrev) + { + if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue; + if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd, TRUE)) return FALSE; + } + + WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active. + + // While in calling message proc or hook: + // Fail if a preemptive switch was made, current active not made previous, + // focus window is dead or no longer the same thread queue. + if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive || + pWndChg != WndPrev || + (Wnd && !VerifyWnd(Wnd)) || + ThreadQueue != pti->MessageQueue ) + { + ERR("SetActiveWindow: Summary ERROR, active state changed!\n"); + return FALSE; + } + + if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE; + + /* set the current thread active window */ + ThreadQueue->spwndActive = Wnd; + + // Set state flag to prevent recursions. + Wnd->state |= WNDS_BEINGACTIVATED; + + IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); + + // Clear out activate EVENT messages. + FindRemoveEventMsg(pti, POSTEVENT_SAW, POSTEVENT_DAW); + + WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again. + + InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async); + + /* now change focus if necessary */ + //// Fixes CORE-6452 allows setting focus on window. + if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE)) + { + /* Do not change focus if the window is no longer active */ + if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus)) + { + PWND pWndSend = pti->MessageQueue->spwndActive; + // Clear focus if the active window is minimized. + if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL; + // Send focus messages and if so, set the focus. + IntSendFocusMessages( pti, pWndSend); + } + } + //// + if (InAAPM) + { + pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; + } + + // Checked in MENU_TrackMenu + ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE; + + //ERR("co_IntSetActiveWindow Exit\n"); + Wnd->state &= ~WNDS_BEINGACTIVATED; + return (ThreadQueue->spwndActive == Wnd); +} + +// +// Set the Active Window. +// +// Window is not optional! +// +BOOL FASTCALL +IntUserSetActiveWindow( + _In_ PWND Wnd, + _In_ BOOL bMouse, + _In_ BOOL bFocus, + _In_ BOOL Async) +{ + PTHREADINFO pti; + PUSER_MESSAGE_QUEUE ThreadQueue; + + //ERR("IntUserSetActiveWindow 1\n"); + ASSERT_REFS_CO(Wnd); + if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; + //ERR("IntUserSetActiveWindow 1a hWnd 0x%p\n",UserHMGetHandle(Wnd)); + + //ERR("IntUserSetActiveWindow 2\n"); + pti = PsGetCurrentThreadWin32Thread(); + ThreadQueue = pti->MessageQueue; + ASSERT(ThreadQueue != 0); + while (Wnd) { BOOL Ret, DoFG, AllowFG; - - if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE; - if (Wnd == pWndChg) - { - return TRUE; // Fix CORE-8780 and CORE-11979. See CORE-11324 for breakage. - }
if (ThreadQueue == Wnd->head.pti->MessageQueue) { @@ -591,17 +1084,16 @@ } else { - //ERR("co_IntSetActiveWindow 3 Go Out!\n"); + //ERR("IntUserSetActiveWindow 3 Go Out!\n"); break; } AllowFG = !pti->cVisWindows; // Nothing is visable. - //ERR("co_IntSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG); + //ERR("IntUserSetActiveWindow 3a DoFG = %d AllowFG = %d\n",DoFG,AllowFG); } else //if (ThreadQueue != Wnd->head.pti->MessageQueue) { //PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Rule 1 & 4, We are foreground so set this FG window or NULL foreground.... - //if (!ForegroundQueue || ForegroundQueue == ThreadQueue) if (!gpqForeground || gpqForeground == ThreadQueue) { DoFG = TRUE; @@ -617,14 +1109,14 @@ } else AllowFG = FALSE; - //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG); + //ERR("IntUserSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG); } Ret = FALSE; if (DoFG) { pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; - //ERR("co_IntSetActiveWindow 3c FG set\n"); - Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse); + //ERR("IntUserSetActiveWindow 3c FG set\n"); + Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse, TRUE); if (AllowFG) { pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE; @@ -637,106 +1129,26 @@ return Ret; }
- /* Call CBT hook chain */ - cbt.fMouse = bMouse; - cbt.hWndActive = hWndPrev; - if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt)) - { - ERR("SetActiveWindow: WH_CBT Call Hook return!\n"); - return FALSE; - } - - if ( ThreadQueue->spwndActive && ThreadQueue->spwndActive->state & WNDS_DESTROYED ) - ThreadQueue->spwndActive = NULL; - else - ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive; - - WndPrev = ThreadQueue->spwndActive; // Keep to save changing active. - - if (WndPrev) - { - if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue; - if (!co_IntSendDeactivateMessages(UserHMGetHandle(WndPrev), hWnd)) return FALSE; - } - - WndPrev = ThreadQueue->spwndActive; // Again keep to save changing active. - - // While in calling message proc or hook: - // Fail if a preemptive switch was made, current active not made previous, - // focus window is dead or no longer the same thread queue. - if ( ThreadQueue->spwndActivePrev != ThreadQueue->spwndActive || - pWndChg != WndPrev || - (Wnd && !VerifyWnd(Wnd)) || - ThreadQueue != pti->MessageQueue ) - { - ERR("SetActiveWindow: Summary ERROR, active state changed!\n"); - return FALSE; - } - - if (!WndPrev) ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE; - - if (Wnd) Wnd->state |= WNDS_BEINGACTIVATED; - - IntNotifyWinEvent(EVENT_SYSTEM_FOREGROUND, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI); - //// Breaks Atl-Esc/Tab via User32. - ////FindRemoveAsyncMsg(Wnd,(WPARAM)Wnd); // Clear out activate ASYNC messages. - - /* check if the specified window can be set in the input data of a given queue */ - if ( !Wnd || ThreadQueue == Wnd->head.pti->MessageQueue) - { - /* set the current thread active window */ - ThreadQueue->spwndActive = Wnd; - } - - WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again. - - InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async); - - /* now change focus if necessary */ - //// Fixes CORE-6452 allows setting focus on window. - if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE)) - { - /* Do not change focus if the window is no longer active */ - if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus)) - { - PWND pWndSend = pti->MessageQueue->spwndActive; - // Clear focus if the active window is minimized. - if (pWndSend && pti->MessageQueue->spwndActive->style & WS_MINIMIZE) pWndSend = NULL; - // Send focus messages and if so, set the focus. - IntSendFocusMessages( pti, pWndSend); - } - } - //// - if (InAAPM) - { - pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG; - } - - // FIXME: Used in the menu loop!!! - ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE; - - //ERR("co_IntSetActiveWindow Exit\n"); - if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED; - return (ThreadQueue->spwndActive == Wnd); + return co_IntSetActiveWindow(Wnd, bMouse, bFocus, Async); }
BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd) { TRACE("Mouse Active\n"); - return co_IntSetForegroundAndFocusWindow(Wnd, TRUE); -} - -BOOL FASTCALL -UserSetActiveWindow(PWND Wnd) + return co_IntSetForegroundAndFocusWindow(Wnd, TRUE, TRUE); +} + +BOOL FASTCALL +UserSetActiveWindow( _In_opt_ PWND Wnd ) { PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
- if (Wnd) // Must have a window! + if (Wnd) { if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
- return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE); + return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE); } /* Yes your eye are not deceiving you~! @@ -759,18 +1171,18 @@ (Wnd = VerifyWnd(gpqForegroundPrev->spwndActivePrev)) != NULL ) { TRACE("USAW:PAW hwnd %p\n",Wnd?Wnd->head.h:NULL); - return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE); + return IntUserSetActiveWindow(Wnd, FALSE, TRUE, FALSE); }
// Activate anyone but the active window. if ( pti->MessageQueue->spwndActive && (Wnd = VerifyWnd(pti->MessageQueue->spwndActive)) != NULL ) { - ERR("USAW:AOWM hwnd %p\n",Wnd?Wnd->head.h:NULL); + //ERR("USAW:AOWM hwnd %p\n",Wnd?Wnd->head.h:NULL); if (!ActivateOtherWindowMin(Wnd)) { // Okay, now go find someone else to play with! - ERR("USAW: Going to WPAOW\n"); + //ERR("USAW: Going to WPAOW\n"); co_WinPosActivateOtherWindow(Wnd); } return TRUE; @@ -838,7 +1250,7 @@ { pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; } - if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE)) + if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE, TRUE)) { ERR("SetFocus: Set Foreground and Focus Failed!\n"); return 0; @@ -848,7 +1260,7 @@ /* Set Active when it is needed. */ if (pwndTop != ThreadQueue->spwndActive) { - //ERR("SetFocus: Set Active!\n"); + //ERR("SetFocus: Set Active! %p\n",pwndTop?UserHMGetHandle(pwndTop):0); if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE)) { ERR("SetFocus: Set Active Failed!\n"); @@ -880,7 +1292,7 @@ ERR("SetFocus: 2 WH_CBT Call Hook return!\n"); return 0; } - + //ERR("SetFocus: Set Focus NULL\n"); /* set the current thread focus window null */ IntSendFocusMessages( pti, NULL); } @@ -1021,7 +1433,7 @@ { if (Window) ASSERT_REFS_CO(Window);
- return co_IntSetForegroundAndFocusWindow(Window, FALSE); + return co_IntSetForegroundAndFocusWindow(Window, FALSE, TRUE); }
/* @@ -1032,7 +1444,7 @@ { if (Window) ASSERT_REFS_CO(Window);
- return co_IntSetForegroundAndFocusWindow(Window, TRUE); + return co_IntSetForegroundAndFocusWindow(Window, TRUE, FALSE); }
/*
Modified: trunk/reactos/win32ss/user/ntuser/focus.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/focus.h... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/focus.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/focus.h [iso-8859-1] Sat Oct 1 18:48:02 2016 @@ -21,6 +21,11 @@ BOOL FASTCALL co_IntSetForegroundWindow(PWND Window); BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window); BOOL FASTCALL co_IntSetActiveWindow(PWND,BOOL,BOOL,BOOL); +BOOL FASTCALL IntUserSetActiveWindow(PWND,BOOL,BOOL,BOOL); BOOL FASTCALL UserSetActiveWindow(PWND Wnd); BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode); BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId); +VOID FASTCALL IntActivateWindow(PWND,PTHREADINFO,HANDLE,DWORD); +BOOL FASTCALL IntDeactivateWindow(PTHREADINFO,HANDLE); +BOOL FASTCALL co_IntSetForegroundMessageQueue(PWND,PTHREADINFO,BOOL,DWORD ); +VOID FASTCALL UpdateShellHook(PWND);
Modified: trunk/reactos/win32ss/user/ntuser/message.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/message... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/message.c [iso-8859-1] Sat Oct 1 18:48:02 2016 @@ -613,7 +613,7 @@ static LRESULT handle_internal_message( PWND pWnd, UINT msg, WPARAM wparam, LPARAM lparam ) { LRESULT lRes; - USER_REFERENCE_ENTRY Ref; +// USER_REFERENCE_ENTRY Ref; // PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
if (!pWnd || @@ -641,14 +641,6 @@ ExFreePoolWithTag(winpos, USERTAG_SWP); return lRes; } - case WM_ASYNC_SETACTIVEWINDOW: - { - PWND Window = (PWND)wparam; - if (wparam) UserRefObjectCo(Window, &Ref); - lRes = (LRESULT)co_IntSetActiveWindow(Window,(BOOL)lparam,TRUE,TRUE); - if (wparam) UserDerefObjectCo(Window); - return lRes; - } case WM_ASYNC_DESTROYWINDOW: { ERR("WM_ASYNC_DESTROYWINDOW\n"); @@ -661,16 +653,29 @@ return 0; }
-static LRESULT handle_internal_events( PTHREADINFO pti, PWND pWnd, LONG_PTR ExtraInfo, PMSG pMsg) +static LRESULT handle_internal_events( PTHREADINFO pti, PWND pWnd, DWORD dwQEvent, LONG_PTR ExtraInfo, PMSG pMsg) { LRESULT Result = 0;
- switch(pMsg->lParam) + switch(dwQEvent) { case POSTEVENT_NWE: { co_EVENT_CallEvents( pMsg->message, pMsg->hwnd, pMsg->wParam, ExtraInfo); } + break; + case POSTEVENT_SAW: + { + //ERR("HIE : SAW : pti 0x%p hWnd 0x%p\n",pti,pMsg->hwnd); + IntActivateWindow((PWND)pMsg->wParam, pti, (HANDLE)pMsg->lParam, (DWORD)ExtraInfo); + } + break; + case POSTEVENT_DAW: + { + //ERR("HIE : DAW : pti 0x%p tid 0x%p hWndPrev 0x%p\n",pti,ExtraInfo,pMsg->hwnd); + IntDeactivateWindow(pti, (HANDLE)ExtraInfo); + } + break; } return Result; } @@ -873,6 +878,7 @@ MsgFilterMax, ProcessMask, ExtraInfo, + 0, Msg )) { return TRUE; @@ -914,6 +920,7 @@ { LONG_PTR eExtraInfo; MSG eMsg; + DWORD dwQEvent; if (MsqPeekMessage( pti, TRUE, Window, @@ -921,9 +928,10 @@ 0, QS_EVENT, &eExtraInfo, + &dwQEvent, &eMsg )) { - handle_internal_events( pti, Window, eExtraInfo, &eMsg); + handle_internal_events( pti, Window, dwQEvent, eExtraInfo, &eMsg); continue; } }
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgqueu... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/msgqueue.c [iso-8859-1] Sat Oct 1 18:48:02 2016 @@ -2115,6 +2115,7 @@ IN UINT MsgFilterHigh, IN UINT QSflags, OUT LONG_PTR *ExtraInfo, + OUT DWORD *dwQEvent, OUT PMSG Message) { PUSER_MESSAGE CurrentMessage; @@ -2145,6 +2146,7 @@ *Message = CurrentMessage->Msg; *ExtraInfo = CurrentMessage->ExtraInfo; QS_Flags = CurrentMessage->QS_Flags; + if (dwQEvent) *dwQEvent = CurrentMessage->dwQEvent;
if (Remove) {
Modified: trunk/reactos/win32ss/user/ntuser/msgqueue.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/msgqueu... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/msgqueue.h [iso-8859-1] Sat Oct 1 18:48:02 2016 @@ -120,7 +120,10 @@ WM_ASYNC_DESTROYWINDOW };
+#define POSTEVENT_DAW 4 +#define POSTEVENT_SAW 5 #define POSTEVENT_NWE 14 +#define POSTEVENT_NONE 0xFFFF
extern LIST_ENTRY usmList;
@@ -141,6 +144,7 @@ IN UINT MsgFilterHigh, IN UINT QSflags, OUT LONG_PTR *ExtraInfo, + OUT DWORD *dwQEvent, OUT PMSG Message); BOOL APIENTRY co_MsqPeekHardwareMessage(IN PTHREADINFO pti, @@ -261,7 +265,7 @@ BOOL FASTCALL IsThreadSuspended(PTHREADINFO); PUSER_SENT_MESSAGE FASTCALL AllocateUserMessage(BOOL); VOID FASTCALL FreeUserMessage(PUSER_SENT_MESSAGE); - +VOID FASTCALL MsqDestroyMessage(PUSER_MESSAGE);
int UserShowCursor(BOOL bShow); PCURICON_OBJECT
Modified: trunk/reactos/win32ss/user/ntuser/winpos.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/win32ss/user/ntuser/winpos.... ============================================================================== --- trunk/reactos/win32ss/user/ntuser/winpos.c [iso-8859-1] (original) +++ trunk/reactos/win32ss/user/ntuser/winpos.c [iso-8859-1] Sat Oct 1 18:48:02 2016 @@ -401,6 +401,7 @@
if (IntIsDesktopWindow(Wnd)) { + //ERR("WinPosActivateOtherWindow Set Focus Msg Q No window!\n"); IntSetFocusMessageQueue(NULL); return; } @@ -437,6 +438,7 @@ WndTo = WndTo->spwndChild; if ( WndTo == NULL ) { + //ERR("WinPosActivateOtherWindow No window!\n"); return; } for (;;) @@ -464,10 +466,10 @@ } } //ERR("WinPosActivateOtherWindow Set Active 0x%p\n",WndTo); - if (!co_IntSetActiveWindow(WndTo,FALSE,TRUE,FALSE)) /* Ok for WndTo to be NULL here */ + if (!UserSetActiveWindow(WndTo)) /* Ok for WndTo to be NULL here */ { //ERR("WPAOW SA 1\n"); - co_IntSetActiveWindow(NULL,FALSE,TRUE,FALSE); + UserSetActiveWindow(NULL); } if (WndTo) UserDerefObjectCo(WndTo); } @@ -1817,7 +1819,7 @@ RECTL CopyRect; PWND Ancestor; BOOL bPointerInWindow, PosChanged = FALSE; - //PTHREADINFO pti = PsGetCurrentThreadWin32Thread(); + PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
ASSERT_REFS_CO(Window);
@@ -2215,10 +2217,15 @@ else { //ERR("SetWindowPos Set FG Window!\n"); - if (Window->state & WNDS_BEINGACTIVATED) // Inside SAW? - co_IntSetActiveWindow(Window, FALSE, TRUE, FALSE); // Fixes Api AttachThreadInput tests. - else - co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow. + if ( pti->MessageQueue->spwndActive != Window || + pti->MessageQueue != gpqForeground ) + { + //ERR("WPSWP : set active window\n"); + if (!(Window->state & WNDS_BEINGACTIVATED)) // Inside SAW? + { + co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow. + } + } } }