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

Reply via email to