Index: win32ss/user/ntuser/msgqueue.h
===================================================================
--- win32ss/user/ntuser/msgqueue.h	(revision 59990)
+++ win32ss/user/ntuser/msgqueue.h	(working copy)
@@ -42,7 +42,6 @@
   /* Reference counter, only access this variable with interlocked functions! */
   LONG References;
 
-  PTHREADINFO ptiOwner; // temp..
   /* Desktop that the message queue is attached to */
   struct _DESKTOP *Desktop;
 
Index: win32ss/user/ntuser/keyboard.c
===================================================================
--- win32ss/user/ntuser/keyboard.c	(revision 59990)
+++ win32ss/user/ntuser/keyboard.c	(working copy)
@@ -868,22 +868,19 @@
     else if (pFocusQueue && bPostMsg)
     {
         PWND Wnd = pFocusQueue->spwndFocus;
-        if (!Wnd)
+
+        pti = pFocusQueue->ptiKeyboard;
+
+        if (!Wnd && pFocusQueue->spwndActive)
         {
            // Focus can be null so going with Active. WM_SYSKEYXXX last wine Win test_keyboard_input.
            Wnd = pFocusQueue->spwndActive;
         }
 
-        if ( !Wnd || Wnd->state2 & WNDS2_INDESTROY || Wnd->state & WNDS_DESTROYED )
-        {
-           ERR("ProcessKeyEvent Active Focus window is dead!\n");
-           return FALSE;
-        }
- 
-        pti = Wnd->head.pti;
+        if (Wnd) pti = Wnd->head.pti;
 
         /* Init message */
-        Msg.hwnd = UserHMGetHandle(Wnd);
+        Msg.hwnd = Wnd ? UserHMGetHandle(Wnd) : NULL;
         Msg.wParam = wFixedVk & 0xFF; /* Note: It's simplified by msg queue */
         Msg.lParam = MAKELPARAM(1, wScanCode);
         Msg.time = dwTime;
@@ -931,9 +928,9 @@
     /* Find the target thread whose locale is in effect */
     pFocusQueue = IntGetFocusMessageQueue();
 
-    if (pFocusQueue && pFocusQueue->ptiOwner)
+    if (pFocusQueue && pFocusQueue->ptiKeyboard)
     {
-        pKl = pFocusQueue->ptiOwner->KeyboardLayout;
+        pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
     }
 
     if (!pKl)
@@ -1014,9 +1011,9 @@
     /* Find the target thread whose locale is in effect */
     pFocusQueue = IntGetFocusMessageQueue();
 
-    if (pFocusQueue && pFocusQueue->ptiOwner)
+    if (pFocusQueue && pFocusQueue->ptiKeyboard)
     {
-        pKl = pFocusQueue->ptiOwner->KeyboardLayout;
+        pKl = pFocusQueue->ptiKeyboard->KeyboardLayout;
     }
 
     if (!pKl)
Index: win32ss/user/ntuser/message.c
===================================================================
--- win32ss/user/ntuser/message.c	(revision 59990)
+++ win32ss/user/ntuser/message.c	(working copy)
@@ -502,21 +502,15 @@
 IdlePing(VOID)
 {
    PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
-   PUSER_MESSAGE_QUEUE ForegroundQueue;
-   PTHREADINFO pti, ptiForeground = NULL;
+   PTHREADINFO pti;
 
-   ForegroundQueue = IntGetFocusMessageQueue();
-
-   if (ForegroundQueue)
-       ptiForeground = ForegroundQueue->ptiOwner;
-
    pti = PsGetCurrentThreadWin32Thread();
 
    if ( pti )
    {
       pti->pClientInfo->cSpins = 0; // Reset spins.
 
-      if ( pti->pDeskInfo && pti == ptiForeground )
+      if ( pti->pDeskInfo && pti == gptiForeground )
       {
          if ( pti->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) ||
               pti->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_FOREGROUNDIDLE) )
@@ -602,13 +596,14 @@
 {
     LRESULT lRes;
     USER_REFERENCE_ENTRY Ref;
+//    PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
 
     if (!pWnd ||
          pWnd == UserGetDesktopWindow() || // pWnd->fnid == FNID_DESKTOP
          pWnd == UserGetMessageWindow() )  // pWnd->fnid == FNID_MESSAGEWND
        return 0;
 
-    TRACE("Internal Event Msg %u hWnd %p\n", msg, pWnd->head.h);
+    ERR("Internal Event Msg %p hWnd 0x%x\n",msg,pWnd->head.h);
 
     switch(msg)
     {
@@ -632,7 +627,7 @@
        {
           PWND Window = (PWND)wparam;
           if (wparam) UserRefObjectCo(Window, &Ref);
-          lRes = (LRESULT)co_IntSetActiveWindow(Window,NULL,(BOOL)lparam,TRUE,TRUE);
+          lRes = (LRESULT)co_IntSetActiveWindow(Window,(BOOL)lparam,TRUE,TRUE);
           if (wparam) UserDerefObjectCo(Window);
           return lRes;
        }
@@ -751,6 +746,14 @@
 
 /*
  * Internal version of PeekMessage() doing all the work
+ *
+ * MSDN:
+ *   Sent messages
+ *   Posted messages
+ *   Input (hardware) messages and system internal events
+ *   Sent messages (again)
+ *   WM_PAINT messages
+ *   WM_TIMER messages
  */
 BOOL FASTCALL
 co_IntPeekMessage( PMSG Msg,
@@ -770,7 +773,7 @@
 
     RemoveMessages = RemoveMsg & PM_REMOVE;
     ProcessMask = HIWORD(RemoveMsg);
-    
+
  /* Hint, "If wMsgFilterMin and wMsgFilterMax are both zero, PeekMessage returns
     all available messages (that is, no range filtering is performed)".        */
     if (!ProcessMask) ProcessMask = (QS_ALLPOSTMESSAGE|QS_ALLINPUT);
@@ -1107,6 +1110,19 @@
     return FALSE;
 }
 
+PTHREADINFO FASTCALL
+IntSendTo(PWND Window, PTHREADINFO ptiCur, UINT Msg)
+{
+   if ( ptiCur )
+   {
+      if ( Window->head.pti->MessageQueue == ptiCur->MessageQueue )
+      {
+         return NULL;
+      }
+   }
+   return Window->head.pti;
+}
+
 BOOL FASTCALL
 UserPostMessage( HWND Wnd,
                  UINT Msg,
@@ -1215,11 +1231,11 @@
 
         if (WM_QUIT == Msg)
         {
-            MsqPostQuitMessage(Window->head.pti, wParam);
+            MsqPostQuitMessage(pti, wParam);
         }
         else
         {
-            MsqPostMessage(Window->head.pti, &Message, FALSE, QS_POSTMESSAGE, 0);
+            MsqPostMessage(pti, &Message, FALSE, QS_POSTMESSAGE, 0);
         }
     }
     return TRUE;
@@ -1253,7 +1269,7 @@
     PMSGMEMORY MsgMemoryEntry;
     INT lParamBufferSize;
     LPARAM lParamPacked;
-    PTHREADINFO Win32Thread;
+    PTHREADINFO Win32Thread, ptiSendTo = NULL;
     ULONG_PTR Hi, Lo, Result = 0;
     DECLARE_RETURN(LRESULT);
     USER_REFERENCE_ENTRY Ref;
@@ -1269,8 +1285,9 @@
 
     Win32Thread = PsGetCurrentThreadWin32Thread();
 
-    if ( Win32Thread &&
-         Window->head.pti == Win32Thread)
+    ptiSendTo = IntSendTo(Window, Win32Thread, Msg);
+
+    if ( !ptiSendTo )
     {
         if (Win32Thread->TIF_flags & TIF_INCLEANUP)
         {
@@ -1356,7 +1373,7 @@
         RETURN( TRUE);
     }
 
-    if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(Window->head.pti))
+    if (uFlags & SMTO_ABORTIFHUNG && MsqIsHung(ptiSendTo/*Window->head.pti*/))
     {
         // FIXME: Set window hung and add to a list.
         /* FIXME: Set a LastError? */
@@ -1372,7 +1389,7 @@
 
     do
     {
-        Status = co_MsqSendMessage( Window->head.pti,
+        Status = co_MsqSendMessage( ptiSendTo, //Window->head.pti,
                                     hWnd,
                                     Msg,
                                     wParam,
@@ -1384,7 +1401,7 @@
     }
     while ((STATUS_TIMEOUT == Status) &&
            (uFlags & SMTO_NOTIMEOUTIFNOTHUNG) &&
-           !MsqIsHung(Window->head.pti)); // FIXME: Set window hung and add to a list.
+           !MsqIsHung(ptiSendTo/*Window->head.pti*/)); // FIXME: Set window hung and add to a list.
 
     if (STATUS_TIMEOUT == Status)
     {
@@ -1514,7 +1531,7 @@
     PMSGMEMORY MsgMemoryEntry;
     INT lParamBufferSize;
     LPARAM lParamPacked;
-    PTHREADINFO Win32Thread;
+    PTHREADINFO Win32Thread, ptiSendTo = NULL;
     DECLARE_RETURN(LRESULT);
     USER_REFERENCE_ENTRY Ref;
     PUSER_SENT_MESSAGE Message;
@@ -1542,9 +1559,11 @@
     {
         RETURN(FALSE);
     }
+    
+    ptiSendTo = IntSendTo(Window, Win32Thread, Msg);
 
     if (Msg & 0x80000000 &&
-        Window->head.pti == Win32Thread)
+        !ptiSendTo)
     {
        if (Win32Thread->TIF_flags & TIF_INCLEANUP) RETURN( FALSE);
 
@@ -1565,14 +1584,14 @@
         lParamBufferSize = MsgMemorySize(MsgMemoryEntry, wParam, lParam);
     }
 
-    if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, Window->head.pti != Win32Thread)))
+    if (! NT_SUCCESS(PackParam(&lParamPacked, Msg, wParam, lParam, !!ptiSendTo)))
     {
         ERR("Failed to pack message parameters\n");
         RETURN( FALSE);
     }
 
     /* If it can be sent now, then send it. */
-    if (Window->head.pti == Win32Thread)
+    if ( !ptiSendTo )
     {
         if (Win32Thread->TIF_flags & TIF_INCLEANUP)
         {
@@ -1622,7 +1641,7 @@
         }
     }
 
-    if (Window->head.pti == Win32Thread)
+    if ( !ptiSendTo)
     {
         if (! NT_SUCCESS(UnpackParam(lParamPacked, Msg, wParam, lParam, FALSE)))
         {
@@ -1645,7 +1664,7 @@
     Message->Result = 0;
     Message->lResult = 0;
     Message->QS_Flags = 0;
-    Message->ptiReceiver = Window->head.pti;
+    Message->ptiReceiver = ptiSendTo; //Window->head.pti;
     Message->ptiSender = NULL; // mjmartin, you are right! This is null.
     Message->ptiCallBackSender = Win32Thread;
     Message->DispatchingListEntry.Flink = NULL;
@@ -1656,10 +1675,10 @@
     Message->QS_Flags = QS_SENDMESSAGE;
 
     if (Msg & 0x80000000) // Higher priority event message!
-       InsertHeadList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
+       InsertHeadList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry);
     else
-       InsertTailList(&Window->head.pti->SentMessagesListHead, &Message->ListEntry);
-    MsqWakeQueue(Window->head.pti, QS_SENDMESSAGE, TRUE);
+       InsertTailList(&ptiSendTo->SentMessagesListHead/*&Window->head.pti->SentMessagesListHead*/, &Message->ListEntry);
+    MsqWakeQueue(ptiSendTo/*Window->head.pti*/, QS_SENDMESSAGE, TRUE);
 
     RETURN(TRUE);
 
@@ -1697,7 +1716,7 @@
 
     pti = PsGetCurrentThreadWin32Thread();
 
-    if ( Window->head.pti->MessageQueue != pti->MessageQueue &&
+    if ( IntSendTo(Window, pti, Msg) &&
          FindMsgMemory(Msg) == 0 )
     {
         Result = UserPostMessage(hWnd, Msg, wParam, lParam);
Index: win32ss/user/ntuser/scrollbar.c
===================================================================
--- win32ss/user/ntuser/scrollbar.c	(revision 59990)
+++ win32ss/user/ntuser/scrollbar.c	(working copy)
@@ -66,6 +66,7 @@
             return 0;
          }
          pSBWnd = (PSBWND)pwnd;
+         pSBWnd->fVert = !!(pwnd->style & SBS_VERT);
          return (PSBDATA)&pSBWnd->SBCalc;
        default:
             ERR("IntGetSBData Bad Bar!\n");
@@ -210,23 +211,7 @@
 
    return TRUE;
 }
-/*
-static VOID FASTCALL
-IntUpdateSBInfo(PWND Window, int wBar)
-{
-   PSCROLLBARINFO sbi;
-   PSBDATA pSBData;
 
-   ASSERT(Window);
-   ASSERT(Window->pSBInfo);
-   ASSERT(Window->pSBInfoex);
-
-   sbi = IntGetScrollbarInfoFromWindow(Window, wBar);
-   pSBData = IntGetSBData(Window, wBar);
-   IntGetScrollBarRect(Window, wBar, &(sbi->rcScrollBar));
-   IntCalculateThumb(Window, wBar, sbi, pSBData);
-}
-*/
 static BOOL FASTCALL
 co_IntGetScrollInfo(PWND Window, INT nBar, PSBDATA pSBData, LPSCROLLINFO lpsi)
 {
@@ -675,8 +660,6 @@
    {
       case SB_CTL:
          {
-            //IntUpdateSBInfo(Wnd, SB_CTL); // Is this needed? Was tested w/o!
-
             co_WinPosShowWindow(Wnd, fShowH ? SW_SHOW : SW_HIDE);
             return TRUE;
          }
@@ -696,13 +679,15 @@
    }
 
    old_style = IntSetStyle( Wnd, set_bits, clear_bits );
+
+   if ((fShowH || fShowV) && !Wnd->pSBInfo)
+   {
+      co_IntCreateScrollBars(Wnd);
+   }
+
    if ((old_style & clear_bits) != 0 || (old_style & set_bits) != set_bits)
    {
-      /////  Is this needed? Was tested w/o!
-      //if (Wnd->style & WS_HSCROLL) IntUpdateSBInfo(Wnd, SB_HORZ);
-      //if (Wnd->style & WS_VSCROLL) IntUpdateSBInfo(Wnd, SB_VERT);
-      /////
-         /* Frame has been changed, let the window redraw itself */
+      /* Frame has been changed, let the window redraw itself */
       co_WinPosSetWindowPos(Wnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
                             SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOSENDCHANGING);
       return TRUE;
Index: win32ss/user/ntuser/input.c
===================================================================
--- win32ss/user/ntuser/input.c	(revision 59990)
+++ win32ss/user/ntuser/input.c	(working copy)
@@ -13,8 +13,6 @@
 /* GLOBALS *******************************************************************/
 
 PTHREADINFO ptiRawInput;
-PTHREADINFO ptiKeyboard;
-PTHREADINFO ptiMouse;
 PKTIMER MasterTimer = NULL;
 PATTACHINFO gpai = NULL;
 INT paiCount = 0;
@@ -396,24 +394,47 @@
     return ret;
 }
 
-PTHREADINFO FASTCALL
-IsThreadAttach(PTHREADINFO ptiTo)
+BOOL
+FASTCALL
+IsRemoveAttachThread(PTHREADINFO pti)
 {
+    NTSTATUS Status;
     PATTACHINFO pai;
+    BOOL Ret = TRUE;
+    PTHREADINFO ptiFrom = NULL, ptiTo = NULL;
 
-    if (!gpai) return NULL;
-
-    pai = gpai;
     do
     {
-        if (pai->pti2 == ptiTo) break;
-        pai = pai->paiNext;
-    } while (pai);
+       if (!gpai) return TRUE;
+ 
+       pai = gpai; // Bottom of the list.
 
-    if (!pai) return NULL;
+       do
+       {
+          if (pai->pti2 == pti)
+          {
+             ptiFrom = pai->pti1;
+             ptiTo = pti;
+             break;
+          }
+          if (pai->pti1 == pti)
+          {
+             ptiFrom = pti;
+             ptiTo = pai->pti2;
+             break;
+          }
+          pai = pai->paiNext;
+        
+       } while (pai);
 
-    // Return ptiFrom.
-    return pai->pti1;
+       if (!pai && !ptiFrom && !ptiTo) break;
+
+       Status = UserAttachThreadInput(ptiFrom, ptiTo, FALSE);
+       if (!NT_SUCCESS(Status)) Ret = FALSE;
+
+    } while (Ret);
+
+    return Ret;
 }
 
 NTSTATUS FASTCALL
@@ -448,44 +469,52 @@
         paiCount++;
         ERR("Attach Allocated! ptiFrom 0x%p  ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
 
-        if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
+        if (ptiTo->MessageQueue != ptiFrom->MessageQueue)
         {
-           ERR("Attach Threads are already associated!\n");
-        }
 
-        ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
+           ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
 
-        /* Keep the original queue in pqAttach (ie do not trash it in a second attachment) */
-        if (ptiFrom->pqAttach == NULL)
-           ptiFrom->pqAttach = ptiFrom->MessageQueue;
-        ptiFrom->MessageQueue = ptiTo->MessageQueue;
+           // FIXME: conditions?
+           if (ptiTo->MessageQueue == gpqForeground)
+           {
+              ERR("ptiTo is Foreground\n");
+           }
+           else
+           {
+              ERR("ptiTo NOT Foreground\n");
+           }
 
-        ptiFrom->MessageQueue->cThreads++;
-        ERR("ptiTo S Share count %lu\n", ptiFrom->MessageQueue->cThreads);
+           if (ptiFrom->MessageQueue == gpqForeground)
+           {
+              ERR("ptiFrom is Foreground\n");
+              ptiTo->MessageQueue->spwndActive  = ptiFrom->MessageQueue->spwndActive;
+              ptiTo->MessageQueue->spwndFocus   = ptiFrom->MessageQueue->spwndFocus;
+              ptiTo->MessageQueue->CursorObject = ptiFrom->MessageQueue->CursorObject;
+              ptiTo->MessageQueue->spwndCapture = ptiFrom->MessageQueue->spwndCapture;
+              ptiTo->MessageQueue->QF_flags    ^= ((ptiTo->MessageQueue->QF_flags ^ ptiFrom->MessageQueue->QF_flags) & QF_CAPTURELOCKED);
+              ptiTo->MessageQueue->CaretInfo    = ptiFrom->MessageQueue->CaretInfo;
+              IntSetFocusMessageQueue(NULL);
+              IntSetFocusMessageQueue(ptiTo->MessageQueue);
+              gptiForeground = ptiTo;
+           }
+           else
+           {
+              ERR("ptiFrom NOT Foreground\n");
+           }
 
-        // FIXME: conditions?
-        if (ptiFrom->pqAttach == gpqForeground)
-        {
-           ERR("ptiFrom is Foreground\n");
-        ptiFrom->MessageQueue->spwndActive = ptiFrom->pqAttach->spwndActive;
-        ptiFrom->MessageQueue->spwndFocus = ptiFrom->pqAttach->spwndFocus;
-        ptiFrom->MessageQueue->CursorObject = ptiFrom->pqAttach->CursorObject;
-        ptiFrom->MessageQueue->spwndCapture = ptiFrom->pqAttach->spwndCapture;
-        ptiFrom->MessageQueue->QF_flags ^= ((ptiFrom->MessageQueue->QF_flags ^ ptiFrom->pqAttach->QF_flags) & QF_CAPTURELOCKED);
-        ptiFrom->MessageQueue->CaretInfo = ptiFrom->pqAttach->CaretInfo;
+           MsqDestroyMessageQueue(ptiFrom);
+
+           ptiFrom->MessageQueue = ptiTo->MessageQueue;
+
+           ptiFrom->MessageQueue->cThreads++;
+           ERR("ptiTo S Share count %d\n", ptiFrom->MessageQueue->cThreads);
+
+           IntReferenceMessageQueue(ptiTo->MessageQueue);
         }
         else
         {
-           ERR("ptiFrom NOT Foreground\n");
+           ERR("Attach Threads are already associated!\n");
         }
-        if (ptiTo->MessageQueue == gpqForeground)
-        {
-           ERR("ptiTo is Foreground\n");
-        }
-        else
-        {
-           ERR("ptiTo NOT Foreground\n");
-        }
     }
     else /* If clear, unlink and free it. */
     {
@@ -512,41 +541,31 @@
         }
 
         if (!Hit) return STATUS_INVALID_PARAMETER;
-
-        ASSERT(ptiFrom->pqAttach);
  
         ERR("Attach Free! ptiFrom 0x%p  ptiTo 0x%p paiCount %d\n",ptiFrom,ptiTo,paiCount);
+ 
+        if (ptiTo->MessageQueue == ptiFrom->MessageQueue)
+        {
+           if (gptiForeground == ptiFrom)
+           {
+              ERR("ptiTo is now pti FG.\n");
+              // MessageQueue foreground is set so switch threads.
+              gptiForeground = ptiTo;
+           }
+           ptiTo->MessageQueue->cThreads--;
+           ERR("ptiTo E Share count %d\n", ptiTo->MessageQueue->cThreads);
+           ASSERT(ptiTo->MessageQueue->cThreads >= 1);
 
-        /* Search list and check if the thread is attached one more time */
-        pai = gpai;
-        while(pai)
+           IntDereferenceMessageQueue(ptiTo->MessageQueue);
+
+           ptiFrom->MessageQueue = MsqCreateMessageQueue(ptiFrom);
+
+           ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
+        }
+        else
         {
-            /* If the thread is attached again , we are done */
-            if (pai->pti1 == ptiFrom) 
-            {
-                ptiFrom->MessageQueue->cThreads--;
-                ERR("ptiTo L Share count %lu\n", ptiFrom->MessageQueue->cThreads);
-                /* Use the message queue of the last attachment */
-                ptiFrom->MessageQueue = pai->pti2->MessageQueue;
-                ptiFrom->MessageQueue->CursorObject = NULL;
-                ptiFrom->MessageQueue->spwndActive = NULL;
-                ptiFrom->MessageQueue->spwndFocus = NULL;
-                ptiFrom->MessageQueue->spwndCapture = NULL;
-                return STATUS_SUCCESS;
-            }
-            pai = pai->paiNext;
+           ERR("Detaching Threads are not associated!\n");
         }
-
-        ptiFrom->MessageQueue->cThreads--;
-        ERR("ptiTo E Share count %lu\n", ptiFrom->MessageQueue->cThreads);
-        ptiFrom->MessageQueue = ptiFrom->pqAttach;
-        // FIXME: conditions?
-        ptiFrom->MessageQueue->CursorObject = NULL;
-        ptiFrom->MessageQueue->spwndActive = NULL;
-        ptiFrom->MessageQueue->spwndFocus = NULL;
-        ptiFrom->MessageQueue->spwndCapture = NULL;
-        ptiFrom->pqAttach = NULL;
-        ptiTo->MessageQueue->iCursorLevel -= ptiFrom->iCursorLevel;
     }
     /* Note that key state, which can be ascertained by calls to the GetKeyState
        or GetKeyboardState function, is reset after a call to AttachThreadInput.
Index: win32ss/user/ntuser/input.h
===================================================================
--- win32ss/user/ntuser/input.h	(revision 59990)
+++ win32ss/user/ntuser/input.h	(working copy)
@@ -63,7 +63,7 @@
 BOOL FASTCALL IntBlockInput(PTHREADINFO W32Thread, BOOL BlockIt);
 DWORD NTAPI CreateSystemThreads(UINT Type);
 NTSTATUS FASTCALL UserAttachThreadInput(PTHREADINFO,PTHREADINFO,BOOL);
-PTHREADINFO FASTCALL IsThreadAttach(PTHREADINFO);
+BOOL FASTCALL IsRemoveAttachThread(PTHREADINFO);
 VOID FASTCALL DoTheScreenSaver(VOID);
 #define ThreadHasInputAccess(W32Thread) (TRUE)
 
Index: win32ss/user/ntuser/window.c
===================================================================
--- win32ss/user/ntuser/window.c	(revision 59990)
+++ win32ss/user/ntuser/window.c	(working copy)
@@ -123,7 +123,12 @@
     styleNew = (pwnd->style | set_bits) & ~clear_bits;
     if (styleNew == styleOld) return styleNew;
     pwnd->style = styleNew;
-    if ((styleOld ^ styleNew) & WS_VISIBLE) DceResetActiveDCEs( pwnd );
+    if ((styleOld ^ styleNew) & WS_VISIBLE) // State Change.
+    {
+       if (styleOld & WS_VISIBLE) pwnd->head.pti->cVisWindows--; 
+       if (styleNew & WS_VISIBLE) pwnd->head.pti->cVisWindows++;
+       DceResetActiveDCEs( pwnd );
+    }
     return styleOld;
 }
 
@@ -159,21 +164,16 @@
 BOOL FASTCALL
 IntIsWindowVisible(PWND Wnd)
 {
-   BOOL Ret = TRUE;
-   do
+   PWND Temp = Wnd;
+   for (;;)
    {
-      if (!(Wnd->style & WS_VISIBLE))
-      {
-         Ret = FALSE;
-         break;
-      }
-      if (Wnd->spwndParent != NULL)
-         Wnd = Wnd->spwndParent;
-      else
-         break;
+      if (!Temp) return TRUE;
+      if (!(Temp->style & WS_VISIBLE)) break;
+      if (Temp->style & WS_MINIMIZE && Temp != Wnd) break;
+      if (Temp->fnid == FNID_DESKTOP) return TRUE;
+      Temp = Temp->spwndParent;
    }
-   while (Wnd != NULL);
-   return Ret;
+   return FALSE;
 }
 
 PWND FASTCALL
@@ -436,6 +436,7 @@
    }
    Window->state2 |= WNDS2_INDESTROY;
    Window->style &= ~WS_VISIBLE;
+   Window->head.pti->cVisWindows--;
 
    IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
 
@@ -497,9 +498,6 @@
    /* flush the message queue */
    MsqRemoveWindowMessagesFromQueue(Window);
 
-   NT_ASSERT(Window->head.pti);
-   IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
-
    /* from now on no messages can be sent to this window anymore */
    Window->state |= WNDS_DESTROYED;
    Window->fnid |= FNID_FREED;
@@ -571,6 +569,7 @@
       GreDeleteObject(Window->hrgnClip);
       Window->hrgnClip = NULL;
    }
+   Window->head.pti->cWindows--;
 
 //   ASSERT(Window != NULL);
    UserFreeWindowInfo(Window->head.pti, Window);
@@ -1091,8 +1090,8 @@
               Wnd->head.pti == WndNewOwner->head.pti ||
               WndOldOwner->head.pti != WndNewOwner->head.pti )
          {
-            ERR("ProcessOwnerSwap Old out.\n");
-            //UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE);
+            //ERR("ProcessOwnerSwap Old out.\n");
+            UserAttachThreadInput(Wnd->head.pti, WndOldOwner->head.pti, FALSE);
          }
       }
    }
@@ -1103,8 +1102,8 @@
          if (!WndOldOwner ||
               WndOldOwner->head.pti != WndNewOwner->head.pti )
          {
-            ERR("ProcessOwnerSwap New in.\n");
-            //UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE);
+            //ERR("ProcessOwnerSwap New in.\n");
+            UserAttachThreadInput(Wnd->head.pti, WndNewOwner->head.pti, TRUE);
          }
       }
    }
@@ -1133,6 +1132,8 @@
       goto Error;
    }
 
+   /* if parent belongs to a different thread and the window isn't */
+   /* top-level, attach the two threads */
    IntProcessOwnerSwap(Wnd, WndNewOwner, WndOldOwner);
 
    if (IntValidateOwnerDepth(Wnd, WndNewOwner))
@@ -1179,6 +1180,7 @@
    /* Some applications try to set a child as a parent */
    if (IntIsChildWindow(Wnd, WndNewParent))
    {
+      ERR("IntSetParent try to set a child as a parent.\n");
       EngSetLastError( ERROR_INVALID_PARAMETER );
       return NULL;
    }
@@ -1189,6 +1191,7 @@
    {
       if (Wnd == pWndExam)
       {
+         ERR("IntSetParent Failed Test for set parent to parent!\n");
          EngSetLastError(ERROR_INVALID_PARAMETER);
          return NULL;
       }
@@ -1203,7 +1206,10 @@
 
    /* Window must belong to current process */
    if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process())
+   {
+      ERR("IntSetParent Window must belong to current process!\n");
       return NULL;
+   }
 
    WndOldParent = Wnd->spwndParent;
 
@@ -1242,22 +1248,31 @@
 
    }
 
+   if ( WndNewParent == co_GetDesktopWindow(Wnd) &&
+       !(Wnd->style & WS_CLIPSIBLINGS) )
+   {
+      Wnd->style |= WS_CLIPSIBLINGS;
+      DceResetActiveDCEs(Wnd);
+   }
+
+   /* if parent belongs to a different thread and the window isn't */
+   /* top-level, attach the two threads */
    if ((Wnd->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
    {
       if ( Wnd->spwndParent != co_GetDesktopWindow(Wnd))
       {
          if (Wnd->head.pti != WndOldParent->head.pti)
          {
-            ERR("SetParent Old out.\n");
-            //UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE);
+            //ERR("SetParent Old out.\n");
+            UserAttachThreadInput(Wnd->head.pti, WndOldParent->head.pti, FALSE);
          }
       }
       if ( WndNewParent != co_GetDesktopWindow(Wnd))
       {
          if (Wnd->head.pti != WndNewParent->head.pti)
          {
-            ERR("SetParent New in.\n");
-            //UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE);
+            //ERR("SetParent New in.\n");
+            UserAttachThreadInput(Wnd->head.pti, WndNewParent->head.pti, TRUE);
          }
       }
    }
@@ -1271,10 +1286,11 @@
     * in the z-order and send the expected WM_WINDOWPOSCHANGING and
     * WM_WINDOWPOSCHANGED notification messages.
     */
+   //ERR("IntSetParent SetWindowPos 1\n");
    co_WinPosSetWindowPos( Wnd,
                          (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
                           pt.x, pt.y, 0, 0, swFlags);
-
+   //ERR("IntSetParent SetWindowPos 2\n");
    if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL);
 
    return WndOldParent;
@@ -1295,6 +1311,7 @@
 
    if (hWndChild == IntGetDesktopWindow())
    {
+      ERR("UserSetParent Access Denied!\n");
       EngSetLastError(ERROR_ACCESS_DENIED);
       return( NULL);
    }
@@ -1303,6 +1320,7 @@
    {
       if (!(WndParent = UserGetWindowObject(hWndNewParent)))
       {
+         ERR("UserSetParent Bad New Parent!\n");
          return( NULL);
       }
    }
@@ -1316,6 +1334,7 @@
 
    if (!(Wnd = UserGetWindowObject(hWndChild)))
    {
+      ERR("UserSetParent Bad Child!\n");
       return( NULL);
    }
 
@@ -1755,13 +1774,14 @@
    pWnd->InternalPos.MaxPos.x  = pWnd->InternalPos.MaxPos.y  = -1;
    pWnd->InternalPos.IconPos.x = pWnd->InternalPos.IconPos.y = -1;
 
-   IntReferenceMessageQueue(pWnd->head.pti->MessageQueue);
    if (pWnd->spwndParent != NULL && Cs->hwndParent != 0)
    {
        pWnd->HideFocus = pWnd->spwndParent->HideFocus;
        pWnd->HideAccel = pWnd->spwndParent->HideAccel;
    }
 
+   pWnd->head.pti->cWindows++;
+
    if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
       pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
 
@@ -1946,8 +1966,8 @@
             Class->atomClassName != gpsi->atomSysClass[ICLS_IME] &&
             pti != pWnd->spwndOwner->head.pti)
        {
-          ERR("CreateWindow Owner in.\n");
-          //UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE);
+          //ERR("CreateWindow Owner in.\n");
+          UserAttachThreadInput(pti, pWnd->spwndOwner->head.pti, TRUE);
        }
    }
 
@@ -2187,6 +2207,15 @@
    Cs->lpszName = (LPCWSTR) WindowName;
    Cs->lpszClass = (LPCWSTR) ClassName;
 
+   if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
+   {
+      if (ParentWindow != co_GetDesktopWindow(Window))
+      {
+         Cs->x += ParentWindow->rcClient.left;
+         Cs->y += ParentWindow->rcClient.top; 
+      }
+   }
+
    /* Send the WM_GETMINMAXINFO message */
    Size.cx = Cs->cx;
    Size.cy = Cs->cy;
@@ -2204,6 +2233,7 @@
    Window->rcWindow.top = Cs->y;
    Window->rcWindow.right = Cs->x + Size.cx;
    Window->rcWindow.bottom = Cs->y + Size.cy;
+/*
    if (0 != (Window->style & WS_CHILD) && ParentWindow)
    {
 //      ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
@@ -2211,6 +2241,7 @@
                         ParentWindow->rcClient.left,
                         ParentWindow->rcClient.top);
    }
+*/
    Window->rcClient = Window->rcWindow;
 
    /* Link the window */
@@ -2229,8 +2260,8 @@
       {
          if (pti != Window->spwndParent->head.pti)
          {
-            ERR("CreateWindow Parent in.\n");
-            //UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE);
+            //ERR("CreateWindow Parent in.\n");
+            UserAttachThreadInput(pti, Window->spwndParent->head.pti, TRUE);
          }
       }
    }
@@ -2244,15 +2275,20 @@
    }
 
    /* Send the WM_NCCALCSIZE message */
+   {
+  // RECT rc;
    MaxPos.x = Window->rcWindow.left;
    MaxPos.y = Window->rcWindow.top;
 
    Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient);
+   //rc = Window->rcWindow;
+   //Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM)&rc);
+   //Window->rcClient = rc;
 
    RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left,
                                      MaxPos.y - Window->rcWindow.top);
+   }
 
-
    /* Send the WM_CREATE message. */
    Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs);
    if (Result == (LRESULT)-1)
@@ -2570,8 +2606,8 @@
       {
          if (Window->spwndOwner)
          {
-            ERR("DestroyWindow Owner out.\n");
-            //UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE);
+            //ERR("DestroyWindow Owner out.\n");
+            UserAttachThreadInput(Window->head.pti, Window->spwndOwner->head.pti, FALSE);
          }
       }
    }
@@ -2609,8 +2645,8 @@
       {
          if (!IntIsTopLevelWindow(Window))
          {
-            ERR("DestroyWindow Parent out.\n");
-            //UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE);
+            //ERR("DestroyWindow Parent out.\n");
+            UserAttachThreadInput(Window->head.pti, Window->spwndParent->head.pti, FALSE);
          }
       }
    }
@@ -3556,6 +3592,12 @@
             else
                Window->ExStyle &= ~WS_EX_WINDOWEDGE;
 
+            if ((Style.styleOld ^ Style.styleNew) & WS_VISIBLE)
+            {
+               if (Style.styleOld & WS_VISIBLE) Window->head.pti->cVisWindows--;
+               if (Style.styleNew & WS_VISIBLE) Window->head.pti->cVisWindows++;
+               DceResetActiveDCEs( Window );
+            }
             Window->style = (DWORD)Style.styleNew;
             co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
             break;
Index: win32ss/user/ntuser/desktop.c
===================================================================
--- win32ss/user/ntuser/desktop.c	(revision 59990)
+++ win32ss/user/ntuser/desktop.c	(working copy)
@@ -28,7 +28,7 @@
 /* Currently active desktop */
 PDESKTOP gpdeskInputDesktop = NULL;
 HDC ScreenDeviceContext = NULL;
-PTHREADINFO gptiDesktopThread;
+PTHREADINFO gptiDesktopThread = NULL;
 HCURSOR gDesktopCursor = NULL;
 
 /* OBJECT CALLBACKS **********************************************************/
Index: win32ss/user/ntuser/desktop.h
===================================================================
--- win32ss/user/ntuser/desktop.h	(revision 59990)
+++ win32ss/user/ntuser/desktop.h	(working copy)
@@ -69,9 +69,10 @@
                             DESKTOP_SWITCHDESKTOP    | \
                             DESKTOP_WRITEOBJECTS
 
-extern PDESKTOP InputDesktop;
+extern PDESKTOP gpdeskInputDesktop;
 extern PCLS DesktopWindowClass;
 extern HDC ScreenDeviceContext;
+extern PTHREADINFO gptiForeground;
 extern PTHREADINFO gptiDesktopThread;
 
 typedef struct _SHELL_HOOK_WINDOW
Index: win32ss/user/ntuser/winpos.c
===================================================================
--- win32ss/user/ntuser/winpos.c	(revision 59990)
+++ win32ss/user/ntuser/winpos.c	(working copy)
@@ -237,6 +237,7 @@
              if (!(pWndSetActive->ExStyle & WS_EX_TOOLWINDOW) )
              {
                 UserRefObjectCo(pWndSetActive, &Ref);
+                //ERR("ActivateOtherWindowMin Set FG 1\n");
                 co_IntSetForegroundWindow(pWndSetActive);
                 UserDerefObjectCo(pWndSetActive);
                 //ERR("AOWM 2 Exit Good\n");
@@ -273,6 +274,7 @@
     if ((pWndSetActive = pWndTemp))
     {
        UserRefObjectCo(pWndSetActive, &Ref);
+       //ERR("ActivateOtherWindowMin Set FG 2\n");
        co_IntSetForegroundWindow(pWndSetActive);
        UserDerefObjectCo(pWndSetActive);
        //ERR("AOWM 3 Exit Good\n");
@@ -299,7 +301,7 @@
     if (style & WS_MINIMIZE) return FALSE;
     if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
     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. */
     //return !(style & WS_DISABLED);
 }
@@ -314,7 +316,6 @@
 co_WinPosActivateOtherWindow(PWND Wnd)
 {
    PWND WndTo = NULL;
-   HWND Fg, previous;
    USER_REFERENCE_ENTRY Ref;
 
    ASSERT_REFS_CO(Wnd);
@@ -345,26 +346,24 @@
 
    if (WndTo) UserRefObjectCo(WndTo, &Ref);
 
-   Fg = UserGetForegroundWindow();
-   if ((!Fg || Wnd->head.h == Fg) && WndTo) // FIXME: Ok if WndTo is NULL?? No, rule #4.
+   if (!gpqForeground || Wnd == gpqForeground->spwndActive)
    {
-      /* FIXME: Wine can pass WndTo = NULL to co_IntSetForegroundWindow. Hmm... */
+      /* ReactOS can pass WndTo = NULL to co_IntSetForegroundWindow and returns FALSE. */
+      //ERR("WinPosActivateOtherWindow Set FG 0x%p\n",WndTo);
       if (co_IntSetForegroundWindow(WndTo))
       {
-         UserDerefObjectCo(WndTo);
+         if (WndTo) UserDerefObjectCo(WndTo);
          return;
       }
    }
-
-   if (!co_IntSetActiveWindow(WndTo,&previous,FALSE,TRUE,FALSE) ||  /* Ok for WndTo to be NULL here */
-       !previous)
+   //ERR("WinPosActivateOtherWindow Set Active  0x%p\n",WndTo);
+   if (!co_IntSetActiveWindow(WndTo,FALSE,TRUE,FALSE))  /* Ok for WndTo to be NULL here */
    {
-      co_IntSetActiveWindow(0,NULL,FALSE,TRUE,FALSE);
+      co_IntSetActiveWindow(0,FALSE,TRUE,FALSE);
    }
    if (WndTo) UserDerefObjectCo(WndTo);
 }
 
-
 UINT
 FASTCALL
 co_WinPosArrangeIconicWindows(PWND parent)
@@ -1131,11 +1130,71 @@
       ClientRect->bottom = WindowRect->bottom;
    }
 }
+/***********************************************************************
+ *           get_valid_rects
+ *
+ * Compute the valid rects from the old and new client rect and WVR_* flags.
+ * Helper for WM_NCCALCSIZE handling.
+ */
+static
+VOID FASTCALL
+get_valid_rects( RECTL *old_client, RECTL *new_client, UINT flags, RECTL *valid )
+{
+    int cx, cy;
 
+    if (flags & WVR_REDRAW)
+    {
+        RECTL_vSetEmptyRect( &valid[0] );
+        RECTL_vSetEmptyRect( &valid[1] );
+        return;
+    }
+
+    if (flags & WVR_VALIDRECTS)
+    {
+        if (!RECTL_bIntersectRect( &valid[0], &valid[0], new_client ) ||
+            !RECTL_bIntersectRect( &valid[1], &valid[1], old_client ))
+        {
+            RECTL_vSetEmptyRect( &valid[0] );
+            RECTL_vSetEmptyRect( &valid[1] );
+            return;
+        }
+        flags = WVR_ALIGNLEFT | WVR_ALIGNTOP;
+    }
+    else
+    {
+        valid[0] = *new_client;
+        valid[1] = *old_client;
+    }
+
+    /* make sure the rectangles have the same size */
+    cx = min( valid[0].right - valid[0].left, valid[1].right - valid[1].left );
+    cy = min( valid[0].bottom - valid[0].top, valid[1].bottom - valid[1].top );
+
+    if (flags & WVR_ALIGNBOTTOM)
+    {
+        valid[0].top = valid[0].bottom - cy;
+        valid[1].top = valid[1].bottom - cy;
+    }
+    else
+    {
+        valid[0].bottom = valid[0].top + cy;
+        valid[1].bottom = valid[1].top + cy;
+    }
+    if (flags & WVR_ALIGNRIGHT)
+    {
+        valid[0].left = valid[0].right - cx;
+        valid[1].left = valid[1].right - cx;
+    }
+    else
+    {
+        valid[0].right = valid[0].left + cx;
+        valid[1].right = valid[1].left + cx;
+    }
+}
+
 static
 LONG FASTCALL
-co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
-                      RECT* WindowRect, RECT* ClientRect)
+co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos, RECTL* WindowRect, RECTL* ClientRect, RECTL* validRects)
 {
    PWND Parent;
    UINT wvrFlags = 0;
@@ -1148,9 +1207,10 @@
       NCCALCSIZE_PARAMS params;
       WINDOWPOS winposCopy;
 
-      params.rgrc[0] = *WindowRect;
-      params.rgrc[1] = Window->rcWindow;
-      params.rgrc[2] = Window->rcClient;
+      params.rgrc[0] = *WindowRect;      // new coordinates of a window that has been moved or resized
+      params.rgrc[1] = Window->rcWindow; // window before it was moved or resized
+      params.rgrc[2] = Window->rcClient; // client area before the window was moved or resized
+
       Parent = Window->spwndParent;
       if (0 != (Window->style & WS_CHILD) && Parent)
       {
@@ -1161,6 +1221,7 @@
          RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->rcClient.left,
                           - Parent->rcClient.top);
       }
+
       params.lppos = &winposCopy;
       winposCopy = *WinPos;
 
@@ -1170,7 +1231,7 @@
       if (params.rgrc[0].left <= params.rgrc[0].right &&
           params.rgrc[0].top <= params.rgrc[0].bottom)
       {
-         *ClientRect = params.rgrc[0];
+         *ClientRect = params.rgrc[0]; // First rectangle contains the coordinates of the new client rectangle resulting from the move or resize
          if ((Window->style & WS_CHILD) && Parent)
          {
             RECTL_vOffsetRect(ClientRect, Parent->rcClient.left,
@@ -1179,21 +1240,30 @@
          FixClientRect(ClientRect, WindowRect);
       }
 
-      /* FIXME: WVR_ALIGNxxx */
-
       if (ClientRect->left != Window->rcClient.left ||
           ClientRect->top != Window->rcClient.top)
       {
          WinPos->flags &= ~SWP_NOCLIENTMOVE;
       }
 
-      if ((ClientRect->right - ClientRect->left !=
-            Window->rcClient.right - Window->rcClient.left) ||
-          (ClientRect->bottom - ClientRect->top !=
-            Window->rcClient.bottom - Window->rcClient.top))
+      if (ClientRect->right - ClientRect->left !=
+          Window->rcClient.right - Window->rcClient.left)
       {
          WinPos->flags &= ~SWP_NOCLIENTSIZE;
       }
+      else
+         wvrFlags &= ~WVR_HREDRAW;
+
+      if (ClientRect->bottom - ClientRect->top !=
+          Window->rcClient.bottom - Window->rcClient.top)
+      {
+         WinPos->flags &= ~SWP_NOCLIENTSIZE;
+      }
+      else
+         wvrFlags &= ~WVR_VREDRAW;
+
+      validRects[0] = params.rgrc[1]; // second rectangle contains the valid destination rectangle
+      validRects[1] = params.rgrc[2]; // third rectangle contains the valid source rectangle
    }
    else
    {
@@ -1205,6 +1275,13 @@
       }
    }
 
+   if (WinPos->flags & (SWP_NOCOPYBITS | SWP_NOREDRAW | SWP_SHOWWINDOW | SWP_HIDEWINDOW))
+   {
+      RECTL_vSetEmptyRect( &validRects[0] );
+      RECTL_vSetEmptyRect( &validRects[1] );
+   }
+   else get_valid_rects( &Window->rcClient, ClientRect, wvrFlags, validRects );
+
    return wvrFlags;
 }
 
@@ -1215,16 +1292,47 @@
                           PRECTL WindowRect,
                           PRECTL ClientRect)
 {
-   INT X, Y;
-
    ASSERT_REFS_CO(Window);
 
+   /* Send WM_WINDOWPOSCHANGING message */
+
    if (!(WinPos->flags & SWP_NOSENDCHANGING))
    {
       co_IntSendMessageNoWait(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
    }
 
+   /* Calculate new position and size */
+
    *WindowRect = Window->rcWindow;
+   *ClientRect = (Window->style & WS_MINIMIZE) ? Window->rcWindow : Window->rcClient;
+
+   if (!(WinPos->flags & SWP_NOSIZE))
+   {
+      if (Window->style & WS_MINIMIZE)
+      {
+         WindowRect->right  = WindowRect->left + UserGetSystemMetrics(SM_CXICON);
+         WindowRect->bottom = WindowRect->top + UserGetSystemMetrics(SM_CYICON);
+      }
+      else
+      {
+         WindowRect->right = WindowRect->left + WinPos->cx;
+         WindowRect->bottom = WindowRect->top + WinPos->cy;
+      }
+   }
+#if 0
+   if (!(WinPos->flags & SWP_NOMOVE))
+   {
+      WindowRect->left    = WinPos->x;
+      WindowRect->top     = WinPos->y;
+      WindowRect->right  += WinPos->x - Window->rcWindow.left;
+      WindowRect->bottom += WinPos->y - Window->rcWindow.top;
+      RECTL_vOffsetRect(ClientRect,
+                        WinPos->x - Window->rcWindow.left,
+                        WinPos->y - Window->rcWindow.top);
+
+   }
+
+   *WindowRect = Window->rcWindow;
    *ClientRect = Window->rcClient;
 
    if (!(WinPos->flags & SWP_NOSIZE))
@@ -1232,22 +1340,26 @@
       WindowRect->right = WindowRect->left + WinPos->cx;
       WindowRect->bottom = WindowRect->top + WinPos->cy;
    }
-
+#endif
    if (!(WinPos->flags & SWP_NOMOVE))
    {
+      INT X, Y;
       PWND Parent;
       X = WinPos->x;
       Y = WinPos->y;
+      //ERR("Not SWP_NOMOVE\n");
       Parent = Window->spwndParent;
-      if ((0 != (Window->style & WS_CHILD)) && Parent)
+      if ((0 != (Window->style & WS_CHILD)) && Parent &&
+          Parent != Window->head.rpdesk->pDeskInfo->spwnd)
       {
+         //ERR("Not SWP_NOMOVE Parent client offset\n");
          X += Parent->rcClient.left;
          Y += Parent->rcClient.top;
       }
 
-      WindowRect->left = X;
-      WindowRect->top = Y;
-      WindowRect->right += X - Window->rcWindow.left;
+      WindowRect->left    = X;
+      WindowRect->top     = Y;
+      WindowRect->right  += X - Window->rcWindow.left;
       WindowRect->bottom += Y - Window->rcWindow.top;
       RECTL_vOffsetRect(ClientRect,
                        X - Window->rcWindow.left,
@@ -1256,6 +1368,10 @@
 
    WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
 
+   TRACE( "hwnd %p, after %p, swp %d,%d %dx%d flags %08x\n",
+           WinPos->hwnd, WinPos->hwndInsertAfter, WinPos->x, WinPos->y,
+           WinPos->cx, WinPos->cy, WinPos->flags );
+
    return TRUE;
 }
 
@@ -1396,6 +1512,21 @@
 BOOL FASTCALL
 WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
 {
+   PWND Parent;
+   POINT pt;
+
+   /* Finally make sure that all coordinates are valid */
+   if (WinPos->x < -32768) WinPos->x = -32768;   
+   else if (WinPos->x > 32767) WinPos->x = 32767;
+   if (WinPos->y < -32768) WinPos->y = -32768;   
+   else if (WinPos->y > 32767) WinPos->y = 32767;
+
+   WinPos->cx = max(WinPos->cx, 0);
+   WinPos->cy = max(WinPos->cy, 0);
+
+   Parent = UserGetAncestor( Wnd, GA_PARENT );
+   if (!IntIsWindowVisible( Parent )) WinPos->flags |= SWP_NOREDRAW;
+
    if (Wnd->style & WS_VISIBLE)
    {
       WinPos->flags &= ~SWP_SHOWWINDOW;
@@ -1407,9 +1538,6 @@
          WinPos->flags |= SWP_NOREDRAW;
    }
 
-   WinPos->cx = max(WinPos->cx, 0);
-   WinPos->cy = max(WinPos->cy, 0);
-
    /* Check for right size */
    if (Wnd->rcWindow.right - Wnd->rcWindow.left == WinPos->cx &&
        Wnd->rcWindow.bottom - Wnd->rcWindow.top == WinPos->cy)
@@ -1417,10 +1545,15 @@
       WinPos->flags |= SWP_NOSIZE;
    }
 
+   pt.x = WinPos->x;
+   pt.y = WinPos->y;
+   IntClientToScreen( Parent, &pt );
+//   ERR("WPFU C2S wpx %d wpy %d ptx %d pty %d\n",WinPos->x,WinPos->y,pt.x,pt.y);
    /* Check for right position */
-   if (Wnd->rcWindow.left == WinPos->x &&
-       Wnd->rcWindow.top == WinPos->y)
+   if (Wnd->rcWindow.left == pt.x &&
+       Wnd->rcWindow.top == pt.y)
    {
+//      ERR("In right pos\n");
       WinPos->flags |= SWP_NOMOVE;
    }
 
@@ -1526,6 +1659,7 @@
    WINDOWPOS WinPos;
    RECTL NewWindowRect;
    RECTL NewClientRect;
+   RECTL valid_rects[2];
    PROSRGNDATA VisRgn;
    HRGN VisBefore = NULL;
    HRGN VisAfter = NULL;
@@ -1543,7 +1677,7 @@
 
    ASSERT_REFS_CO(Window);
 
-   /* FIXME: Get current active window from active queue. */
+   /* FIXME: Get current active window from active queue. Why? since r2915. */
 
    bPointerInWindow = IntPtInWindow(Window, gpsi->ptCursor.x, gpsi->ptCursor.y);
 
@@ -1555,6 +1689,27 @@
    WinPos.cy = cy;
    WinPos.flags = flags;
 
+   if ( flags & SWP_ASYNCWINDOWPOS )
+   {
+      LRESULT lRes;
+      PWINDOWPOS ppos = ExAllocatePoolWithTag(PagedPool, sizeof(WINDOWPOS), USERTAG_SWP);
+      if ( ppos )
+      {
+         WinPos.flags &= ~SWP_ASYNCWINDOWPOS; // Clear flag.
+         *ppos = WinPos;
+         /* Yes it's a pointer inside Win32k! */
+         lRes = co_IntSendMessageNoWait( WinPos.hwnd, WM_ASYNC_SETWINDOWPOS, 0, (LPARAM)ppos);
+         /* We handle this the same way as Event Hooks and Hooks. */
+         if ( !lRes )
+         {
+            ExFreePoolWithTag(ppos, USERTAG_SWP);
+            return FALSE;
+         }
+         return TRUE;
+      }
+      return FALSE;
+   }
+
    co_WinPosDoWinPosChanging(Window, &WinPos, &NewWindowRect, &NewClientRect);
 
    // HWND_NOTOPMOST is redirected in WinPosFixupFlags.
@@ -1610,9 +1765,11 @@
       }
    }
 
-   WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect);
+   WvrFlags = co_WinPosDoNCCALCSize(Window, &WinPos, &NewWindowRect, &NewClientRect, valid_rects);
 
-   TRACE("co_WinPosDoNCCALCSize returned %lu\n", WvrFlags);
+//   ERR("co_WinPosDoNCCALCSize returned 0x%x\n valid dest: %d %d %d %d\n valid src : %d %d %d %d\n", WvrFlags,
+//      valid_rects[0].left,valid_rects[0].top,valid_rects[0].right,valid_rects[0].bottom,
+//      valid_rects[1].left,valid_rects[1].top,valid_rects[1].right,valid_rects[1].bottom);
 
    /* Validate link windows. (also take into account shell window in hwndShellWindow) */
    if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow())
@@ -1624,6 +1781,7 @@
 
       if ((ParentWindow = Window->spwndParent)) // Must have a Parent window!
       {
+         //ERR("SetWindowPos has parent window.\n");
          if (WinPos.hwndInsertAfter == HWND_TOPMOST)
          {
             InsertAfterWindow = NULL;
@@ -1682,21 +1840,9 @@
 
    OldWindowRect = Window->rcWindow;
    OldClientRect = Window->rcClient;
+   //ERR("SetWindowPos OldWindowRect: %d %d %d %d\n", OldWindowRect.left,OldWindowRect.top,OldWindowRect.right,OldWindowRect.bottom);
+   //ERR("SetWindowPos OldClientRect: %d %d %d %d\n", OldClientRect.left,OldClientRect.top,OldClientRect.right,OldClientRect.bottom);
 
-   if (OldClientRect.bottom - OldClientRect.top ==
-         NewClientRect.bottom - NewClientRect.top)
-   {
-      WvrFlags &= ~WVR_VREDRAW;
-   }
-
-   if (OldClientRect.right - OldClientRect.left ==
-         NewClientRect.right - NewClientRect.left)
-   {
-      WvrFlags &= ~WVR_HREDRAW;
-   }
-
-   /* FIXME: Actually do something with WVR_VALIDRECTS */
-
    if (NewClientRect.left != OldClientRect.left ||
        NewClientRect.top  != OldClientRect.top)
    {
@@ -1708,6 +1854,9 @@
    Window->rcWindow = NewWindowRect;
    Window->rcClient = NewClientRect;
 
+   //ERR("SetWindowPos NewWindowRect: %d %d %d %d\n", NewWindowRect.left,NewWindowRect.top,NewWindowRect.right,NewWindowRect.bottom);
+   //ERR("SetWindowPos NewClientRect: %d %d %d %d\n", NewClientRect.left,NewClientRect.top,NewClientRect.right,NewClientRect.bottom);
+
    /* erase parent when hiding or resizing child */
    if (WinPos.flags & SWP_HIDEWINDOW)
    {
@@ -1721,6 +1870,7 @@
          co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (WPARAM)Window->head.h, 0);
 
       Window->style &= ~WS_VISIBLE; //IntSetStyle( Window, 0, WS_VISIBLE );
+      Window->head.pti->cVisWindows--;
       IntNotifyWinEvent(EVENT_OBJECT_HIDE, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
    }
    else if (WinPos.flags & SWP_SHOWWINDOW)
@@ -1729,6 +1879,7 @@
          co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)Window->head.h, 0);
 
       Window->style |= WS_VISIBLE; //IntSetStyle( Window, WS_VISIBLE, 0 );
+      Window->head.pti->cVisWindows++;
       IntNotifyWinEvent(EVENT_OBJECT_SHOW, Window, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
    }
 
@@ -1955,7 +2106,10 @@
       else
       {
          //ERR("SetWindowPos Set FG Window!\n");
-         co_IntSetForegroundWindow(Window);
+         if (Window->state & WNDS_BEINGACTIVATED) // Inside SAW?
+            co_IntSetActiveWindow(Window, FALSE, TRUE, FALSE); // Fixes Api AttachThreadInput tests.
+         else
+            co_IntSetForegroundWindow(Window); // Fixes SW_HIDE issues. Wine win test_SetActiveWindow & test_SetForegroundWindow.
       }
    }
 
@@ -2036,7 +2190,7 @@
 
     co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_SIZE, wParam, lParam);
 
-    if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid != FNID_DESKTOP )
+    if (Wnd->spwndParent == UserGetDesktopWindow()) // Wnd->spwndParent->fnid == FNID_DESKTOP )
        lParam = MAKELONG(Wnd->rcClient.left, Wnd->rcClient.top);
     else
        lParam = MAKELONG(Wnd->rcClient.left-Wnd->spwndParent->rcClient.left, Wnd->rcClient.top-Wnd->spwndParent->rcClient.top);
@@ -2056,9 +2210,9 @@
    LONG style;
    PWND Parent;
    PTHREADINFO pti;
-   //  BOOL ShowOwned = FALSE;
    //  HRGN VisibleRgn;
-
+   //ERR("co_WinPosShowWindow START\n");
+   BOOL ShowOwned = FALSE;
    ASSERT_REFS_CO(Wnd);
 
    pti = PsGetCurrentThreadWin32Thread();
@@ -2071,6 +2225,7 @@
          {
             if (!WasVisible)
             {
+               //ERR("co_WinPosShowWindow Exit Bad\n");
                return(FALSE);
             }
             Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
@@ -2091,11 +2246,12 @@
             Swp |= SWP_NOACTIVATE;
             if (!(style & WS_MINIMIZE))
             {
-               //IntShowOwnedPopups(Wnd, FALSE );
+               IntShowOwnedPopups(Wnd, FALSE );
 
                // Fix wine Win test_SetFocus todo #1 & #2,
                if (Cmd == SW_SHOWMINIMIZED)
                {
+                  //ERR("co_WinPosShowWindow Set focus 1\n");
                   if ((style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
                      co_UserSetFocus(Wnd->spwndParent);
                   else
@@ -2114,7 +2270,10 @@
                   Swp |= SWP_FRAMECHANGED;
                }
                else ////
+               {
+                  //ERR("co_WinPosShowWindow Exit Good\n");
                   return TRUE;
+               }
                Swp |= SWP_NOSIZE | SWP_NOMOVE;
             }
             break;
@@ -2125,7 +2284,7 @@
             Swp |= SWP_SHOWWINDOW;
             if (!(style & WS_MAXIMIZE))
             {
-               //ShowOwned = TRUE;
+               ShowOwned = TRUE;
 
                Swp |= co_WinPosMinMaximize(Wnd, SW_MAXIMIZE, &NewPos) |
                       SWP_FRAMECHANGED;
@@ -2139,7 +2298,10 @@
                   Swp |= SWP_FRAMECHANGED;
                }
                else ////
+               {
+                  //ERR("co_WinPosShowWindow Exit Good 1\n");
                   return TRUE;
+               }
                Swp |= SWP_NOSIZE | SWP_NOMOVE;
             }
             break;
@@ -2177,7 +2339,10 @@
                Swp |= SWP_FRAMECHANGED;
             }
             else ////
+            {
+               //ERR("co_WinPosShowWindow Exit Good 3\n");
                return TRUE;
+            }
             Swp |= SWP_NOSIZE | SWP_NOMOVE;
          }
          if ( style & WS_CHILD &&
@@ -2187,6 +2352,7 @@
          break;
 
       default:
+         //ERR("co_WinPosShowWindow Exit Good 4\n");
          return WasVisible;
    }
 
@@ -2214,7 +2380,8 @@
         Wnd->pcls->style & CS_SAVEBITS &&
         ((Cmd == SW_SHOW) || (Cmd == SW_NORMAL)))
    {
-      co_IntSetActiveWindow(Wnd,NULL,FALSE,TRUE,FALSE);
+      ERR("WinPosShowWindow Set active\n");
+      UserSetActiveWindow(Wnd);
       Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
    }
 #endif
@@ -2242,7 +2409,7 @@
 
    if ( EventMsg ) IntNotifyWinEvent(EventMsg, Wnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
 
-   //if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE );
+   if ( ShowOwned ) IntShowOwnedPopups(Wnd, TRUE );
 
    if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE))
    {
@@ -2281,6 +2448,7 @@
       // Fix wine Win test_SetFocus todo #3,
       if (!(style & WS_CHILD)) co_IntSendMessageNoWait(UserHMGetHandle(Wnd), WM_ACTIVATE, WA_ACTIVE, 0);
    }
+   //ERR("co_WinPosShowWindow EXIT\n");
    return(WasVisible);
 }
 
Index: win32ss/user/ntuser/focus.c
===================================================================
--- win32ss/user/ntuser/focus.c	(revision 59990)
+++ win32ss/user/ntuser/focus.c	(working copy)
@@ -80,7 +80,7 @@
 co_IntMakeWindowActive(PWND Window)
 {
   PWND spwndOwner;
-  if (Window)
+  if (VerifyWnd(Window))
   {  // Set last active for window and it's owner.
      spwndOwner = Window;
      while (spwndOwner->spwndOwner)
@@ -132,6 +132,7 @@
             {
                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);
             }
          }
@@ -156,8 +157,7 @@
             if ( OldTID )
             {
                ptiOld->TIF_flags |= TIF_INACTIVATEAPPMSG;
-               ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags;
-
+               // Note: Do not set pci flags, this does crash!
                for (phWnd = List; *phWnd; ++phWnd)
                {
                   cWindow = ValidateHwndNoErr(*phWnd);
@@ -168,13 +168,11 @@
                   }
                }
                ptiOld->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
-               ptiOld->pClientInfo->dwTIFlags = ptiOld->TIF_flags;
             }
             if ( NewTID )
             {  //// Prevents a resource crash due to reentrance!
                InAAPM = TRUE;
                pti->TIF_flags |= TIF_INACTIVATEAPPMSG;
-               pti->pClientInfo->dwTIFlags = pti->TIF_flags;
                ////
                for (phWnd = List; *phWnd; ++phWnd)
                {
@@ -186,7 +184,7 @@
                   }
                }
             }
-            ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
+            ExFreePool(List);//ExFreePoolWithTag(List, USERTAG_WINDOWLIST);
          }
       }
       if (WindowPrev)
@@ -205,12 +203,11 @@
 
       co_IntMakeWindowActive(Window);
 
-      UserDerefObjectCo(Window);
+      /* FIXME: IntIsWindow */
 
-      /* FIXME: IntIsWindow */
       co_IntSendMessageNoWait( UserHMGetHandle(Window),
                                WM_NCACTIVATE,
-                              (WPARAM)(gpqForeground ? (Window == gpqForeground->spwndActive) : FALSE),
+                              (WPARAM)(Window == (gpqForeground ? gpqForeground->spwndActive : NULL)),
                                0); //(LPARAM)hWndPrev);
 
       co_IntSendMessageNoWait( UserHMGetHandle(Window),
@@ -226,6 +223,7 @@
 
       Window->state &= ~WNDS_NONCPAINT;
 
+      UserDerefObjectCo(Window);
    }
    return InAAPM;
 }
@@ -294,7 +292,7 @@
 }
 
 VOID FASTCALL
-FindRemoveAsyncMsg(PWND Wnd)
+FindRemoveAsyncMsg(PWND Wnd, WPARAM wParam)
 {
    PTHREADINFO pti;
    PUSER_SENT_MESSAGE Message;
@@ -311,20 +309,60 @@
       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 != &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.
  */
@@ -339,6 +377,7 @@
         gppiInputProvider == ppi ||
        !gpqForeground
       ) return TRUE;
+   //ERR("CanForceFG is FALSE\n");
    return FALSE;
 }
 
@@ -356,37 +395,35 @@
     * The foreground lock time-out has expired (see SPI_GETFOREGROUNDLOCKTIMEOUT in SystemParametersInfo).
     * No menus are active.
 */
-
-static BOOL FASTCALL
+static
+BOOL FASTCALL
 co_IntSetForegroundAndFocusWindow(
     _In_ PWND Wnd,
     _In_ BOOL MouseActivate)
 {
-   HWND hWnd;
+   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);
-   NT_ASSERT(Wnd != NULL);
+   if (Wnd) ASSERT_REFS_CO(Wnd);
 
-   hWnd = UserHMGetHandle(Wnd);
+   //ERR("SetForegroundAndFocusWindow(%x, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
 
-   TRACE("SetForegroundAndFocusWindow(%p, %s)\n", hWnd, (MouseActivate ? "TRUE" : "FALSE"));
-
    PrevForegroundQueue = IntGetFocusMessageQueue(); // Use this active desktop.
    pti = PsGetCurrentThreadWin32Thread();
 
    if (PrevForegroundQueue)
    {  // Same Window Q as foreground just do active.
-      //ERR("Same Window Q as foreground just do active.\n");
       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.
             //ERR("Same WQ and TQ go active.\n");
-            Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE);
+            Ret = co_IntSetActiveWindow(Wnd, MouseActivate, TRUE, FALSE);
          }
          else if (Wnd->head.pti->MessageQueue->spwndActive == Wnd)
          { // Same WQ and it is active.
@@ -395,14 +432,15 @@
          }
          else
          { // Same WQ as FG but not the same TQ send active.
-            //ERR("Same WQ as FG but not the same TQ send active.\n");
-            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 ) &&
@@ -410,16 +448,29 @@
         pti->ppi == ppiScrnSaver
       )
    {
-      IntSetFocusMessageQueue(Wnd->head.pti->MessageQueue);
-      gptiForeground = Wnd->head.pti;
-      TRACE("Set Foreground pti 0x%p Q 0x%p\n",Wnd->head.pti, Wnd->head.pti->MessageQueue);
+
+      //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;
    }
 
@@ -428,34 +479,41 @@
    {
       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, FALSE);
+            co_IntSetActiveWindow(NULL, FALSE, TRUE, FALSE);
          }
-         else
-         co_IntSendMessageNoWait(hWndPrev, WM_ASYNC_SETACTIVEWINDOW, 0, 0 );
+         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 );
+         }
       }
    }
 
+   if (!Wnd) return FALSE; // Always return false.
+
    if (pti->MessageQueue == Wnd->head.pti->MessageQueue)
    {
-       Ret = co_IntSetActiveWindow(Wnd, NULL, MouseActivate, TRUE, FALSE);
+       //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;
 }
 
@@ -500,7 +558,7 @@
 }
 
 BOOL FASTCALL
-co_IntSetActiveWindow(PWND Wnd OPTIONAL, HWND * Prev, BOOL bMouse, BOOL bFocus, BOOL Async)
+co_IntSetActiveWindow(PWND Wnd OPTIONAL, BOOL bMouse, BOOL bFocus, BOOL Async)
 {
    PTHREADINFO pti;
    PUSER_MESSAGE_QUEUE ThreadQueue;
@@ -509,38 +567,83 @@
    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;
 
    pWndChg = ThreadQueue->spwndActive; // Keep to notify of a preemptive switch.
 
-   if (Wnd)
+   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 */
@@ -562,14 +665,16 @@
    if (WndPrev)
    {
       if (ThreadQueue == gpqForeground) gpqForegroundPrev = ThreadQueue;
-      if (!co_IntSendDeactivateMessages(hWndPrev, hWnd)) return FALSE;
+      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 != ThreadQueue->spwndActive ||
+        pWndChg != WndPrev ||
         (Wnd && !VerifyWnd(Wnd)) ||
         ThreadQueue != pti->MessageQueue )
    {
@@ -582,6 +687,8 @@
    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)
@@ -590,6 +697,8 @@
       ThreadQueue->spwndActive = Wnd;
    }
 
+   WndPrev = VerifyWnd(ThreadQueue->spwndActivePrev); // Now should be set but verify it again.
+
    InAAPM = co_IntSendActivateMessages(WndPrev, Wnd, bMouse, Async);
 
    /* now change focus if necessary */
@@ -610,16 +719,40 @@
    if (InAAPM)
    {
       pti->TIF_flags &= ~TIF_INACTIVATEAPPMSG;
-      pti->pClientInfo->dwTIFlags = pti->TIF_flags;
    }
 
    // FIXME: Used in the menu loop!!!
    //ThreadQueue->QF_flags |= QF_ACTIVATIONCHANGE;
 
+   //ERR("co_IntSetActiveWindow Exit\n");
    if (Wnd) Wnd->state &= ~WNDS_BEINGACTIVATED;
    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
 co_UserSetFocus(PWND Window)
 {
@@ -653,17 +786,10 @@
       }
 
       /* Check if we can set the focus to this window */
-      pwndTop = Window;
-      for (;;)
+      for (pwndTop = Window; pwndTop != NULL; 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))
@@ -676,8 +802,13 @@
       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");
@@ -688,7 +819,8 @@
          /* Set Active when it is needed. */
          if (pwndTop != ThreadQueue->spwndActive)
          {
-            if (!co_IntSetActiveWindow(pwndTop, NULL, FALSE, FALSE, FALSE))
+            //ERR("SetFocus: Set Active!\n");
+            if (!co_IntSetActiveWindow(pwndTop, FALSE, FALSE, FALSE))
             {
                ERR("SetFocus: Set Active Failed!\n");
                return 0;
@@ -714,8 +846,6 @@
    }
    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("SetFocus: 2 WH_CBT Call Hook return!\n");
@@ -857,7 +987,7 @@
 BOOL FASTCALL
 co_IntSetForegroundWindow(PWND Window)
 {
-   ASSERT_REFS_CO(Window);
+   if (Window) ASSERT_REFS_CO(Window);
 
    return co_IntSetForegroundAndFocusWindow(Window, FALSE);
 }
@@ -942,7 +1072,7 @@
    else
    {  // Rule #3, last input event in force.
       ERR("Fixme: ptiLastInput is SET!!\n");
-      //ptiLastInput = ppi->ptiList;
+      //ptiLastInput = ppi->ptiList; See CORE-6384 & CORE-7030.
       ObDereferenceObject(Process);
    }
    return TRUE;
@@ -962,7 +1092,7 @@
    RETURN( UserGetForegroundWindow());
 
 CLEANUP:
-   TRACE("Leave NtUserGetForegroundWindow, ret=%p\n", _ret_);
+   TRACE("Leave NtUserGetForegroundWindow, ret=%p\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -993,7 +1123,7 @@
    {
       hWndPrev = gptiCurrent->MessageQueue->spwndActive ? UserHMGetHandle(gptiCurrent->MessageQueue->spwndActive) : NULL;
       if (Window) UserRefObjectCo(Window, &Ref);
-      co_IntSetActiveWindow(Window, NULL, FALSE, TRUE, FALSE);
+      UserSetActiveWindow(Window);
       if (Window) UserDerefObjectCo(Window);
       RETURN( hWndPrev ? (IntIsWindow(hWndPrev) ? hWndPrev : 0) : 0 );
    }
Index: win32ss/user/ntuser/main.c
===================================================================
--- win32ss/user/ntuser/main.c	(revision 59990)
+++ win32ss/user/ntuser/main.c	(working copy)
@@ -154,6 +154,9 @@
            ppiCurrent->W32PF_flags |= W32PF_SCREENSAVER;
         }
 
+        // Fixme check if this process is allowed.
+        ppiCurrent->W32PF_flags |= W32PF_ALLOWFOREGROUNDACTIVATE; // Starting application it will get toggled off.
+
         /* Create pools for GDI object attributes */
         ppiCurrent->pPoolDcAttr = GdiPoolCreate(sizeof(DC_ATTR), 'acdG');
         ppiCurrent->pPoolBrushAttr = GdiPoolCreate(sizeof(BRUSH_ATTR), 'arbG');
@@ -275,14 +278,17 @@
 
     RtlZeroMemory(ptiCurrent, sizeof(THREADINFO));
 
+    /* Initialize the THREADINFO */
+
     PsSetThreadWin32Thread(Thread, ptiCurrent);
+    IntReferenceThreadInfo(ptiCurrent);
+    ptiCurrent->pEThread = Thread;
+    ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
     pTeb->Win32ThreadInfo = ptiCurrent;
     ptiCurrent->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
 
     TRACE_CH(UserThread, "Allocated pti 0x%p for TID %p\n", ptiCurrent, Thread->Cid.UniqueThread);
 
-    /* Initialize the THREADINFO */
-    IntReferenceThreadInfo(ptiCurrent);
     InitializeListHead(&ptiCurrent->WindowListHead);
     InitializeListHead(&ptiCurrent->W32CallbackListHead);
     InitializeListHead(&ptiCurrent->PostedMessagesListHead);
@@ -294,8 +300,6 @@
     {
         InitializeListHead(&ptiCurrent->aphkStart[i]);
     }
-    ptiCurrent->pEThread = Thread;
-    ptiCurrent->ppi = PsGetCurrentProcessWin32Process();
     ptiCurrent->ptiSibling = ptiCurrent->ppi->ptiList;
     ptiCurrent->ppi->ptiList = ptiCurrent;
     ptiCurrent->ppi->cThreads++;
@@ -307,7 +311,7 @@
     {
        goto error;
     }
-   Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
+    Status = ObReferenceObjectByHandle(ptiCurrent->hEventQueueClient, 0,
                                        ExEventObjectType, KernelMode,
                                        (PVOID*)&ptiCurrent->pEventQueueServer, NULL);
     if (!NT_SUCCESS(Status))
@@ -319,7 +323,7 @@
 
     KeQueryTickCount(&LargeTickCount);
     ptiCurrent->timeLast = LargeTickCount.u.LowPart;
-    
+
     ptiCurrent->MessageQueue = MsqCreateMessageQueue(ptiCurrent);
     if(ptiCurrent->MessageQueue == NULL)
     {
@@ -419,8 +423,14 @@
 
     /* mark the thread as fully initialized */
     ptiCurrent->TIF_flags |= TIF_GUITHREADINITIALIZED;
-    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
 
+    if (!(ptiCurrent->ppi->W32PF_flags & (W32PF_ALLOWFOREGROUNDACTIVATE | W32PF_APPSTARTING)) &&
+         (gptiForeground && gptiForeground->ppi == ptiCurrent->ppi ))
+    {
+       ptiCurrent->TIF_flags |= TIF_ALLOWFOREGROUNDACTIVATE;
+    }
+    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
+    ERR_CH(UserThread,"UserCreateW32Thread pti 0x%p\n",ptiCurrent);
     return STATUS_SUCCESS;
 
 error:
@@ -483,27 +493,10 @@
     ppiCurrent = ptiCurrent->ppi;
     ASSERT(ppiCurrent);
 
-    // ptiTo
-    if (IsThreadAttach(ptiCurrent))
-    {
-       PTHREADINFO ptiFrom = IsThreadAttach(ptiCurrent);
-       TRACE_CH(UserThread,"Attached Thread ptiTo is getting switched!\n");
-       UserAttachThreadInput(ptiFrom, ptiCurrent, FALSE);
-    }
+    IsRemoveAttachThread(ptiCurrent);
 
-    // ptiFrom
-    if (ptiCurrent->pqAttach && ptiCurrent->MessageQueue)
-    {
-       PTHREADINFO ptiTo;
-       ptiTo = ptiCurrent->MessageQueue->ptiOwner;
-       TRACE_CH(UserThread,"Attached Thread ptiFrom is getting switched!\n");
-       if (ptiTo) UserAttachThreadInput( ptiCurrent, ptiTo, FALSE);
-       else
-       {
-          // eThread maybe okay but Win32Thread already made NULL!
-          ERR_CH(UserThread,"Attached Thread ptiFrom did not switch due to ptiTo is NULL!\n");
-       }
-    }
+    ptiCurrent->TIF_flags |= TIF_DONTATTACHQUEUE;
+    ptiCurrent->pClientInfo->dwTIFlags = ptiCurrent->TIF_flags;
 
     /* Decrement thread count and check if its 0 */
     ppiCurrent->cThreads--;
@@ -553,7 +546,8 @@
 */
         co_DestroyThreadWindows(Thread);
 
-        if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling)
+        if (ppiCurrent && ppiCurrent->ptiList == ptiCurrent && !ptiCurrent->ptiSibling &&
+            ppiCurrent->W32PF_flags & W32PF_CLASSESREGISTERED)
         {
            //ERR_CH(UserThread,"DestroyProcessClasses\n");
           /* no process windows should exist at this point, or the function will assert! */
@@ -592,7 +586,7 @@
     if (ptiCurrent->KeyboardLayout)
         UserDereferenceObject(ptiCurrent->KeyboardLayout);
 
-    IntSetThreadDesktop(NULL, TRUE);
+    if (gptiForeground == ptiCurrent) gptiForeground = NULL;
 
     TRACE_CH(UserThread,"Freeing pti 0x%p\n", ptiCurrent);
 
Index: win32ss/user/ntuser/focus.h
===================================================================
--- win32ss/user/ntuser/focus.h	(revision 59990)
+++ win32ss/user/ntuser/focus.h	(working copy)
@@ -18,7 +18,8 @@
 HWND FASTCALL UserGetActiveWindow(VOID);
 BOOL FASTCALL co_IntMouseActivateWindow(PWND Window);
 BOOL FASTCALL co_IntSetForegroundWindow(PWND Window);
-BOOL FASTCALL co_IntSetActiveWindow(PWND,HWND *,BOOL,BOOL,BOOL);
 BOOL FASTCALL co_IntSetForegroundWindowMouse(PWND Window);
+BOOL FASTCALL co_IntSetActiveWindow(PWND,BOOL,BOOL,BOOL);
+BOOL FASTCALL UserSetActiveWindow(PWND Wnd);
 BOOL FASTCALL IntLockSetForegroundWindow(UINT uLockCode);
 BOOL FASTCALL IntAllowSetForegroundWindow(DWORD dwProcessId);
Index: win32ss/user/ntuser/msgqueue.c
===================================================================
--- win32ss/user/ntuser/msgqueue.c	(revision 59990)
+++ win32ss/user/ntuser/msgqueue.c	(working copy)
@@ -404,7 +404,6 @@
    {
       ERR("This Message Queue is in Destroy!\n");
    }
-
    pti->pcti->fsWakeBits |= MessageBits;
    pti->pcti->fsChangeBits |= MessageBits;
 
@@ -475,6 +474,10 @@
    {
       if (--pti->nCntsQBits[QSRosHotKey] == 0) ClrMask |= QS_HOTKEY;
    }
+   if (MessageBits & QS_EVENT)
+   {
+      if (--pti->nCntsQBits[QSRosEvent] == 0) ClrMask |= QS_EVENT;
+   }
 
    pti->pcti->fsWakeBits &= ~ClrMask;
    pti->pcti->fsChangeBits &= ~ClrMask;
@@ -506,6 +509,7 @@
 {
    LARGE_INTEGER LargeTickCount;
    MSLLHOOKSTRUCT MouseHookData;
+//   PDESKTOP pDesk;
    PWND pwnd, pwndDesktop;
    HDC hdcScreen;
    PTHREADINFO pti;
@@ -549,6 +553,7 @@
    /* Get the desktop window */
    pwndDesktop = UserGetDesktopWindow();
    if (!pwndDesktop) return;
+//   pDesk = pwndDesktop->head.rpdesk;
 
    /* Check if the mouse is captured */
    Msg->hwnd = IntGetCaptureWindow();
@@ -709,7 +714,7 @@
 }
 
 BOOLEAN FASTCALL
-co_MsqDispatchOneSentMessage(_In_ PTHREADINFO pti)
+co_MsqDispatchOneSentMessage(PTHREADINFO pti)
 {
    PUSER_SENT_MESSAGE SaveMsg, Message;
    PLIST_ENTRY Entry;
@@ -959,12 +964,6 @@
 
     ptiSender = PsGetCurrentThreadWin32Thread();
 
-    IntReferenceMessageQueue(ptiReceiver->MessageQueue);
-    /* Take reference on this MessageQueue if its a callback. It will be released
-       when message is processed or removed from target hwnd MessageQueue */
-    if (CompletionCallback)
-       IntReferenceMessageQueue(ptiSender->MessageQueue);
-
     Message->Msg.hwnd = hwnd;
     Message->Msg.message = Msg;
     Message->Msg.wParam = wParam;
@@ -1228,6 +1227,12 @@
    PUSER_MESSAGE Message;
    PUSER_MESSAGE_QUEUE MessageQueue;
 
+   if ( pti->TIF_flags & TIF_INCLEANUP || pti->MessageQueue->QF_flags & QF_INDESTROY )
+   {
+      ERR("Post Msg; Thread or Q is Dead!\n");
+      return;
+   }
+
    if(!(Message = MsqCreateMessage(Msg)))
    {
       return;
@@ -1237,6 +1242,7 @@
 
    if (dwQEvent)
    {
+       ERR("Post Msg; System Qeued Event Message!\n");
        InsertHeadList(&pti->PostedMessagesListHead,
                       &Message->ListEntry);
    }
@@ -1253,7 +1259,7 @@
 
    Message->dwQEvent = dwQEvent;
    Message->QS_Flags = MessageBits;
-   //Message->pti = pti; Fixed in ATI changes. See CORE-6551
+   Message->pti = pti;
    MsqWakeQueue(pti, MessageBits, (MessageBits & QS_TIMER ? FALSE : TRUE));
 }
 
@@ -1301,7 +1307,7 @@
 IntTrackMouseMove(PWND pwndTrack, PDESKTOP pDesk, PMSG msg, USHORT hittest)
 {
 //   PWND pwndTrack = IntChildrenWindowFromPoint(pwndMsg, msg->pt.x, msg->pt.y);
-   hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this???
+//   hittest = (USHORT)GetNCHitEx(pwndTrack, msg->pt); /// @todo WTF is this???
 
    if ( pDesk->spwndTrack != pwndTrack || // Change with tracking window or
         msg->message != WM_MOUSEMOVE   || // Mouse click changes or
@@ -1538,7 +1544,7 @@
         hook.dwExtraInfo  = 0 /* extra_info */ ;
         co_HOOK_CallHooks( WH_CBT, HCBT_CLICKSKIPPED, message, (LPARAM)&hook );
 
-        ERR("WH_MOUSE dorpped mouse message!\n");
+        ERR("WH_MOUSE dropped mouse message!\n");
 
         /* Remove and skip message */
         *RemoveMessages = TRUE;
@@ -1852,7 +1858,7 @@
    ListHead = &pti->PostedMessagesListHead;
 
    if (IsListEmpty(CurrentEntry)) return FALSE;
-   
+
    CurrentMessage = CONTAINING_RECORD(CurrentEntry, USER_MESSAGE,
                                          ListEntry);
    do
@@ -1927,9 +1933,8 @@
 BOOLEAN FASTCALL
 MsqInitializeMessageQueue(PTHREADINFO pti, PUSER_MESSAGE_QUEUE MessageQueue)
 {
-   MessageQueue->ptiOwner = pti;
    MessageQueue->CaretInfo = (PTHRDCARETINFO)(MessageQueue + 1);
-   InitializeListHead(&MessageQueue->HardwareMessagesListHead);
+   InitializeListHead(&MessageQueue->HardwareMessagesListHead); // Keep here!
    MessageQueue->spwndFocus = NULL;
    MessageQueue->iCursorLevel = 0;
    MessageQueue->CursorObject = NULL;
@@ -1947,7 +1952,7 @@
    PLIST_ENTRY CurrentEntry;
    PUSER_MESSAGE CurrentMessage;
    PUSER_SENT_MESSAGE CurrentSentMessage;
-   
+
    /* cleanup posted messages */
    while (!IsListEmpty(&pti->PostedMessagesListHead))
    {
@@ -1983,7 +1988,7 @@
          if (CurrentSentMessage->Msg.lParam)
             ExFreePool((PVOID)CurrentSentMessage->Msg.lParam);
       }
-      
+
       /* free the message */
       ExFreePool(CurrentSentMessage);
    }
@@ -2046,16 +2051,16 @@
    pti->nCntsQBits[QSRosPostMessage] = 0;
    pti->nCntsQBits[QSRosSendMessage] = 0;
    pti->nCntsQBits[QSRosHotKey] = 0;
+   pti->nCntsQBits[QSRosEvent] = 0;
+}
 
-}
- 
 VOID FASTCALL
 MsqCleanupMessageQueue(PTHREADINFO pti)
 {
    PUSER_MESSAGE_QUEUE MessageQueue;
 
    MessageQueue = pti->MessageQueue;
-  MessageQueue->cThreads--;
+   MessageQueue->cThreads--;
 
    if (MessageQueue->cThreads)
    {
@@ -2080,6 +2085,7 @@
            IntGetSysCursorInfo()->CurrentCursorObject = NULL;
        }
 
+       ERR("DereferenceObject pCursor\n");
        UserDereferenceObject(pCursor);
    }
 
Index: win32ss/user/ntuser/misc.c
===================================================================
--- win32ss/user/ntuser/misc.c	(revision 59990)
+++ win32ss/user/ntuser/misc.c	(working copy)
@@ -662,8 +662,11 @@
         ASSERT(pti->pDeskInfo == pti->rpdesk->pDeskInfo);
 
     /*too bad we still get this assertion*/
+
+    // Why? Not all flags are passed to the user and doing so could crash the system........
+
     /* ASSERT(pci->dwTIFlags == pti->TIF_flags); */
-    if(pci->dwTIFlags != pti->TIF_flags)
+/*    if(pci->dwTIFlags != pti->TIF_flags)
     {
         ERR("pci->dwTIFlags(0x%x) doesn't match pti->TIF_flags(0x%x)\n", pci->dwTIFlags, pti->TIF_flags);
         if(showCaller)
@@ -673,6 +676,7 @@
         }
         pci->dwTIFlags = pti->TIF_flags;
     }
+*/
 }
 
 void
Index: win32ss/user/user32/windows/message.c
===================================================================
--- win32ss/user/user32/windows/message.c	(revision 59990)
+++ win32ss/user/user32/windows/message.c	(working copy)
@@ -1346,7 +1346,7 @@
       }
       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
-         ERR("Got exception when calling Ansi WndProc %p Msg %d \n",WndProc,Msg);
+         ERR("Got exception when calling Ansi WndProc %p Msg %d pti %p Wndpti %p\n",WndProc,Msg,GetW32ThreadInfo(),pWnd->head.pti);
       }
       _SEH2_END;
 
@@ -1395,7 +1395,7 @@
       }
       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
-         ERR("Got exception when calling unicode WndProc %p Msg %d \n",WndProc, Msg);
+         ERR("Got exception when calling unicode WndProc %p Msg %d pti %p Wndpti %p\n",WndProc, Msg,GetW32ThreadInfo(),pWnd->head.pti);
       }
       _SEH2_END;
 
@@ -1488,7 +1488,7 @@
       }
       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
-         ERR("Got exception when calling Ansi WndProc %p Msg %d \n",WndProc,Msg);
+         ERR("Got exception when calling Ansi WndProc %p Msg %d pti %p Wndpti %p\n",WndProc,Msg,GetW32ThreadInfo(),pWnd->head.pti);
       }
       _SEH2_END;
 
@@ -1542,7 +1542,7 @@
       }
       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
-         ERR("Got exception when calling unicode WndProc %p Msg %d \n",WndProc, Msg);
+         ERR("Got exception when calling unicode WndProc %p Msg %d pti %p Wndpti %p\n",WndProc, Msg,GetW32ThreadInfo(),pWnd->head.pti);
       }
       _SEH2_END;
 
@@ -2210,7 +2210,7 @@
 
       if ( Window != NULL &&
            Window->head.pti == ti &&
-//          !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
+          !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
           !ISITHOOKED(WH_CALLWNDPROC) &&
           !ISITHOOKED(WH_CALLWNDPROCRET) &&
           !(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
@@ -2226,6 +2226,10 @@
 
           return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, FALSE);
       }
+      else
+      {
+          ERR("SMW: Message inside a Hook!\n");
+      }
   }
 
   UMMsg.hwnd = Wnd;
@@ -2275,7 +2279,7 @@
 
       if ( Window != NULL &&
            Window->head.pti == ti &&
-//          !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
+          !IsThreadHooked(GetWin32ClientInfo()) && // Enable to test message system bug.
           !ISITHOOKED(WH_CALLWNDPROC) &&
           !ISITHOOKED(WH_CALLWNDPROCRET) &&
           !(Window->state & WNDS_SERVERSIDEWINDOWPROC) )
@@ -2291,6 +2295,10 @@
 
           return IntCallMessageProc(Window, Wnd, Msg, wParam, lParam, TRUE);
       }
+      else
+      {
+          ERR("SMA: Message inside a Hook!\n");
+      }
   }
 
   AnsiMsg.hwnd = Wnd;
@@ -2422,8 +2430,8 @@
   MSG AnsiMsg, UcMsg;
   LRESULT Result;
   DOSENDMESSAGE dsm;
-  PWND Window;
-  PTHREADINFO ti = GetW32ThreadInfo();
+//  PWND Window;
+//  PTHREADINFO ti = GetW32ThreadInfo();
 
   if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK))
   {
@@ -2434,6 +2442,7 @@
   if (lpdwResult) *lpdwResult = 0;
 
   //// This is due to message system bug.
+#if 0
   if (hWnd != HWND_TOPMOST && hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
   {
       Window = ValidateHwnd(hWnd);
@@ -2449,6 +2458,7 @@
           return TRUE;
       }
   }
+#endif  
   ////
   SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
 
@@ -2499,8 +2509,8 @@
 {
   LRESULT Result;
   DOSENDMESSAGE dsm;
-  PWND Window;
-  PTHREADINFO ti = GetW32ThreadInfo();
+//  PWND Window;
+//  PTHREADINFO ti = GetW32ThreadInfo();
 
   if ( Msg & ~WM_MAXIMUM || fuFlags & ~(SMTO_NOTIMEOUTIFNOTHUNG|SMTO_ABORTIFHUNG|SMTO_BLOCK))
   {
@@ -2511,6 +2521,7 @@
   if (lpdwResult) *lpdwResult = 0;
 
   //// This is due to message system bug.
+#if 0
   if (hWnd != HWND_TOPMOST && hWnd != HWND_BROADCAST && (Msg < WM_DDE_FIRST || Msg > WM_DDE_LAST))
   {
       Window = ValidateHwnd(hWnd);
@@ -2526,6 +2537,7 @@
           return TRUE;
       }
   }
+#endif
   ////
   SPY_EnterMessage(SPY_SENDMESSAGE, hWnd, Msg, wParam, lParam);
 
