https://git.reactos.org/?p=reactos.git;a=commitdiff;h=826bd41d88df8b83494ce921f7f4a3ec55544c7f
commit 826bd41d88df8b83494ce921f7f4a3ec55544c7f Author: Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com> AuthorDate: Tue Oct 4 09:40:43 2022 +0900 Commit: GitHub <nore...@github.com> CommitDate: Tue Oct 4 09:40:43 2022 +0900 [NTUSER][USER32] Initial support of WS_EX_NOACTIVATE flag (#4731) WS_EX_NOACTIVATE flag forbids the window to be activated. CORE-18417 --- win32ss/user/ntuser/focus.c | 23 ++++++++++++++++------- win32ss/user/ntuser/nonclient.c | 22 ++++++++++++---------- win32ss/user/ntuser/window.c | 6 +++++- win32ss/user/ntuser/winpos.c | 1 + win32ss/user/user32/controls/appswitch.c | 4 ++-- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/win32ss/user/ntuser/focus.c b/win32ss/user/ntuser/focus.c index f40a2bf686b..a72070c3542 100644 --- a/win32ss/user/ntuser/focus.c +++ b/win32ss/user/ntuser/focus.c @@ -734,7 +734,7 @@ IsAllowedFGActive(PTHREADINFO pti, PWND Wnd) pti->rpdesk != gpdeskInputDesktop || // not current Desktop, pti->MessageQueue == gpqForeground || // if already the queue foreground, 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; } @@ -1041,9 +1041,8 @@ co_IntSetActiveWindow( ThreadQueue = pti->MessageQueue; ASSERT(ThreadQueue != 0); - hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL; - pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch. + hWndPrev = (pWndChg ? UserHMGetHandle(pWndChg) : NULL); if ( !Wnd || Wnd == UserGetDesktopWindow() ) { @@ -1055,6 +1054,9 @@ co_IntSetActiveWindow( hWnd = UserHMGetHandle(Wnd); //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 */ if ( ThreadQueue != Wnd->head.pti->MessageQueue ) { @@ -1248,9 +1250,12 @@ BOOL FASTCALL co_IntMouseActivateWindow(PWND Wnd) { TRACE("Mouse Active\n"); + if (Wnd && (Wnd->ExStyle & WS_EX_NOACTIVATE)) + return TRUE; return co_IntSetForegroundAndFocusWindow(Wnd, TRUE, TRUE); } +/* Win: PWND xxxSetActiveWindow(Wnd) */ BOOL FASTCALL UserSetActiveWindow( _In_opt_ PWND Wnd ) { @@ -1660,8 +1665,9 @@ NtUserSetActiveWindow(HWND hWnd) { USER_REFERENCE_ENTRY Ref; HWND hWndPrev; - PWND Window; + PWND Window, pwndPrev; DECLARE_RETURN(HWND); + BOOL bActivated; TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd); UserEnterExclusive(); @@ -1679,11 +1685,14 @@ NtUserSetActiveWindow(HWND hWnd) if (!Window || 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); - UserSetActiveWindow(Window); + bActivated = UserSetActiveWindow(Window); if (Window) UserDerefObjectCo(Window); - RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 ); + if (!bActivated) + RETURN(NULL); + RETURN(hWndPrev ? hWndPrev : hWnd); } RETURN( NULL); diff --git a/win32ss/user/ntuser/nonclient.c b/win32ss/user/ntuser/nonclient.c index 59bd57e2f3d..0cace3c0ba3 100644 --- a/win32ss/user/ntuser/nonclient.c +++ b/win32ss/user/ntuser/nonclient.c @@ -438,12 +438,12 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam) if (doSideSnap) { co_WinPosSetWindowPos(pwnd, - 0, + NULL, snapRect.left, snapRect.top, snapRect.right - snapRect.left, snapRect.bottom - snapRect.top, - 0); + SWP_NOACTIVATE); pwnd->InternalPos.NormalRect = origRect; } else @@ -551,13 +551,13 @@ DefWndDoSizeMove(PWND pwnd, WORD wParam) //// This causes the mdi child window to jump up when it is moved. //IntMapWindowPoints( 0, pWndParent, (POINT *)&rect, 2 ); - co_WinPosSetWindowPos( pwnd, - 0, - newRect.left, - newRect.top, - newRect.right - newRect.left, - newRect.bottom - newRect.top, - ( hittest == HTCAPTION ) ? SWP_NOSIZE : 0 ); + co_WinPosSetWindowPos(pwnd, + NULL, + newRect.left, + newRect.top, + newRect.right - newRect.left, + newRect.bottom - newRect.top, + SWP_NOACTIVATE | ((hittest == HTCAPTION) ? SWP_NOSIZE : 0)); hrgnNew = GreCreateRectRgnIndirect(&pwnd->rcWindow); if (pwnd->hrgnClip != NULL) @@ -1532,7 +1532,8 @@ NC_HandleNCLButtonDown(PWND pWnd, WPARAM wParam, LPARAM lParam) TopWnd = parent; } - if ( co_IntSetForegroundWindowMouse(TopWnd) || + if ( (pWnd && (pWnd->ExStyle & WS_EX_NOACTIVATE)) || + co_IntSetForegroundWindowMouse(TopWnd) || //NtUserCallHwndLock(hTopWnd, HWNDLOCK_ROUTINE_SETFOREGROUNDWINDOWMOUSE) || UserGetActiveWindow() == UserHMGetHandle(TopWnd)) { @@ -1689,6 +1690,7 @@ LRESULT NC_HandleNCRButtonDown( PWND pwnd, WPARAM wParam, LPARAM lParam ) if (UserHMGetHandle(pwnd) != IntGetCapture()) return 0; } IntReleaseCapture(); + 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); diff --git a/win32ss/user/ntuser/window.c b/win32ss/user/ntuser/window.c index c880ddcc173..e9026864d57 100644 --- a/win32ss/user/ntuser/window.c +++ b/win32ss/user/ntuser/window.c @@ -2494,7 +2494,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs, 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; + if (!(style & WS_VISIBLE) || (style & WS_CHILD) || UserGetActiveWindow() || + (Window->ExStyle & WS_EX_NOACTIVATE)) + { + SwFlag |= SWP_NOACTIVATE; + } co_WinPosSetWindowPos(Window, 0, NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, SwFlag); } diff --git a/win32ss/user/ntuser/winpos.c b/win32ss/user/ntuser/winpos.c index 25c13b48102..3dc4491fa09 100644 --- a/win32ss/user/ntuser/winpos.c +++ b/win32ss/user/ntuser/winpos.c @@ -379,6 +379,7 @@ BOOL FASTCALL can_activate_window( PWND Wnd OPTIONAL) if (!(style & WS_VISIBLE)) return FALSE; if (style & WS_MINIMIZE) return FALSE; if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; + if (Wnd->ExStyle & WS_EX_NOACTIVATE) return FALSE; return TRUE; /* FIXME: This window could be disable because the child that closed was a popup. */ diff --git a/win32ss/user/user32/controls/appswitch.c b/win32ss/user/user32/controls/appswitch.c index fa522be1c01..6cff11c465f 100644 --- a/win32ss/user/user32/controls/appswitch.c +++ b/win32ss/user/user32/controls/appswitch.c @@ -225,9 +225,9 @@ BOOL IsAltTabWindow(HWND hwnd) if (!IsWindowVisible(hwnd)) return FALSE; - // must not be WS_EX_TOOLWINDOW + // must not be WS_EX_TOOLWINDOW nor WS_EX_NOACTIVATE ExStyle = GetWindowLong(hwnd, GWL_EXSTYLE); - if (ExStyle & WS_EX_TOOLWINDOW) + if (ExStyle & (WS_EX_TOOLWINDOW | WS_EX_NOACTIVATE)) return FALSE; // must be not empty rect