[Win32k]
[reactos.git] / reactos / win32ss / user / ntuser / focus.c
index 284cb8f..c58e1d0 100644 (file)
@@ -29,7 +29,7 @@ HWND FASTCALL
 IntGetCaptureWindow(VOID)
 {
    PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
-   return ForegroundQueue != NULL ? ForegroundQueue->CaptureWindow : 0;
+   return ( ForegroundQueue ? (ForegroundQueue->spwndCapture ? UserHMGetHandle(ForegroundQueue->spwndCapture) : 0) : 0);
 }
 
 HWND FASTCALL
@@ -45,119 +45,164 @@ IntGetThreadFocusWindow(VOID)
    return ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 }
 
-VOID FASTCALL
+BOOL FASTCALL
 co_IntSendDeactivateMessages(HWND hWndPrev, HWND hWnd)
 {
-    PWND WndPrev ;
+   USER_REFERENCE_ENTRY RefPrev;
+   PWND WndPrev;
+   BOOL Ret = TRUE;
 
-   if (hWndPrev && (WndPrev = UserGetWindowObject(hWndPrev)))
+   if (hWndPrev && (WndPrev = ValidateHwndNoErr(hWndPrev)))
    {
-      co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0);
-      co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
-                 MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE),
-                 (LPARAM)hWnd);
+      UserRefObjectCo(WndPrev, &RefPrev);
+
+      if (co_IntSendMessageNoWait(hWndPrev, WM_NCACTIVATE, FALSE, 0)) //(LPARAM)hWnd))
+      {
+         co_IntSendMessageNoWait(hWndPrev, WM_ACTIVATE,
+                    MAKEWPARAM(WA_INACTIVE, WndPrev->style & WS_MINIMIZE),
+                    (LPARAM)hWnd);
+
+         if (WndPrev)
+            WndPrev->state &= ~WNDS_ACTIVEFRAME;
+      }
+      else
+      {
+         ERR("Application is keeping itself Active to prevent the change!\n");
+         Ret = FALSE;
+      }
+
+      UserDerefObjectCo(WndPrev);
    }
+   return Ret;
 }
 
 BOOL FASTCALL
 co_IntMakeWindowActive(PWND Window)
 {
   PWND spwndOwner;
-  if (Window)
+  if (VerifyWnd(Window))
   {  // Set last active for window and it's owner.
-     Window->spwndLastActive = Window;
-     spwndOwner = Window->spwndOwner;
-     while (spwndOwner)
+     spwndOwner = Window;
+     while (spwndOwner->spwndOwner)
      {
-       spwndOwner->spwndLastActive = Window;
        spwndOwner = spwndOwner->spwndOwner;
      }
+     spwndOwner->spwndLastActive = Window;
      return TRUE;
    }
    ERR("MakeWindowActive Failed!\n");
    return FALSE;
 }
 
-VOID FASTCALL
-co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
+BOOL FASTCALL
+co_IntSendActivateMessages(PWND WindowPrev, PWND Window, BOOL MouseActivate, BOOL Async)
 {
    USER_REFERENCE_ENTRY Ref, RefPrev;
-   PWND Window, WindowPrev = NULL;
    HANDLE OldTID, NewTID;
-   PTHREADINFO ptiOld, ptiNew;
+   PTHREADINFO pti, ptiOld, ptiNew;
+   BOOL InAAPM = FALSE;
 
-   if ((Window = UserGetWindowObject(hWnd)))
-   { 
-      UserRefObjectCo(Window, &Ref);
+   if (Window)
+   {
+      pti = PsGetCurrentThreadWin32Thread();
 
-      WindowPrev = UserGetWindowObject(hWndPrev);
+      UserRefObjectCo(Window, &Ref);
 
       if (WindowPrev) UserRefObjectCo(WindowPrev, &RefPrev);
 
       /* Send palette messages */
       if (gpsi->PUSIFlags & PUSIF_PALETTEDISPLAY &&
-          co_IntPostOrSendMessage(hWnd, WM_QUERYNEWPALETTE, 0, 0))
+          //co_IntPostOrSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
+          co_IntSendMessage(UserHMGetHandle(Window), WM_QUERYNEWPALETTE, 0, 0))
       {
          UserSendNotifyMessage( HWND_BROADCAST,
                                 WM_PALETTEISCHANGING,
-                               (WPARAM)hWnd,
+                               (WPARAM)UserHMGetHandle(Window),
                                 0);
       }
-
-      if (Window->spwndPrev != NULL)
-         co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0,
-                               SWP_NOSIZE | SWP_NOMOVE);
-
-      if (!Window->spwndOwner && !IntGetParent(Window))
+      //// Fixes bug 7089.
+      if (!(Window->style & WS_CHILD))
       {
-         co_IntShellHookNotify(HSHELL_WINDOWACTIVATED, (LPARAM) hWnd);
-      }
+         PWND pwndTemp = co_GetDesktopWindow(Window)->spwndChild;
 
-      if (Window)
-      {
-         Window->state |= WNDS_ACTIVEFRAME;
+         while (pwndTemp && !(pwndTemp->style & WS_VISIBLE)) pwndTemp = pwndTemp->spwndNext;
 
-         if (Window->style & WS_MINIMIZE)
+         if (Window != pwndTemp || (WindowPrev && !IntIsWindowVisible(WindowPrev)))
          {
-            TRACE("Widow was minimized\n");
+            if (!Async || pti->MessageQueue == gpqForeground)
+            {
+               UINT flags = SWP_NOSIZE | SWP_NOMOVE;
+               if (Window == pwndTemp) flags |= SWP_NOACTIVATE;
+               //ERR("co_IntSendActivateMessages SetWindowPos! Async %d pti Q == FGQ %d\n",Async,pti->MessageQueue == gpqForeground);
+               co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, flags);
+            }
          }
       }
+      ////
+      //// CORE-1161 and CORE-6651
+      if (Window->spwndPrev)
+      {
+         HWND *phwndTopLevel, *phwndCurrent;
+         PWND pwndCurrent, pwndDesktop;
 
-      if (WindowPrev)
-         WindowPrev->state &= ~WNDS_ACTIVEFRAME;
+         pwndDesktop = UserGetDesktopWindow();
+         if (Window->spwndParent == pwndDesktop )
+         {
+            phwndTopLevel = IntWinListChildren(pwndDesktop);
+            phwndCurrent = phwndTopLevel;
+            while(*phwndCurrent)
+            {
+                pwndCurrent = UserGetWindowObject(*phwndCurrent);
 
+                if (pwndCurrent && pwndCurrent->spwndOwner == Window )
+                {
+                    co_WinPosSetWindowPos(pwndCurrent, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_NOACTIVATE);
+                }
+                phwndCurrent++;
+            }
+            ExFreePool(phwndTopLevel);
+          }
+      }
+      ////
       OldTID = WindowPrev ? IntGetWndThreadId(WindowPrev) : NULL;
-      NewTID = Window ? IntGetWndThreadId(Window) : NULL;
+      NewTID = IntGetWndThreadId(Window);
       ptiOld = WindowPrev ? WindowPrev->head.pti : NULL;
-      ptiNew = Window ? Window->head.pti : NULL;
+      ptiNew = Window->head.pti;
 
-      TRACE("SendActiveMessage Old -> %x, New -> %x\n", OldTID, NewTID);
+      //ERR("SendActivateMessage Old -> %x, New -> %x\n", OldTID, NewTID);
 
-      if (OldTID != NewTID)
+      if (!(pti->TIF_flags & TIF_INACTIVATEAPPMSG) &&
+           (!WindowPrev || OldTID != NewTID) )
       {
          PWND cWindow;
          HWND *List, *phWnd;
 
-         List = IntWinListChildren(UserGetWindowObject(IntGetDesktopWindow()));
+         List = IntWinListChildren(UserGetDesktopWindow());
          if ( List )
          {
             if ( OldTID )
             {
+               ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
+               // Note: Do not set pci flags, this does crash!
                for (phWnd = List; *phWnd; ++phWnd)
                {
-                  cWindow = UserGetWindowObject(*phWnd);
+                  cWindow = ValidateHwndNoErr(*phWnd);
                   if (cWindow && cWindow->head.pti == ptiOld)
                   {  // FALSE if the window is being deactivated,
                      // ThreadId that owns the window being activated.
                     co_IntSendMessageNoWait(*phWnd, WM_ACTIVATEAPP, FALSE, (LPARAM)NewTID);
                   }
                }
+               ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
             }
             if ( NewTID )
-            {
+            {  //// Prevents a resource crash due to reentrance!
+               InAAPM = TRUE;
+               pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
+               ////
                for (phWnd = List; *phWnd; ++phWnd)
                {
-                  cWindow = UserGetWindowObject(*phWnd);
+                  cWindow = ValidateHwndNoErr(*phWnd);
                   if (cWindow && cWindow->head.pti == ptiNew)
                   { // TRUE if the window is being activated,
                     // ThreadId that owns the window being deactivated.
@@ -165,44 +210,90 @@ co_IntSendActivateMessages(HWND hWndPrev, HWND hWnd, BOOL MouseActivate)
                   }
                }
             }
-            ExFreePool(List);
+            ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
          }
       }
       if (WindowPrev)
          UserDerefObjectCo(WindowPrev); // Now allow the previous window to die.
 
-      UserDerefObjectCo(Window);
+      if (Window->state & WNDS_ACTIVEFRAME)
+      {  // If already active frame do not allow NCPaint.
+         //ERR("SendActivateMessage Is Active Frame!\n");
+         Window->state |= WNDS_NONCPAINT;
+      }
+
+      if (Window->style & WS_MINIMIZE)
+      {
+         TRACE("Widow was minimized\n");
+      }
+
+      co_IntMakeWindowActive(Window);
 
       /* FIXME: IntIsWindow */
-      co_IntSendMessageNoWait(hWnd, WM_NCACTIVATE, (WPARAM)(hWnd == UserGetForegroundWindow()), 0);
-      /* FIXME: WA_CLICKACTIVE */
-      co_IntSendMessageNoWait(hWnd, WM_ACTIVATE,
-                              MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE,
-                              Window->style & WS_MINIMIZE),
-                              (LPARAM)hWndPrev);
+
+      co_IntSendMessageNoWait( UserHMGetHandle(Window),
+                               WM_NCACTIVATE,
+                              (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)),
+                               0); //(LPARAM)hWndPrev);
+
+      co_IntSendMessageNoWait( UserHMGetHandle(Window),
+                               WM_ACTIVATE,
+                               MAKEWPARAM(MouseActivate ? WA_CLICKACTIVE : WA_ACTIVE, Window->style & WS_MINIMIZE),
+                              (LPARAM)(WindowPrev ? UserHMGetHandle(WindowPrev) : 0));
+
+      if (!Window->spwndOwner && !IntGetParent(Window))
+      {
+         // 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);
+      }
+
+      Window->state &= ~WNDS_NONCPAINT;
+
+      UserDerefObjectCo(Window);
    }
+   return InAAPM;
 }
 
 VOID FASTCALL
-co_IntSendKillFocusMessages(HWND hWndPrev, HWND hWnd)
+IntSendFocusMessages( PTHREADINFO pti, PWND pWnd)
 {
-   if (hWndPrev)
+   PWND pWndPrev;
+   PUSER_MESSAGE_QUEUE ThreadQueue = pti->MessageQueue; // Queue can change...
+
+   ThreadQueue->QF_flags &= ~QF_FOCUSNULLSINCEACTIVE;
+   if (!pWnd && ThreadQueue->spwndActive)
    {
-      IntNotifyWinEvent(EVENT_OBJECT_FOCUS, NULL, OBJID_CLIENT, CHILDID_SELF, 0);
-      co_IntPostOrSendMessage(hWndPrev, WM_KILLFOCUS, (WPARAM)hWnd, 0);
+      ThreadQueue->QF_flags |= QF_FOCUSNULLSINCEACTIVE;
    }
-}
 
-VOID FASTCALL
-co_IntSendSetFocusMessages(HWND hWndPrev, HWND hWnd)
-{
-   if (hWnd)
+   pWndPrev = ThreadQueue->spwndFocus;
+
+   /* check if the specified window can be set in the input data of a given queue */
+   if (!pWnd || ThreadQueue == pWnd->head.pti->MessageQueue)
+      /* set the current thread focus window */
+      ThreadQueue->spwndFocus = pWnd;
+
+   if (pWnd)
    {
-      PWND pWnd = UserGetWindowObject(hWnd);
-      if (pWnd)
+      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(hWnd, WM_SETFOCUS, (WPARAM)hWndPrev, 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);
+      }
+   }
+   else
+   {
+      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);
       }
    }
 }
@@ -230,37 +321,77 @@ IntFindChildWindowToOwner(PWND Root, PWND Owner)
 }
 
 VOID FASTCALL
-FindRemoveAsyncMsg(PWND Wnd)
+FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
 {
-   PUSER_MESSAGE_QUEUE MessageQueue;
+   PTHREADINFO pti;
    PUSER_SENT_MESSAGE Message;
    PLIST_ENTRY Entry;
 
    if (!Wnd) return;
 
-   MessageQueue = Wnd->head.pti->MessageQueue;
+   pti = Wnd->head.pti;
 
-   if (!IsListEmpty(&MessageQueue->SentMessagesListHead))
+   if (!IsListEmpty(&pti->SentMessagesListHead))
    {
       // Scan sent queue messages to see if we received async messages.
-      Entry = MessageQueue->SentMessagesListHead.Flink;
+      Entry = pti->SentMessagesListHead.Flink;
       Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
       do
       {
+         if (IsListEmpty(Entry)) return;
+         if (!Message) return;
+         Entry = Message->ListEntry.Flink;
+
          if (Message->Msg.message == WM_ASYNC_SETACTIVEWINDOW &&
              Message->Msg.hwnd == UserHMGetHandle(Wnd) &&
-             Message->Msg.wParam == 0 )
+             Message->Msg.wParam == wParam )
          {
-             TRACE("ASYNC SAW: Found one in the Sent Msg Queue! %p\n", Message->Msg.hwnd);
-             RemoveEntryList(Entry); // Purge the entry.
+             ERR("ASYNC SAW: Found one in the Sent Msg Queue! %p Activate/Deactivate %d\n", Message->Msg.hwnd,!!wParam);
+             RemoveEntryList(&Message->ListEntry); // Purge the entry.
+             ExFreePoolWithTag(Message, TAG_USRMSG);
          }
-         Entry = Message->ListEntry.Flink;
          Message = CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry);
       }
-      while (Entry != &MessageQueue->SentMessagesListHead);
+      while (Entry != &pti->SentMessagesListHead);
    }
 }
 
+BOOL FASTCALL
+ToggleFGActivate(PTHREADINFO pti)
+{
+   BOOL Ret;
+   PPROCESSINFO ppi = pti->ppi;
+
+   Ret = !!(pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE);
+   if (Ret)
+   {
+      pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
+   }
+   else
+      Ret = !!(ppi->W32PF_flags & W32PF_ALLOWFOREGROUNDACTIVATE);
+
+   if (Ret)
+      ppi->W32PF_flags &= ~W32PF_ALLOWFOREGROUNDACTIVATE;
+   //ERR("ToggleFGActivate is %d\n",Ret);
+   return Ret;
+}
+
+BOOL FASTCALL
+IsAllowedFGActive(PTHREADINFO pti, PWND Wnd)
+{
+   // Not allowed if one or more,,
+   if (!ToggleFGActivate(pti) ||              // bits not set,
+        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.
+   {
+      return FALSE;
+   }
+   //ERR("IsAllowedFGActive is TRUE\n");
+   return TRUE;
+}
+
 /*
    Can the system force foreground from one or more conditions.
  */
@@ -275,13 +406,14 @@ CanForceFG(PPROCESSINFO ppi)
         gppiInputProvider == ppi ||
        !gpqForeground
       ) return TRUE;
+   //ERR("CanForceFG is FALSE\n");
    return FALSE;
 }
 
 /*
    MSDN:
    The system restricts which processes can set the foreground window. A process
-   can set the foreground window only if one of the following conditions is true: 
+   can set the foreground window only if one of the following conditions is true:
 
     * The process is the foreground process.
     * The process was started by the foreground process.
@@ -289,22 +421,25 @@ CanForceFG(PPROCESSINFO ppi)
     * There is no foreground process.
     * The foreground process is being debugged.
     * The foreground is not locked (see LockSetForegroundWindow).
-    * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo). 
+    * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
     * No menus are active.
 */
-
-static BOOL FASTCALL
-co_IntSetForegroundAndFocusWindow(PWND Wnd, BOOL MouseActivate)
+static
+BOOL FASTCALL
+co_IntSetForegroundAndFocusWindow(
+    _In_ PWND Wnd,
+    _In_ BOOL MouseActivate)
 {
-   HWND hWnd = UserHMGetHandle(Wnd);
+   HWND hWnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
    HWND hWndPrev = NULL;
+   PWND pWndPrev = NULL;
    PUSER_MESSAGE_QUEUE PrevForegroundQueue;
    PTHREADINFO pti;
    BOOL fgRet = FALSE, Ret = FALSE;
 
-   ASSERT_REFS_CO(Wnd);
+   if (Wnd) ASSERT_REFS_CO(Wnd);
 
-   TRACE("SetForegroundAndFocusWindow(%x, %x, %s)\n", hWnd, MouseActivate ? "TRUE" : "FALSE");
+   //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
 
    PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
    pti = PsGetCurrentThreadWin32Thread();
@@ -313,75 +448,101 @@ co_IntSetForegroundAndFocusWindow(PWND Wnd, BOOL MouseActivate)
    {  // Same Window Q as foreground just do active.
       if (Wnd && 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.
-            Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE);
+            //ERR("Same WQ and TQ go active.\n");
+            Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
          }
          else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
          { // Same WQ and it is active.
+            //ERR("Same WQ and it is active.\n");
             Ret = TRUE;
          }
          else
          { // Same WQ as FG but not the same TQ send active.
-            co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
+            //ERR("Same WQ as FG but not the same TQ send active.\n");
+            co_IntSendMessage(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
             Ret = TRUE;
          }
          return Ret;
       }
 
       hWndPrev = PrevForegroundQueue->spwndActive ? UserHMGetHandle(PrevForegroundQueue->spwndActive) : 0;
+      pWndPrev = PrevForegroundQueue->spwndActive;
    }
 
    if ( (( !IsFGLocked() || pti->ppi == gppiInputProvider ) &&
          ( CanForceFG(pti->ppi) || pti->TIF_flags & (TIF_SYSTEMTHREAD|TIF_CSRSSTHREAD|TIF_ALLOWFOREGROUNDACTIVATE) )) ||
         pti->ppi == ppiScrnSaver
       )
-   { 
-      IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
-      gptiForeground = Wnd->head.pti;
+   {
+
+      //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.
  */
-      FindRemoveAsyncMsg(Wnd); // Do this to fix test_SFW todos!
+      //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 &&
-          Wnd->head.pti->MessageQueue != PrevForegroundQueue &&
           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, NULL, FALSE, TRUE);
+            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 );
          }
-         else
-         co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
       }
    }
 
+   if (!Wnd) return FALSE; // Always return false.
+
    if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
    {
-       Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE);
+       //ERR("Same PQ and WQ go active.\n");
+       Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
    }
    else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
    {
+       //ERR("Same Active and Wnd.\n");
        Ret = TRUE;
    }
    else
    {
+       //ERR("Activate Not same PQ and WQ and Wnd.\n");
        co_IntSendMessageNoWait(hWnd, WM_ASYNC_SETACTIVEWINDOW, (WPARAM)Wnd, (LPARAM)MouseActivate );
        Ret = TRUE;
    }
-
    return Ret && fgRet;
 }
 
@@ -398,11 +559,11 @@ co_IntMouseActivateWindow(PWND Wnd)
    {
       BOOL Ret;
       PWND TopWnd;
-      PWND DesktopWindow = UserGetWindowObject(IntGetDesktopWindow());
+      PWND DesktopWindow = UserGetDesktopWindow();
       if (DesktopWindow)
       {
          Top = IntFindChildWindowToOwner(DesktopWindow, Wnd);
-         if ((TopWnd = UserGetWindowObject(Top)))
+         if ((TopWnd = ValidateHwndNoErr(Top)))
          {
             UserRefObjectCo(TopWnd, &Ref);
             Ret = co_IntMouseActivateWindow(TopWnd);
@@ -415,54 +576,103 @@ co_IntMouseActivateWindow(PWND Wnd)
    }
 
    TopWindow = UserGetAncestor(Wnd, GA_ROOT);
+   //if (TopWindow) {ERR("MAW 2 pWnd %p hWnd %p\n",TopWindow,TopWindow->head.h);}
    if (!TopWindow) return FALSE;
 
-   /* TMN: Check return valud from this function? */
+   /* TMN: Check return value from this function? */
    UserRefObjectCo(TopWindow, &Ref);
-
    co_IntSetForegroundAndFocusWindow(TopWindow, TRUE);
-
    UserDerefObjectCo(TopWindow);
-
    return TRUE;
 }
 
 BOOL FASTCALL
-co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus)
+co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
 {
    PTHREADINFO pti;
    PUSER_MESSAGE_QUEUE ThreadQueue;
+   PWND pWndChg, WndPrev; // State changes.
    HWND hWndPrev;
    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);
 
    hWndPrev = ThreadQueue->spwndActive ? UserHMGetHandle(ThreadQueue->spwndActive) : NULL;
-   if (Prev) *Prev = hWndPrev;
-   if (hWndPrev == hWnd) return TRUE;
 
-   if (Wnd)
+   pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
+
+   while (Wnd)
    {
-      if (ThreadQueue != Wnd->head.pti->MessageQueue)
+      BOOL Ret, DoFG, AllowFG;
+
+      if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE;
+
+      if (ThreadQueue == Wnd->head.pti->MessageQueue)
       {
-         PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue();
+         if (IsAllowedFGActive(pti, Wnd))
+         {
+             DoFG = TRUE;
+         }
+         else
+         {
+             //ERR("co_IntSetActiveWindow 3 Go Out!\n");
+             break;
+         }
+         AllowFG = !pti->cVisWindows; // Nothing is visable.
+         //ERR("co_IntSetActiveWindow 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 (!ForegroundQueue || ForegroundQueue == ThreadQueue)
+         if (!gpqForeground || gpqForeground == ThreadQueue)
          {
-            return co_IntSetForegroundAndFocusWindow(Wnd, bMouse);
+            DoFG = TRUE;
          }
+         else
+            DoFG = FALSE;
+         if (DoFG)
+         {
+            if (pti->TIF_flags & TIF_ALLOWFOREGROUNDACTIVATE || pti->cVisWindows)
+               AllowFG = TRUE;
+            else
+               AllowFG = FALSE;
+         }
+         else
+            AllowFG = FALSE;
+         //ERR("co_IntSetActiveWindow 3b DoFG = %d AllowFG = %d\n",DoFG,AllowFG);
       }
-
-      if (Wnd->state & WNDS_BEINGACTIVATED) return TRUE;
+      Ret = FALSE;
+      if (DoFG)
+      {
+         pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
+         //ERR("co_IntSetActiveWindow 3c FG set\n");
+         Ret = co_IntSetForegroundAndFocusWindow(Wnd, bMouse);
+         if (AllowFG)
+         {
+            pti->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
+         }
+         else
+         {
+            pti->TIF_flags &= ~TIF_ALLOWFOREGROUNDACTIVATE;
+         }
+      }
+      return Ret;
    }
 
    /* Call CBT hook chain */
@@ -470,46 +680,105 @@ co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus)
    cbt.hWndActive = hWndPrev;
    if (co_HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hWnd, (LPARAM)&cbt))
    {
-      ERR("SetActiveWindow WH_CBT Call Hook return!\n");
+      ERR("SetActiveWindow: WH_CBT Call Hook return!\n");
       return FALSE;
    }
 
-   co_IntSendDeactivateMessages(hWndPrev, hWnd);
+   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: Summery 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 */
-      if (!Wnd || co_IntMakeWindowActive(Wnd))
-      {
-         ThreadQueue->spwndActivePrev = ThreadQueue->spwndActive;
-         ThreadQueue->spwndActive = Wnd;
-      }
+      ThreadQueue->spwndActive = Wnd;
    }
 
-   co_IntSendActivateMessages(hWndPrev, hWnd, bMouse);
+   WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
+
+   InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
 
    /* now change focus if necessary */
-   if (bFocus)
+   if (bFocus && !(ThreadQueue->QF_flags & QF_FOCUSNULLSINCEACTIVE))
    {
       /* Do not change focus if the window is no longer active */
-      if (ThreadQueue->spwndActive == Wnd)
+      if (pti->MessageQueue->spwndActive != IntGetNonChildAncestor(pti->MessageQueue->spwndFocus))
       {
-         if (!ThreadQueue->spwndFocus ||
-             !Wnd ||
-              UserGetAncestor(ThreadQueue->spwndFocus, GA_ROOT) != Wnd)
-         {
-            co_UserSetFocus(Wnd);
-         }
+         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 TRUE;
+   return (ThreadQueue->spwndActive == Wnd);
+}
+
+BOOL FASTCALL
+UserSetActiveWindow(PWND Wnd)
+{
+  if (Wnd) // Must have a window!
+  {
+     if ((Wnd->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
+
+     return co_IntSetActiveWindow(Wnd, FALSE, TRUE, FALSE);
+  }
+  /*
+     Yes your eye are not deceiving you~!
+  
+     First part of wines Win.c test_SetActiveWindow:
+
+     flush_events( TRUE );
+     ShowWindow(hwnd, SW_HIDE);
+     SetFocus(0);
+     SetActiveWindow(0);
+     check_wnd_state(0, 0, 0, 0); <-- This should pass if ShowWindow does it's job!!! As of 10/28/2012 it does!
+
+  */
+  return FALSE;
 }
 
 HWND FASTCALL
@@ -527,13 +796,15 @@ co_UserSetFocus(PWND Window)
    ThreadQueue = pti->MessageQueue;
    ASSERT(ThreadQueue != 0);
 
+   TRACE("Enter SetFocus hWnd 0x%p pti 0x%p\n",Window ? UserHMGetHandle(Window) : 0, pti );
+
    hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 
    if (Window != 0)
    {
       if (hWndPrev == UserHMGetHandle(Window))
       {
-         return hWndPrev; /* Nothing to do */
+         return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0; /* Nothing to do */
       }
 
       if (Window->head.pti->MessageQueue != ThreadQueue)
@@ -543,19 +814,13 @@ co_UserSetFocus(PWND Window)
       }
 
       /* Check if we can set the focus to this window */
-      pwndTop = Window;
-      for (;;)
+      //// Fixes wine win test_SetParent both "todo" line 3710 and 3720...
+      for (pwndTop = Window; pwndTop; pwndTop = pwndTop->spwndParent)
       {
          if (pwndTop->style & (WS_MINIMIZED|WS_DISABLED)) return 0;
-         if (!pwndTop->spwndParent || pwndTop->spwndParent == UserGetDesktopWindow())
-         {
-            if ((pwndTop->style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return 0;
-            break;         
-         }
-         if (pwndTop->spwndParent == UserGetMessageWindow()) return 0;
-         pwndTop = pwndTop->spwndParent;
+         if ((pwndTop->style & (WS_POPUP|WS_CHILD)) != WS_CHILD) break;
       }
-
+      ////
       if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)Window->head.h, (LPARAM)hWndPrev))
       {
          ERR("SetFocus 1 WH_CBT Call Hook return!\n");
@@ -566,11 +831,16 @@ co_UserSetFocus(PWND Window)
       if (pwndTop != ThreadQueue->spwndActive)
       {
          PUSER_MESSAGE_QUEUE ForegroundQueue = IntGetFocusMessageQueue(); // Keep it based on desktop.
-         if (ThreadQueue != ForegroundQueue) // HACK see rule 2 & 3.
+         if (ThreadQueue != ForegroundQueue && IsAllowedFGActive(pti, pwndTop)) // Rule 2 & 3.
          {
+            //ERR("SetFocus: Set Foreground!\n");
+            if (!(pwndTop->style & WS_VISIBLE))
+            {
+                pti->ppi->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE;
+            }
             if (!co_IntSetForegroundAndFocusWindow(pwndTop, FALSE))
             {
-               ERR("SetFocus Set Foreground and Focus Failed!\n");
+               ERR("SetFocus: Set Foreground and Focus Failed!\n");
                return 0;
             }
          }
@@ -578,9 +848,10 @@ co_UserSetFocus(PWND Window)
          /* Set Active when it is needed. */
          if (pwndTop != ThreadQueue->spwndActive)
          {
-            if (!co_IntSetActiveWindow(pwndTop, NULL, FALSE, FALSE))
+            //ERR("SetFocus: Set Active!\n");
+            if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
             {
-               ERR("SetFocus Set Active Failed!\n");
+               ERR("SetFocus: Set Active Failed!\n");
                return 0;
             }
          }
@@ -590,34 +861,28 @@ co_UserSetFocus(PWND Window)
          /* Do not change focus if the window is no longer active */
          if (pwndTop != ThreadQueue->spwndActive)
          {
-            ERR("SetFocus Top window did not go active!\n");
+            ERR("SetFocus: Top window did not go active!\n");
             return 0;
          }
       }
 
-      /* check if the specified window can be set in the input data of a given queue */
-      if ( !Window || ThreadQueue == Window->head.pti->MessageQueue)
-         /* set the current thread focus window */
-         ThreadQueue->spwndFocus = Window;
+      // Check again! SetActiveWindow could have set the focus via WM_ACTIVATE.
+      hWndPrev = ThreadQueue->spwndFocus ? UserHMGetHandle(ThreadQueue->spwndFocus) : 0;
 
-      TRACE("Focus: %d -> %d\n", hWndPrev, Window->head.h);
+      IntSendFocusMessages( pti, Window);
 
-      co_IntSendKillFocusMessages(hWndPrev, Window->head.h);
-      co_IntSendSetFocusMessages(hWndPrev, Window->head.h);
+      TRACE("Focus: %p -> %p\n", hWndPrev, Window->head.h);
    }
    else /* NULL hwnd passed in */
    {
-      if (!hWndPrev) return 0; /* nothing to do */
       if (co_HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)0, (LPARAM)hWndPrev))
       {
-         ERR("SetFocusWindow 2 WH_CBT Call Hook return!\n");
+         ERR("SetFocus: 2 WH_CBT Call Hook return!\n");
          return 0;
       }
 
       /* set the current thread focus window null */
-      ThreadQueue->spwndFocus = 0;
-
-      co_IntSendKillFocusMessages(hWndPrev, 0);
+      IntSendFocusMessages( pti, NULL);
    }
    return hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0;
 }
@@ -652,10 +917,10 @@ IntGetCapture(VOID)
 
    pti = PsGetCurrentThreadWin32Thread();
    ThreadQueue = pti->MessageQueue;
-   RETURN( ThreadQueue ? ThreadQueue->CaptureWindow : 0);
+   RETURN( ThreadQueue ? (ThreadQueue->spwndCapture ? UserHMGetHandle(ThreadQueue->spwndCapture) : 0) : 0);
 
 CLEANUP:
-   TRACE("Leave IntGetCapture, ret=%i\n",_ret_);
+   TRACE("Leave IntGetCapture, ret=%p\n", _ret_);
    END_CLEANUP;
 }
 
@@ -664,7 +929,7 @@ co_UserSetCapture(HWND hWnd)
 {
    PTHREADINFO pti;
    PUSER_MESSAGE_QUEUE ThreadQueue;
-   PWND Window, pWnd;
+   PWND pWnd, Window = NULL;
    HWND hWndPrev;
 
    pti = PsGetCurrentThreadWin32Thread();
@@ -673,15 +938,15 @@ co_UserSetCapture(HWND hWnd)
    if (ThreadQueue->QF_flags & QF_CAPTURELOCKED)
       return NULL;
 
-   if ((Window = UserGetWindowObject(hWnd)))
+   if (hWnd && (Window = UserGetWindowObject(hWnd)))
    {
       if (Window->head.pti->MessageQueue != ThreadQueue)
       {
          return NULL;
       }
    }
-   
-   hWndPrev = MsqSetStateWindow(ThreadQueue, MSQ_STATE_CAPTURE, hWnd);
+
+   hWndPrev = MsqSetStateWindow(pti, MSQ_STATE_CAPTURE, hWnd);
 
    if (hWndPrev)
    {
@@ -697,20 +962,21 @@ co_UserSetCapture(HWND hWnd)
    {
       if (ThreadQueue->MenuOwner && Window) ThreadQueue->QF_flags |= QF_CAPTURELOCKED;
 
-      co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
+      //co_IntPostOrSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
+      co_IntSendMessage(hWndPrev, WM_CAPTURECHANGED, 0, (LPARAM)hWnd);
 
       ThreadQueue->QF_flags &= ~QF_CAPTURELOCKED;
    }
 
-   ThreadQueue->CaptureWindow = hWnd;
+   ThreadQueue->spwndCapture = Window;
 
    if (hWnd == NULL) // Release mode.
    {
       MOUSEINPUT mi;
    /// These are HACKS!
       /* Also remove other windows if not capturing anymore */
-      MsqSetStateWindow(ThreadQueue, MSQ_STATE_MENUOWNER, NULL);
-      MsqSetStateWindow(ThreadQueue, MSQ_STATE_MOVESIZE, NULL);
+      MsqSetStateWindow(pti, MSQ_STATE_MENUOWNER, NULL);
+      MsqSetStateWindow(pti, MSQ_STATE_MOVESIZE, NULL);
    ///
       /* Somebody may have missed some mouse movements */
       mi.dx = 0;
@@ -751,11 +1017,22 @@ IntReleaseCapture(VOID)
 BOOL FASTCALL
 co_IntSetForegroundWindow(PWND Window)
 {
-   ASSERT_REFS_CO(Window);
+   if (Window) ASSERT_REFS_CO(Window);
 
    return co_IntSetForegroundAndFocusWindow(Window, FALSE);
 }
 
+/*
+  API Call
+*/
+BOOL FASTCALL
+co_IntSetForegroundWindowMouse(PWND Window)
+{
+   if (Window) ASSERT_REFS_CO(Window);
+
+   return co_IntSetForegroundAndFocusWindow(Window, TRUE);
+}
+
 /*
   API Call
 */
@@ -820,11 +1097,13 @@ IntAllowSetForegroundWindow(DWORD dwProcessId)
    }
    if (dwProcessId == ASFW_ANY)
    {  // All processes will be enabled to set the foreground window.
+      //ERR("ptiLastInput is CLEARED!!\n");
       ptiLastInput = NULL;
    }
    else
    {  // Rule #3, last input event in force.
-      ptiLastInput = ppi->ptiList;
+      ERR("ptiLastInput is SET!!\n");
+      //ptiLastInput = ppi->ptiList; // See CORE-6384 & CORE-7030.
       ObDereferenceObject(Process);
    }
    return TRUE;
@@ -844,7 +1123,7 @@ NtUserGetForegroundWindow(VOID)
    RETURN( UserGetForegroundWindow());
 
 CLEANUP:
-   TRACE("Leave NtUserGetForegroundWindow, ret=%i\n",_ret_);
+   TRACE("Leave NtUserGetForegroundWindow, ret=%p\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -857,7 +1136,7 @@ NtUserSetActiveWindow(HWND hWnd)
    PWND Window;
    DECLARE_RETURN(HWND);
 
-   TRACE("Enter NtUserSetActiveWindow(%x)\n", hWnd);
+   TRACE("Enter NtUserSetActiveWindow(%p)\n", hWnd);
    UserEnterExclusive();
 
    Window = NULL;
@@ -865,24 +1144,24 @@ NtUserSetActiveWindow(HWND hWnd)
    {
       if (!(Window = UserGetWindowObject(hWnd)))
       {
-         RETURN( 0);
+         ERR("NtUserSetActiveWindow: Invalid handle 0x%p!\n",hWnd);
+         RETURN( NULL);
       }
    }
 
    if (!Window ||
         Window->head.pti->MessageQueue == gptiCurrent->MessageQueue)
    {
+      hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL;
       if (Window) UserRefObjectCo(Window, &Ref);
-      if (!co_IntSetActiveWindow(Window, &hWndPrev, FALSE, TRUE)) hWndPrev = NULL;
+      UserSetActiveWindow(Window);
       if (Window) UserDerefObjectCo(Window);
+      RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
    }
-   else
-      hWndPrev = NULL;
-
-   RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
+   RETURN( NULL);
 
 CLEANUP:
-   TRACE("Leave NtUserSetActiveWindow, ret=%i\n",_ret_);
+   TRACE("Leave NtUserSetActiveWindow, ret=%p\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -895,13 +1174,13 @@ NtUserSetCapture(HWND hWnd)
 {
    DECLARE_RETURN(HWND);
 
-   TRACE("Enter NtUserSetCapture(%x)\n", hWnd);
+   TRACE("Enter NtUserSetCapture(%p)\n", hWnd);
    UserEnterExclusive();
 
    RETURN( co_UserSetCapture(hWnd));
 
 CLEANUP:
-   TRACE("Leave NtUserSetCapture, ret=%i\n",_ret_);
+   TRACE("Leave NtUserSetCapture, ret=%p\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -917,13 +1196,14 @@ NtUserSetFocus(HWND hWnd)
    DECLARE_RETURN(HWND);
    HWND ret;
 
-   TRACE("Enter NtUserSetFocus(%x)\n", hWnd);
+   TRACE("Enter NtUserSetFocus(%p)\n", hWnd);
    UserEnterExclusive();
 
    if (hWnd)
    {
       if (!(Window = UserGetWindowObject(hWnd)))
       {
+         ERR("NtUserSetFocus: Invalid handle 0x%p!\n",hWnd);
          RETURN(NULL);
       }
 
@@ -939,7 +1219,7 @@ NtUserSetFocus(HWND hWnd)
    }
 
 CLEANUP:
-   TRACE("Leave NtUserSetFocus, ret=%i\n",_ret_);
+   TRACE("Leave NtUserSetFocus, ret=%p\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }