[NTUSER][USER32] Initial support of WS_EX_NOACTIVATE flag (#4731)

WS_EX_NOACTIVATE flag forbids the window to be activated. CORE-18417
This commit is contained in:
Katayama Hirofumi MZ 2022-10-04 09:40:43 +09:00 committed by GitHub
parent bd027c9de4
commit 826bd41d88
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 36 additions and 20 deletions

View file

@ -734,7 +734,7 @@ IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
pti->rpdesk != gpdeskInputDesktop || // not current Desktop, pti->rpdesk != gpdeskInputDesktop || // not current Desktop,
pti->MessageQueue == gpqForeground || // if already the queue foreground, pti->MessageQueue == gpqForeground || // if already the queue foreground,
IsFGLocked() || // foreground is locked, IsFGLocked() || // foreground is locked,
Wnd->ExStyle & WS_EX_NOACTIVATE ) // or,,, does not become the foreground window when the user clicks it. (Wnd->ExStyle & WS_EX_NOACTIVATE)) // or, does not become the foreground window when the user clicks it.
{ {
return FALSE; return FALSE;
} }
@ -1041,9 +1041,8 @@ co_IntSetActiveWindow(
ThreadQueue = pti->MessageQueue; ThreadQueue = pti->MessageQueue;
ASSERT(ThreadQueue != 0); ASSERT(ThreadQueue != 0);
hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch. pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
hWndPrev = (pWndChg ? UserHMGetHandle(pWndChg) : NULL);
if ( !Wnd || Wnd == UserGetDesktopWindow() ) if ( !Wnd || Wnd == UserGetDesktopWindow() )
{ {
@ -1055,6 +1054,9 @@ co_IntSetActiveWindow(
hWnd = UserHMGetHandle(Wnd); hWnd = UserHMGetHandle(Wnd);
//ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd); //ERR("co_IntSetActiveWindow 2 hWnd 0x%p\n",hWnd);
if (Wnd->ExStyle & WS_EX_NOACTIVATE)
return TRUE;
/* check if the specified window can be set in the input data of a given queue */ /* check if the specified window can be set in the input data of a given queue */
if ( ThreadQueue != Wnd->head.pti->MessageQueue ) if ( ThreadQueue != Wnd->head.pti->MessageQueue )
{ {
@ -1248,9 +1250,12 @@ BOOL FASTCALL
co_IntMouseActivateWindow(PWND Wnd) co_IntMouseActivateWindow(PWND Wnd)
{ {
TRACE("Mouse Active\n"); TRACE("Mouse Active\n");
if (Wnd && (Wnd->ExStyle & WS_EX_NOACTIVATE))
return TRUE;
return co_IntSetForegroundAndFocusWindow(Wnd, TRUE, TRUE); return co_IntSetForegroundAndFocusWindow(Wnd, TRUE, TRUE);
} }
/* Win: PWND xxxSetActiveWindow(Wnd) */
BOOL FASTCALL BOOL FASTCALL
UserSetActiveWindow( _In_opt_ PWND Wnd ) UserSetActiveWindow( _In_opt_ PWND Wnd )
{ {
@ -1660,8 +1665,9 @@ NtUserSetActiveWindow(HWND hWnd)
{ {
USER_REFERENCE_ENTRY Ref; USER_REFERENCE_ENTRY Ref;
HWND hWndPrev; HWND hWndPrev;
PWND Window; PWND Window, pwndPrev;
DECLARE_RETURN(HWND); DECLARE_RETURN(HWND);
BOOL bActivated;
TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd); TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
UserEnterExclusive(); UserEnterExclusive();
@ -1679,11 +1685,14 @@ NtUserSetActiveWindow(HWND hWnd)
if (!Window || if (!Window ||
Window->head.pti->MessageQueue == gptiCurrent->MessageQueue) Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
{ {
hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL; pwndPrev = gptiCurrent->MessageQueue->spwndActive;
hWndPrev = (pwndPrev ? UserHMGetHandle(pwndPrev) : NULL);
if (Window) UserRefObjectCo(Window, &Ref); if (Window) UserRefObjectCo(Window, &Ref);
UserSetActiveWindow(Window); bActivated = UserSetActiveWindow(Window);
if (Window) UserDerefObjectCo(Window); if (Window) UserDerefObjectCo(Window);
RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 ); if (!bActivated)
RETURN(NULL);
RETURN(hWndPrev ? hWndPrev : hWnd);
} }
RETURN( NULL); RETURN( NULL);

View file

@ -438,12 +438,12 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
if (doSideSnap) if (doSideSnap)
{ {
co_WinPosSetWindowPos(pwnd, co_WinPosSetWindowPos(pwnd,
0, NULL,
snapRect.left, snapRect.left,
snapRect.top, snapRect.top,
snapRect.right - snapRect.left, snapRect.right - snapRect.left,
snapRect.bottom - snapRect.top, snapRect.bottom - snapRect.top,
0); SWP_NOACTIVATE);
pwnd->InternalPos.NormalRect = origRect; pwnd->InternalPos.NormalRect = origRect;
} }
else else
@ -551,13 +551,13 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam)
//// This causes the mdi child window to jump up when it is moved. //// This causes the mdi child window to jump up when it is moved.
//IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 ); //IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 );
co_WinPosSetWindowPos( pwnd, co_WinPosSetWindowPos(pwnd,
0, NULL,
newRect.left, newRect.left,
newRect.top, newRect.top,
newRect.right - newRect.left, newRect.right - newRect.left,
newRect.bottom - newRect.top, newRect.bottom - newRect.top,
( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 ); SWP_NOACTIVATE | ((hittest == HTCAPTION) ? SWP_NOSIZE : 0));
hrgnNew = GreCreateRectRgnIndirect(&pwnd->rcWindow); hrgnNew = GreCreateRectRgnIndirect(&pwnd->rcWindow);
if (pwnd->hrgnClip != NULL) if (pwnd->hrgnClip != NULL)
@ -1532,7 +1532,8 @@ NC_HandleNCLButtonDown(PWND pWnd, WPARAM wParam, LPARAM lParam)
TopWnd = parent; TopWnd = parent;
} }
if ( co_IntSetForegroundWindowMouse(TopWnd) || if ( (pWnd && (pWnd->ExStyle & WS_EX_NOACTIVATE)) ||
co_IntSetForegroundWindowMouse(TopWnd) ||
//NtUserCallHwndLock(hTopWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE) || //NtUserCallHwndLock(hTopWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE) ||
UserGetActiveWindow() == UserHMGetHandle(TopWnd)) UserGetActiveWindow() == UserHMGetHandle(TopWnd))
{ {
@ -1689,6 +1690,7 @@ LRESULT NC_HandleNCRButtonDown( PWND pwnd, WPARAM wParam, LPARAM lParam )
if (UserHMGetHandle(pwnd) != IntGetCapture()) return 0; if (UserHMGetHandle(pwnd) != IntGetCapture()) return 0;
} }
IntReleaseCapture(); IntReleaseCapture();
if (hittest == HTCAPTION || hittest == HTSYSMENU || hittest == HTHSCROLL || hittest == HTVSCROLL) if (hittest == HTCAPTION || hittest == HTSYSMENU || hittest == HTHSCROLL || hittest == HTVSCROLL)
{ {
TRACE("Msg pt %x and Msg.lParam %x and lParam %x\n",MAKELONG(msg.pt.x,msg.pt.y),msg.lParam,lParam); TRACE("Msg pt %x and Msg.lParam %x and lParam %x\n",MAKELONG(msg.pt.x,msg.pt.y),msg.lParam,lParam);

View file

@ -2494,7 +2494,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
SwFlag = co_WinPosMinMaximize(Window, SwFlag, &NewPos); SwFlag = co_WinPosMinMaximize(Window, SwFlag, &NewPos);
SwFlag |= SWP_NOZORDER|SWP_FRAMECHANGED; /* Frame always gets changed */ SwFlag |= SWP_NOZORDER|SWP_FRAMECHANGED; /* Frame always gets changed */
if (!(style & WS_VISIBLE) || (style & WS_CHILD) || UserGetActiveWindow()) SwFlag |= SWP_NOACTIVATE; if (!(style & WS_VISIBLE) || (style & WS_CHILD) || UserGetActiveWindow() ||
(Window->ExStyle & WS_EX_NOACTIVATE))
{
SwFlag |= SWP_NOACTIVATE;
}
co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top, co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top,
NewPos.right, NewPos.bottom, SwFlag); NewPos.right, NewPos.bottom, SwFlag);
} }

View file

@ -379,6 +379,7 @@ BOOL FASTCALL can_activate_window( PWND Wnd OPTIONAL)
if (!(style & WS_VISIBLE)) return FALSE; if (!(style & WS_VISIBLE)) return FALSE;
if (style & WS_MINIMIZE) return FALSE; if (style & WS_MINIMIZE) return FALSE;
if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
if (Wnd->ExStyle & WS_EX_NOACTIVATE) return FALSE;
return TRUE; return TRUE;
/* FIXME: This window could be disable because the child that closed /* FIXME: This window could be disable because the child that closed
was a popup. */ was a popup. */

View file

@ -225,9 +225,9 @@ BOOL IsAltTabWindow(HWND hwnd)
if (!IsWindowVisible(hwnd)) if (!IsWindowVisible(hwnd))
return FALSE; return FALSE;
// must not be WS_EX_TOOLWINDOW // must not be WS_EX_TOOLWINDOW nor WS_EX_NOACTIVATE
ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE); ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE);
if (ExStyle & WS_EX_TOOLWINDOW) if (ExStyle & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE))
return FALSE; return FALSE;
// must be not empty rect // must be not empty rect