https://git.reactos.org/?p=reactos.git;a=commitdiff;h=826bd41d88df8b83494ce…
commit 826bd41d88df8b83494ce921f7f4a3ec55544c7f
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Tue Oct 4 09:40:43 2022 +0900
Commit: GitHub <noreply(a)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