* Sync up to trunk head (r64921).
[reactos.git] / win32ss / user / ntuser / window.c
index 0aeb744..b04f6ba 100644 (file)
@@ -90,7 +90,7 @@ PWND FASTCALL VerifyWnd(PWND pWnd)
 
 PWND FASTCALL ValidateHwndNoErr(HWND hWnd)
 {
-   if (hWnd) return (PWND)UserGetObjectNoErr(gHandleTable, hWnd, otWindow);
+   if (hWnd) return (PWND)UserGetObjectNoErr(gHandleTable, hWnd, TYPE_WINDOW);
    return NULL;
 }
 
@@ -105,7 +105,7 @@ PWND FASTCALL UserGetWindowObject(HWND hWnd)
       return NULL;
    }
 
-   Window = (PWND)UserGetObject(gHandleTable, hWnd, otWindow);
+   Window = (PWND)UserGetObject(gHandleTable, hWnd, TYPE_WINDOW);
    if (!Window || 0 != (Window->state & WNDS_DESTROYED))
    {
       EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
@@ -123,7 +123,12 @@ IntSetStyle( PWND pwnd, ULONG set_bits, ULONG clear_bits )
     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 @@ IntIsWindow(HWND hWnd)
 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
@@ -277,11 +277,8 @@ IntWinListChildren(PWND Window)
 PWND FASTCALL
 IntGetNonChildAncestor(PWND pWnd)
 {
-   if (pWnd)
-   {
-      while(pWnd && ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD))
-         pWnd = pWnd->spwndParent;
-   }
+   while(pWnd && (pWnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+      pWnd = pWnd->spwndParent;
    return pWnd;
 }
 
@@ -307,6 +304,64 @@ IntValidateOwnerDepth(PWND Wnd, PWND Owner)
    return FALSE;
 }
 
+HWND FASTCALL
+IntGetWindow(HWND hWnd,
+          UINT uCmd)
+{
+    PWND Wnd, FoundWnd;
+    HWND Ret = NULL;
+
+    Wnd = ValidateHwndNoErr(hWnd);
+    if (!Wnd)
+        return NULL;
+
+    FoundWnd = NULL;
+    switch (uCmd)
+    {
+            case GW_OWNER:
+                if (Wnd->spwndOwner != NULL)
+                    FoundWnd = Wnd->spwndOwner;
+                break;
+
+            case GW_HWNDFIRST:
+                if(Wnd->spwndParent != NULL)
+                {
+                    FoundWnd = Wnd->spwndParent;
+                    if (FoundWnd->spwndChild != NULL)
+                        FoundWnd = FoundWnd->spwndChild;
+                }
+                break;
+            case GW_HWNDNEXT:
+                if (Wnd->spwndNext != NULL)
+                    FoundWnd = Wnd->spwndNext;
+                break;
+
+            case GW_HWNDPREV:
+                if (Wnd->spwndPrev != NULL)
+                    FoundWnd = Wnd->spwndPrev;
+                break;
+   
+            case GW_CHILD:
+                if (Wnd->spwndChild != NULL)
+                    FoundWnd = Wnd->spwndChild;
+                break;
+
+            case GW_HWNDLAST:
+                FoundWnd = Wnd;
+                while ( FoundWnd->spwndNext != NULL)
+                    FoundWnd = FoundWnd->spwndNext;
+                break;
+
+            default:
+                Wnd = NULL;
+                break;
+    }
+
+    if (FoundWnd != NULL)
+        Ret = UserHMGetHandle(FoundWnd);
+    return Ret;
+}
+
 /***********************************************************************
  *           IntSendDestroyMsg
  */
@@ -404,7 +459,7 @@ UserFreeWindowInfo(PTHREADINFO ti, PWND Wnd)
    }
 
 //    DesktopHeapFree(Wnd->head.rpdesk, Wnd);
-//    WindowObject->Wnd = NULL;
+//    WindowObject->hWnd = NULL;
 }
 
 /***********************************************************************
@@ -424,7 +479,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
    HWND *Children;
    HWND *ChildHandle;
    PWND Child;
-   PMENU_OBJECT Menu;
+   PMENU Menu;
    BOOLEAN BelongsToThreadData;
 
    ASSERT(Window);
@@ -436,6 +491,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
    }
    Window->state2 |= WNDS2_INDESTROY;
    Window->style &= ~WS_VISIBLE;
+   Window->head.pti->cVisWindows--;
 
    IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
 
@@ -497,8 +553,6 @@ static LRESULT co_UserFreeWindow(PWND Window,
    /* flush the message queue */
    MsqRemoveWindowMessagesFromQueue(Window);
 
-   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;
@@ -533,14 +587,14 @@ static LRESULT co_UserFreeWindow(PWND Window,
         Window->IDMenu &&
         (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
    {
-      IntDestroyMenuObject(Menu, TRUE, TRUE);
+      IntDestroyMenuObject(Menu, TRUE);
       Window->IDMenu = 0;
    }
 
    if(Window->SystemMenu
          && (Menu = UserGetMenuObject(Window->SystemMenu)))
    {
-      IntDestroyMenuObject(Menu, TRUE, TRUE);
+      IntDestroyMenuObject(Menu, TRUE);
       Window->SystemMenu = (HMENU)0;
    }
 
@@ -553,8 +607,15 @@ static LRESULT co_UserFreeWindow(PWND Window,
 
    IntUnlinkWindow(Window);
 
+   if (Window->PropListItems)
+   {
+      IntRemoveWindowProp(Window);
+      TRACE("Window->PropListItems %d\n",Window->PropListItems);
+      ASSERT(Window->PropListItems==0);
+   }
+
    UserReferenceObject(Window);
-   UserDeleteObject(Window->head.h, otWindow);
+   UserDeleteObject(Window->head.h, TYPE_WINDOW);
 
    IntDestroyScrollBars(Window);
 
@@ -570,6 +631,7 @@ static LRESULT co_UserFreeWindow(PWND Window,
       GreDeleteObject(Window->hrgnClip);
       Window->hrgnClip = NULL;
    }
+   Window->head.pti->cWindows--;
 
 //   ASSERT(Window != NULL);
    UserFreeWindowInfo(Window->head.pti, Window);
@@ -661,7 +723,7 @@ IntSetWindowProc(PWND pWnd,
 
    if (IsCallProcHandle(NewWndProc))
    {
-      CallProc = UserGetObject(gHandleTable, NewWndProc, otCallProc);
+      CallProc = UserGetObject(gHandleTable, NewWndProc, TYPE_CALLPROC);
       if (CallProc)
       {  // Reset new WndProc.
          NewWndProc = CallProc->pfnClientPrevious;
@@ -730,7 +792,7 @@ IntSetMenu(
    HMENU Menu,
    BOOL *Changed)
 {
-   PMENU_OBJECT OldMenu, NewMenu = NULL;
+   PMENU OldMenu, NewMenu = NULL;
 
    if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
    {
@@ -748,7 +810,7 @@ IntSetMenu(
    if (Wnd->IDMenu)
    {
       OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu);
-      ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Wnd->head.h);
+      ASSERT(NULL == OldMenu || OldMenu->hWnd == Wnd->head.h);
    }
    else
    {
@@ -767,7 +829,7 @@ IntSetMenu(
          EngSetLastError(ERROR_INVALID_MENU_HANDLE);
          return FALSE;
       }
-      if (NULL != NewMenu->MenuInfo.Wnd)
+      if (NULL != NewMenu->hWnd)
       {
          /* Can't use the same menu for two windows */
          if (NULL != OldMenu)
@@ -783,12 +845,12 @@ IntSetMenu(
    Wnd->IDMenu = (UINT) Menu;
    if (NULL != NewMenu)
    {
-      NewMenu->MenuInfo.Wnd = Wnd->head.h;
+      NewMenu->hWnd = Wnd->head.h;
       IntReleaseMenuObject(NewMenu);
    }
    if (NULL != OldMenu)
    {
-      OldMenu->MenuInfo.Wnd = NULL;
+      OldMenu->hWnd = NULL;
       IntReleaseMenuObject(OldMenu);
    }
 
@@ -799,149 +861,6 @@ IntSetMenu(
 /* INTERNAL ******************************************************************/
 
 
-VOID FASTCALL
-co_DestroyThreadWindows(struct _ETHREAD *Thread)
-{
-   PTHREADINFO WThread;
-   PLIST_ENTRY Current;
-   PWND Wnd;
-   USER_REFERENCE_ENTRY Ref;
-   WThread = (PTHREADINFO)Thread->Tcb.Win32Thread;
-
-   while (!IsListEmpty(&WThread->WindowListHead))
-   {
-      Current = WThread->WindowListHead.Flink;
-      Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry);
-
-      TRACE("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
-
-      /* Window removes itself from the list */
-
-      /*
-       * FIXME: It is critical that the window removes itself! If now, we will loop
-       * here forever...
-       */
-
-      //ASSERT(co_UserDestroyWindow(Wnd));
-
-      UserRefObjectCo(Wnd, &Ref); // FIXME: Temp HACK??
-      if (!co_UserDestroyWindow(Wnd))
-      {
-         ERR("Unable to destroy window 0x%x at thread cleanup... This is _VERY_ bad!\n", Wnd);
-      }
-      UserDerefObjectCo(Wnd); // FIXME: Temp HACK??
-   }
-}
-
-PMENU_OBJECT FASTCALL
-IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
-{
-   PMENU_OBJECT Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
-   PTHREADINFO W32Thread;
-   HMENU hNewMenu, hSysMenu;
-   ROSMENUITEMINFO ItemInfo;
-
-   if(bRevert)
-   {
-      W32Thread = PsGetCurrentThreadWin32Thread();
-
-      if(!W32Thread->rpdesk)
-         return NULL;
-
-      if(Window->SystemMenu)
-      {
-         Menu = UserGetMenuObject(Window->SystemMenu);
-         if(Menu)
-         {
-            IntDestroyMenuObject(Menu, TRUE, TRUE);
-            Window->SystemMenu = (HMENU)0;
-         }
-      }
-
-      if(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate)
-      {
-         /* Clone system menu */
-         Menu = UserGetMenuObject(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate);
-         if(!Menu)
-            return NULL;
-
-         NewMenu = IntCloneMenu(Menu);
-         if(NewMenu)
-         {
-            Window->SystemMenu = NewMenu->MenuInfo.Self;
-            NewMenu->MenuInfo.Flags |= MF_SYSMENU;
-            NewMenu->MenuInfo.Wnd = Window->head.h;
-            ret = NewMenu;
-            //IntReleaseMenuObject(NewMenu);
-         }
-      }
-      else
-      {
-         hSysMenu = UserCreateMenu(FALSE);
-         if (NULL == hSysMenu)
-         {
-            return NULL;
-         }
-         SysMenu = IntGetMenuObject(hSysMenu);
-         if (NULL == SysMenu)
-         {
-            UserDestroyMenu(hSysMenu);
-            return NULL;
-         }
-         SysMenu->MenuInfo.Flags |= MF_SYSMENU;
-         SysMenu->MenuInfo.Wnd = Window->head.h;
-         hNewMenu = co_IntLoadSysMenuTemplate();
-         if(!hNewMenu)
-         {
-            IntReleaseMenuObject(SysMenu);
-            UserDestroyMenu(hSysMenu);
-            return NULL;
-         }
-         Menu = IntGetMenuObject(hNewMenu);
-         if(!Menu)
-         {
-            IntReleaseMenuObject(SysMenu);
-            UserDestroyMenu(hSysMenu);
-            return NULL;
-         }
-
-         NewMenu = IntCloneMenu(Menu);
-         if(NewMenu)
-         {
-            NewMenu->MenuInfo.Flags |= MF_SYSMENU | MF_POPUP;
-            IntReleaseMenuObject(NewMenu);
-            UserSetMenuDefaultItem(NewMenu, SC_CLOSE, FALSE);
-
-            ItemInfo.cbSize = sizeof(MENUITEMINFOW);
-            ItemInfo.fMask = MIIM_FTYPE | MIIM_STRING | MIIM_STATE | MIIM_SUBMENU;
-            ItemInfo.fType = MF_POPUP;
-            ItemInfo.fState = MFS_ENABLED;
-            ItemInfo.dwTypeData = NULL;
-            ItemInfo.cch = 0;
-            ItemInfo.hSubMenu = NewMenu->MenuInfo.Self;
-            IntInsertMenuItem(SysMenu, (UINT) -1, TRUE, &ItemInfo);
-
-            Window->SystemMenu = SysMenu->MenuInfo.Self;
-
-            ret = SysMenu;
-         }
-         IntDestroyMenuObject(Menu, FALSE, TRUE);
-      }
-      if(RetMenu)
-         return ret;
-      else
-         return NULL;
-   }
-   else
-   {
-      if(Window->SystemMenu)
-         return IntGetMenuObject((HMENU)Window->SystemMenu);
-      else
-         return NULL;
-   }
-}
-
-
 BOOL FASTCALL
 IntIsChildWindow(PWND Parent, PWND BaseWindow)
 {
@@ -1090,8 +1009,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner)
               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);
          }
       }
    }
@@ -1102,8 +1021,8 @@ IntProcessOwnerSwap(PWND Wnd, PWND WndNewOwner, PWND WndOldOwner)
          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);
          }
       }
    }
@@ -1132,6 +1051,8 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner)
       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))
@@ -1178,6 +1099,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
    /* Some applications try to set a child as a parent */
    if (IntIsChildWindow(Wnd, WndNewParent))
    {
+      TRACE("IntSetParent try to set a child as a parent.\n");
       EngSetLastError( ERROR_INVALID_PARAMETER );
       return NULL;
    }
@@ -1188,6 +1110,7 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
    {
       if (Wnd == pWndExam)
       {
+         TRACE("IntSetParent Failed Test for set parent to parent!\n");
          EngSetLastError(ERROR_INVALID_PARAMETER);
          return NULL;
       }
@@ -1202,7 +1125,10 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
 
    /* 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;
 
@@ -1213,6 +1139,8 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
       pt.x = Wnd->rcWindow.left;
    pt.y = Wnd->rcWindow.top;
 
+   IntScreenToClient(WndOldParent, &pt);
+
    if (WndOldParent) UserReferenceObject(WndOldParent); /* Caller must deref */
 
    if (WndNewParent != WndOldParent)
@@ -1239,22 +1167,31 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
 
    }
 
+   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);
          }
       }
    }
@@ -1268,10 +1205,11 @@ co_IntSetParent(PWND Wnd, PWND WndNewParent)
     * 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 X %d Y %d\n",pt.x, pt.y);
    if (WasVisible) co_WinPosShowWindow(Wnd, SW_SHOWNORMAL);
 
    return WndOldParent;
@@ -1292,6 +1230,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
 
    if (hWndChild == IntGetDesktopWindow())
    {
+      ERR("UserSetParent Access Denied!\n");
       EngSetLastError(ERROR_ACCESS_DENIED);
       return( NULL);
    }
@@ -1300,6 +1239,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
    {
       if (!(WndParent = UserGetWindowObject(hWndNewParent)))
       {
+         ERR("UserSetParent Bad New Parent!\n");
          return( NULL);
       }
    }
@@ -1313,6 +1253,7 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
 
    if (!(Wnd = UserGetWindowObject(hWndChild)))
    {
+      ERR("UserSetParent Bad Child!\n");
       return( NULL);
    }
 
@@ -1333,32 +1274,6 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
    return( hWndOldParent);
 }
 
-BOOL FASTCALL
-IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
-{
-   PMENU_OBJECT OldMenu;
-   if(Window->SystemMenu)
-   {
-      OldMenu = IntGetMenuObject(Window->SystemMenu);
-      if(OldMenu)
-      {
-         OldMenu->MenuInfo.Flags &= ~ MF_SYSMENU;
-         IntReleaseMenuObject(OldMenu);
-      }
-   }
-
-   if(Menu)
-   {
-      /* FIXME: Check window style, propably return FALSE? */
-      Window->SystemMenu = Menu->MenuInfo.Self;
-      Menu->MenuInfo.Flags |= MF_SYSMENU;
-   }
-   else
-      Window->SystemMenu = (HMENU)0;
-
-   return TRUE;
-}
-
 /* Unlink the window from siblings. children and parent are kept in place. */
 VOID FASTCALL
 IntUnlinkWindow(PWND Wnd)
@@ -1657,24 +1572,25 @@ IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWND ParentWindow, DWORD* dwShowMode)
 
 /* Allocates and initializes a window */
 PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
-                                        PLARGE_STRING WindowName,
-                                        PCLS Class,
-                                        PWND ParentWindow,
-                                        PWND OwnerWindow,
-                                        PVOID acbiBuffer)
+                              PLARGE_STRING WindowName,
+                              PCLS Class,
+                              PWND ParentWindow,
+                              PWND OwnerWindow,
+                              PVOID acbiBuffer,
+                              PDESKTOP pdeskCreated)
 {
    PWND pWnd = NULL;
    HWND hWnd;
    PTHREADINFO pti = NULL;
-   PMENU_OBJECT SystemMenu;
    BOOL MenuChanged;
    BOOL bUnicodeWindow;
 
-   pti = PsGetCurrentThreadWin32Thread();
+   pti = pdeskCreated ? gptiDesktopThread : GetW32ThreadInfo();
 
    if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
-   {
-      if (ParentWindow)
+   {      // Need both here for wine win.c test_CreateWindow.
+      //if (Cs->hwndParent && ParentWindow)
+      if (ParentWindow) // It breaks more tests..... WIP.
       {
          if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
               ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
@@ -1690,8 +1606,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
          */
          if ( Class->fnid != FNID_DIALOG )
          {
-            PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
-            if (ppi->dwLayout & LAYOUT_RTL)
+            if (pti->ppi->dwLayout & LAYOUT_RTL)
             {
                Cs->dwExStyle |= WS_EX_LAYOUTRTL;
             }
@@ -1713,9 +1628,10 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
 
    /* Allocate the new window */
    pWnd = (PWND) UserCreateObject( gHandleTable,
-                                   pti->rpdesk,
+                                   pdeskCreated ? pdeskCreated : pti->rpdesk,
+                                   pti,
                                   (PHANDLE)&hWnd,
-                                   otWindow,
+                                   TYPE_WINDOW,
                                    sizeof(WND) + Class->cbwndExtra);
 
    if (!pWnd)
@@ -1723,14 +1639,14 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
       goto AllocError;
    }
 
-   TRACE("Created object with handle %X\n", hWnd);
+   TRACE("Created window object with handle %p\n", hWnd);
 
-   if (NULL == pti->rpdesk->DesktopWindow)
+   if (pdeskCreated && pdeskCreated->DesktopWindow == NULL )
    {  /* HACK: Helper for win32csr/desktopbg.c */
       /* If there is no desktop window yet, we must be creating it */
       TRACE("CreateWindow setting desktop.\n");
-      pti->rpdesk->DesktopWindow = hWnd;
-      pti->rpdesk->pDeskInfo->spwnd = pWnd;
+      pdeskCreated->DesktopWindow = hWnd;
+      pdeskCreated->pDeskInfo->spwnd = pWnd;
    }
 
    /*
@@ -1751,13 +1667,55 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    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++;
+#ifdef NEW_CURSORICON
+   if (Class->spicn && !Class->spicnSm)
+   {
+       HICON IconSmHandle = NULL;
+       if((Class->spicn->CURSORF_flags & (CURSORF_LRSHARED | CURSORF_FROMRESOURCE))
+               == (CURSORF_LRSHARED | CURSORF_FROMRESOURCE))
+       {
+           IconSmHandle = co_IntCopyImage(
+               UserHMGetHandle(Class->spicn),
+               IMAGE_ICON,
+               UserGetSystemMetrics( SM_CXSMICON ),
+               UserGetSystemMetrics( SM_CYSMICON ),
+               LR_COPYFROMRESOURCE | LR_SHARED);
+       }
+       if (!IconSmHandle)
+       {
+           /* Retry without copying from resource */
+           IconSmHandle = co_IntCopyImage(
+               UserHMGetHandle(Class->spicn),
+               IMAGE_ICON,
+               UserGetSystemMetrics( SM_CXSMICON ),
+               UserGetSystemMetrics( SM_CYSMICON ),
+               LR_SHARED);
+       }
+
+       if (IconSmHandle)
+       {
+           Class->spicnSm = UserGetCurIconObject(IconSmHandle);
+           Class->CSF_flags |= CSF_CACHEDSMICON;
+       }
+   }
+#else
+   if (Class->hIcon && !Class->hIconSm)
+   {
+      Class->hIconSmIntern = co_IntCopyImage( Class->hIcon, IMAGE_ICON,
+                                              UserGetSystemMetrics( SM_CXSMICON ),
+                                              UserGetSystemMetrics( SM_CYSMICON ), 0 );
+      TRACE("IntCreateWindow hIconSmIntern %p\n",Class->hIconSmIntern);
+      Class->CSF_flags |= CSF_CACHEDSMICON;
+   }
+#endif
+
    if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
       pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
 
@@ -1828,12 +1786,12 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT])
    {
       PCALLPROCDATA CallProc;
-      CallProc = CreateCallProc(NULL, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
+      CallProc = CreateCallProc(pWnd->head.rpdesk, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
 
       if (!CallProc)
       {
          EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
-         ERR("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd);
+         ERR("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %p\n", hWnd);
       }
       else
       {
@@ -1842,6 +1800,7 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    }
 
    InitializeListHead(&pWnd->PropListHead);
+   pWnd->PropListItems = 0;
 
    if ( WindowName->Buffer != NULL && WindowName->Length > 0 )
    {
@@ -1883,22 +1842,13 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    if (!(pWnd->style & (WS_CHILD | WS_POPUP)))
       pWnd->state |= WNDS_SENDSIZEMOVEMSGS;
 
-   /* Create system menu */
-   if ((Cs->style & WS_SYSMENU)) // && (dwStyle & WS_CAPTION) == WS_CAPTION)
-   {
-      SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
-      if(SystemMenu)
-      {
-         pWnd->SystemMenu = SystemMenu->MenuInfo.Self;
-         IntReleaseMenuObject(SystemMenu);
-      }
-   }
-
    /* Set the window menu */
    if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
    {
-       if (Cs->hMenu)
+      if (Cs->hMenu)
+      {
          IntSetMenu(pWnd, Cs->hMenu, &MenuChanged);
+      }
       else if (pWnd->pcls->lpszMenuName) // Take it from the parent.
       {
           UNICODE_STRING MenuName;
@@ -1942,8 +1892,8 @@ PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
             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);
        }
    }
 
@@ -1986,7 +1936,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    PWINSTATION_OBJECT WinSta;
    PCLS Class = NULL;
    SIZE Size;
-   POINT MaxPos;
+   POINT MaxSize, MaxPos, MinTrack, MaxTrack;
    CBT_CREATEWNDW * pCbtCreate;
    LRESULT Result;
    USER_REFERENCE_ENTRY ParentRef, Ref;
@@ -2010,7 +1960,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    pCbtCreate = NULL;
 
    /* Get the class and reference it */
-   Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
+   Class = IntGetAndReferenceClass(ClassName, Cs->hInstance, FALSE);
    if(!Class)
    {
        ERR("Failed to find class %wZ\n", ClassName);
@@ -2018,12 +1968,12 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    }
 
    /* Now find the parent and the owner window */
-   hWndParent = IntGetDesktopWindow();
+   hWndParent = pti->rpdesk->pDeskInfo->spwnd->head.h;
    hWndOwner = NULL;
 
     if (Cs->hwndParent == HWND_MESSAGE)
     {
-        Cs->hwndParent = hWndParent = IntGetMessageWindow();
+        Cs->hwndParent = hWndParent = pti->rpdesk->spwndMessage->head.h;
     }
     else if (Cs->hwndParent)
     {
@@ -2059,7 +2009,8 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
                             Class,
                             ParentWindow,
                             OwnerWindow,
-                            acbiBuffer);
+                            acbiBuffer,
+                            NULL);
    if(!Window)
    {
        ERR("IntCreateWindow failed!\n");
@@ -2182,14 +2133,21 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    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;
 
    if ((Cs->style & WS_THICKFRAME) || !(Cs->style & (WS_POPUP | WS_CHILD)))
    {
-      POINT MaxSize, MaxPos, MinTrack, MaxTrack;
-
       co_WinPosGetMinMaxInfo(Window, &MaxSize, &MaxPos, &MinTrack, &MaxTrack);
       if (Size.cx > MaxTrack.x) Size.cx = MaxTrack.x;
       if (Size.cy > MaxTrack.y) Size.cy = MaxTrack.y;
@@ -2201,13 +2159,26 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    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");
+      ERR("co_UserCreateWindowEx(): Offset rcWindow\n");
       RECTL_vOffsetRect(&Window->rcWindow,
                         ParentWindow->rcClient.left,
                         ParentWindow->rcClient.top);
    }
+ */
+   /* correct child window coordinates if mirroring on parent is enabled */
+   if (ParentWindow != NULL)
+   {
+      if ( ((Cs->style & WS_CHILD) == WS_CHILD) && 
+          ((ParentWindow->ExStyle & WS_EX_LAYOUTRTL) ==  WS_EX_LAYOUTRTL))
+      {
+          Window->rcWindow.right = ParentWindow->rcClient.right - (Window->rcWindow.left - ParentWindow->rcClient.left);
+          Window->rcWindow.left = Window->rcWindow.right - Size.cx;
+      }
+   }
+
    Window->rcClient = Window->rcWindow;
 
    /* Link the window */
@@ -2220,14 +2191,20 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
           IntLinkHwnd(Window, hwndInsertAfter);
    }
 
+   if (!(Window->state2 & WNDS2_WIN31COMPAT))
+   {
+      if (Class->style & CS_PARENTDC && !(ParentWindow->style & WS_CLIPCHILDREN))
+         Window->style &= ~(WS_CLIPSIBLINGS | WS_CLIPCHILDREN);
+   }
+
    if ((Window->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
    {
       if ( !IntIsTopLevelWindow(Window) )
       {
          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);
          }
       }
    }
@@ -2241,14 +2218,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    }
 
    /* 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);
@@ -2291,7 +2273,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    IntSendParentNotify(Window, WM_CREATE);
 
    /* Notify the shell that a new window was created */
-   if ((!hWndParent) && (!hWndOwner))
+   if (Window->spwndParent == UserGetDesktopWindow() &&
+       Window->spwndOwner == NULL &&
+       (Window->style & WS_VISIBLE) &&
+       (!(Window->ExStyle & WS_EX_TOOLWINDOW) ||
+        (Window->ExStyle & WS_EX_APPWINDOW)))
    {
       co_IntShellHookNotify(HSHELL_WINDOWCREATED, (WPARAM)hWnd, 0);
    }
@@ -2327,7 +2313,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
       }
    }
 
-   TRACE("co_UserCreateWindowEx(): Created window %X\n", hWnd);
+   TRACE("co_UserCreateWindowEx(): Created window %p\n", hWnd);
    ret = Window;
 
 cleanup:
@@ -2444,6 +2430,17 @@ NtUserCreateWindowEx(
 
     ASSERT(plstrWindowName);
 
+    if ( (dwStyle & (WS_POPUP|WS_CHILD)) != WS_CHILD) 
+    {
+        /* check hMenu is valid handle */
+        if (hMenu && !UserGetMenuObject(hMenu))
+        {
+            ERR("NtUserCreateWindowEx: Got an invalid menu handle!\n");
+            EngSetLastError(ERROR_INVALID_MENU_HANDLE);
+            return NULL;
+        }
+    } 
+
     /* Copy the window name to kernel mode */
     Status = ProbeAndCaptureLargeString(&lstrWindowName, plstrWindowName);
     if (!NT_SUCCESS(Status))
@@ -2526,12 +2523,13 @@ cleanup:
 }
 
 
-BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
+BOOLEAN co_UserDestroyWindow(PVOID Object)
 {
    HWND hWnd;
    PWND pwndTemp;
    PTHREADINFO ti;
    MSG msg;
+   PWND Window = Object;
 
    ASSERT_REFS_CO(Window); // FIXME: Temp HACK?
 
@@ -2541,11 +2539,14 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
    TRACE("co_UserDestroyWindow \n");
 
    /* Check for owner thread */
-   if ( (Window->head.pti->pEThread != PsGetCurrentThread()) ||
-        Window->head.pti != PsGetCurrentThreadWin32Thread() )
+   if ( Window->head.pti != PsGetCurrentThreadWin32Thread())
    {
-      EngSetLastError(ERROR_ACCESS_DENIED);
-      return FALSE;
+       /* Check if we are destroying the desktop window */
+       if (! ((Window->head.rpdesk->dwDTFlags & DF_DESTROYED) && Window == Window->head.rpdesk->pDeskInfo->spwnd))
+       {
+           EngSetLastError(ERROR_ACCESS_DENIED);
+           return FALSE;
+       }
    }
 
    /* If window was created successfully and it is hooked */
@@ -2564,8 +2565,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
       {
          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);
          }
       }
    }
@@ -2603,8 +2604,8 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
       {
          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);
          }
       }
    }
@@ -2622,7 +2623,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
     * Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
     */
 
-   if ((ti != NULL) & (ti->pDeskInfo != NULL))
+   if ((ti != NULL) && (ti->pDeskInfo != NULL))
    {
       if (ti->pDeskInfo->hShellWindow == hWnd)
       {
@@ -2736,7 +2737,7 @@ NtUserDestroyWindow(HWND Wnd)
    RETURN(ret);
 
 CLEANUP:
-   TRACE("Leave NtUserDestroyWindow, ret=%i\n",_ret_);
+   TRACE("Leave NtUserDestroyWindow, ret=%u\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -3016,7 +3017,7 @@ NtUserFindWindowEx(HWND hwndParent,
    RETURN( Ret);
 
 CLEANUP:
-   TRACE("Leave NtUserFindWindowEx, ret %i\n",_ret_);
+   TRACE("Leave NtUserFindWindowEx, ret %p\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -3069,8 +3070,6 @@ PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type)
 
             for (;;)
             {
-               PWND Parent;
-
                Parent = IntGetParent(WndAncestor);
 
                if (!Parent)
@@ -3115,12 +3114,45 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
    RETURN(Ancestor ? Ancestor->head.h : NULL);
 
 CLEANUP:
-   TRACE("Leave NtUserGetAncestor, ret=%i\n",_ret_);
+   TRACE("Leave NtUserGetAncestor, ret=%p\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
 
-
+////
+//// ReactOS work around! Keep it the sames as in Combo.c and Controls.h
+////
+/* combo state struct */
+typedef struct
+{
+   HWND           self;
+   HWND           owner;
+   UINT           dwStyle;
+   HWND           hWndEdit;
+   HWND           hWndLBox;
+   UINT           wState;
+   HFONT          hFont;
+   RECT           textRect;
+   RECT           buttonRect;
+   RECT           droppedRect;
+   INT            droppedIndex;
+   INT            fixedOwnerDrawHeight;
+   INT            droppedWidth;   /* last two are not used unless set */
+   INT            editHeight;     /* explicitly */
+   LONG           UIState;
+} HEADCOMBO,*LPHEADCOMBO;
+
+// Window Extra data container.
+typedef struct _WND2CBOX
+{
+  WND;
+  LPHEADCOMBO pCBox;
+} WND2CBOX, *PWND2CBOX;
+
+#define CBF_BUTTONDOWN          0x0002
+////
+////
+////
 BOOL
 APIENTRY
 NtUserGetComboBoxInfo(
@@ -3128,6 +3160,9 @@ NtUserGetComboBoxInfo(
    PCOMBOBOXINFO pcbi)
 {
    PWND Wnd;
+   PPROCESSINFO ppi;
+   BOOL NotSameppi = FALSE;
+   BOOL Ret = TRUE;
    DECLARE_RETURN(BOOL);
 
    TRACE("Enter NtUserGetComboBoxInfo\n");
@@ -3153,22 +3188,95 @@ NtUserGetComboBoxInfo(
    }
    _SEH2_END;
 
+   if (pcbi->cbSize < sizeof(COMBOBOXINFO))
+   {
+      EngSetLastError(ERROR_INVALID_PARAMETER);
+      RETURN(FALSE);
+   }
+
    // Pass the user pointer, it was already probed.
-   RETURN( (BOOL) co_IntSendMessage( Wnd->head.h, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
+   if ((Wnd->pcls->atomClassName != gpsi->atomSysClass[ICLS_COMBOBOX]) && Wnd->fnid != FNID_COMBOBOX)
+   {
+      RETURN( (BOOL) co_IntSendMessage( Wnd->head.h, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
+   }
+
+   ppi = PsGetCurrentProcessWin32Process();
+   NotSameppi = ppi != Wnd->head.pti->ppi;
+   if (NotSameppi)
+   {
+      KeAttachProcess(&Wnd->head.pti->ppi->peProcess->Pcb);
+   }
+
+   _SEH2_TRY
+   {
+      LPHEADCOMBO lphc = ((PWND2CBOX)Wnd)->pCBox;
+      pcbi->rcItem = lphc->textRect;
+      pcbi->rcButton = lphc->buttonRect;
+      pcbi->stateButton = 0;
+      if (lphc->wState & CBF_BUTTONDOWN)
+         pcbi->stateButton |= STATE_SYSTEM_PRESSED;
+      if (RECTL_bIsEmptyRect(&lphc->buttonRect))
+         pcbi->stateButton |= STATE_SYSTEM_INVISIBLE;
+      pcbi->hwndCombo = lphc->self;
+      pcbi->hwndItem = lphc->hWndEdit;
+      pcbi->hwndList = lphc->hWndLBox;
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+      Ret = FALSE;
+      SetLastNtError(_SEH2_GetExceptionCode());
+   }
+   _SEH2_END;
+   
+   RETURN( Ret);
 
 CLEANUP:
+   if (NotSameppi) KeDetachProcess();
    TRACE("Leave NtUserGetComboBoxInfo, ret=%i\n",_ret_);
    UserLeave();
    END_CLEANUP;
 }
 
-
+////
+//// ReactOS work around! Keep it the sames as in Listbox.c
+////
+/* Listbox structure */
+typedef struct
+{
+    HWND        self;           /* Our own window handle */
+    HWND        owner;          /* Owner window to send notifications to */
+    UINT        style;          /* Window style */
+    INT         width;          /* Window width */
+    INT         height;         /* Window height */
+    VOID       *items;          /* Array of items */
+    INT         nb_items;       /* Number of items */
+    INT         top_item;       /* Top visible item */
+    INT         selected_item;  /* Selected item */
+    INT         focus_item;     /* Item that has the focus */
+    INT         anchor_item;    /* Anchor item for extended selection */
+    INT         item_height;    /* Default item height */
+    INT         page_size;      /* Items per listbox page */
+    INT         column_width;   /* Column width for multi-column listboxes */
+} LB_DESCR;
+
+// Window Extra data container.
+typedef struct _WND2LB
+{
+  WND;
+  LB_DESCR * pLBiv;
+} WND2LB, *PWND2LB;
+////
+////
+////
 DWORD
 APIENTRY
 NtUserGetListBoxInfo(
    HWND hWnd)
 {
    PWND Wnd;
+   PPROCESSINFO ppi;
+   BOOL NotSameppi = FALSE;
+   DWORD Ret = 0;
    DECLARE_RETURN(DWORD);
 
    TRACE("Enter NtUserGetListBoxInfo\n");
@@ -3179,10 +3287,40 @@ NtUserGetListBoxInfo(
       RETURN( 0 );
    }
 
-   RETURN( (DWORD) co_IntSendMessage( Wnd->head.h, LB_GETLISTBOXINFO, 0, 0 ));
+   if ((Wnd->pcls->atomClassName != gpsi->atomSysClass[ICLS_LISTBOX]) && Wnd->fnid != FNID_LISTBOX)
+   {
+      RETURN( (DWORD) co_IntSendMessage( Wnd->head.h, LB_GETLISTBOXINFO, 0, 0 ));
+   }
+
+   // wine lisbox:test_GetListBoxInfo lb_getlistboxinfo = 0, should not send a message!
+   ppi = PsGetCurrentProcessWin32Process();
+   NotSameppi = ppi != Wnd->head.pti->ppi;
+   if (NotSameppi)
+   {
+      KeAttachProcess(&Wnd->head.pti->ppi->peProcess->Pcb);
+   }
+
+   _SEH2_TRY
+   {
+      LB_DESCR *descr = ((PWND2LB)Wnd)->pLBiv;
+      // See Controls ListBox.c:LB_GETLISTBOXINFO must match...
+      if (descr->style & LBS_MULTICOLUMN) //// ReactOS
+         Ret = descr->page_size * descr->column_width;
+      else
+         Ret = descr->page_size;
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+      Ret = 0;
+      SetLastNtError(_SEH2_GetExceptionCode());
+   }
+   _SEH2_END;
+   
+   RETURN( Ret);
 
 CLEANUP:
-   TRACE("Leave NtUserGetListBoxInfo, ret=%i\n",_ret_);
+   if (NotSameppi) KeDetachProcess();
+   TRACE("Leave NtUserGetListBoxInfo, ret=%lu\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -3227,7 +3365,7 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
    RETURN( co_UserSetParent(hWndChild, hWndNewParent));
 
 CLEANUP:
-   TRACE("Leave NtUserSetParent, ret=%i\n",_ret_);
+   TRACE("Leave NtUserSetParent, ret=%p\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -3341,6 +3479,7 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
    }
 
    UserRefObjectCo(WndShell, &Ref);
+   WndShell->state2 |= WNDS2_BOTTOMMOST;
    co_WinPosSetWindowPos(WndShell, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
 
    WinStaObject->ShellWindow = hwndShell;
@@ -3350,9 +3489,12 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
    if (ti->pDeskInfo)
    {
        ti->pDeskInfo->hShellWindow = hwndShell;
+       ti->pDeskInfo->spwndShell = WndShell;
        ti->pDeskInfo->ppiShellProcess = ti->ppi;
    }
 
+   UserRegisterHotKey(WndShell, SC_TASKLIST, MOD_CONTROL, VK_ESCAPE);
+
    UserDerefObjectCo(WndShell);
 
    ObDereferenceObject(WinStaObject);
@@ -3364,105 +3506,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-/*
- * NtUserGetSystemMenu
- *
- * The NtUserGetSystemMenu function allows the application to access the
- * window menu (also known as the system menu or the control menu) for
- * copying and modifying.
- *
- * Parameters
- *    hWnd
- *       Handle to the window that will own a copy of the window menu.
- *    bRevert
- *       Specifies the action to be taken. If this parameter is FALSE,
- *       NtUserGetSystemMenu returns a handle to the copy of the window menu
- *       currently in use. The copy is initially identical to the window menu
- *       but it can be modified.
- *       If this parameter is TRUE, GetSystemMenu resets the window menu back
- *       to the default state. The previous window menu, if any, is destroyed.
- *
- * Return Value
- *    If the bRevert parameter is FALSE, the return value is a handle to a
- *    copy of the window menu. If the bRevert parameter is TRUE, the return
- *    value is NULL.
- *
- * Status
- *    @implemented
- */
-
-HMENU APIENTRY
-NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
-{
-   PWND Window;
-   PMENU_OBJECT Menu;
-   DECLARE_RETURN(HMENU);
-
-   TRACE("Enter NtUserGetSystemMenu\n");
-   UserEnterShared();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN(NULL);
-   }
-
-   if (!(Menu = IntGetSystemMenu(Window, bRevert, FALSE)))
-   {
-      RETURN(NULL);
-   }
-
-   RETURN(Menu->MenuInfo.Self);
-
-CLEANUP:
-   TRACE("Leave NtUserGetSystemMenu, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-/*
- * NtUserSetSystemMenu
- *
- * Status
- *    @implemented
- */
-
-BOOL APIENTRY
-NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
-{
-   BOOL Result = FALSE;
-   PWND Window;
-   PMENU_OBJECT Menu;
-   DECLARE_RETURN(BOOL);
-
-   TRACE("Enter NtUserSetSystemMenu\n");
-   UserEnterExclusive();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN( FALSE);
-   }
-
-   if (hMenu)
-   {
-      /*
-       * Assign new menu handle.
-       */
-      if (!(Menu = UserGetMenuObject(hMenu)))
-      {
-         RETURN( FALSE);
-      }
-
-      Result = IntSetSystemMenu(Window, Menu);
-   }
-
-   RETURN( Result);
-
-CLEANUP:
-   TRACE("Leave NtUserSetSystemMenu, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
 // Fixes wine Win test_window_styles and todo tests...
 static BOOL FASTCALL
 IntCheckFrameEdge(ULONG Style, ULONG ExStyle)
@@ -3552,6 +3595,12 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             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;
@@ -3594,7 +3643,7 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             break;
 
          default:
-            ERR("NtUserSetWindowLong(): Unsupported index %d\n", Index);
+            ERR("NtUserSetWindowLong(): Unsupported index %lu\n", Index);
             EngSetLastError(ERROR_INVALID_INDEX);
             OldValue = 0;
             break;
@@ -3693,7 +3742,7 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
    RETURN( OldValue);
 
 CLEANUP:
-   TRACE("Leave NtUserSetWindowWord, ret=%i\n",_ret_);
+   TRACE("Leave NtUserSetWindowWord, ret=%u\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -3718,6 +3767,10 @@ CLEANUP:
 DWORD APIENTRY
 NtUserQueryWindow(HWND hWnd, DWORD Index)
 {
+/* Console Leader Process CID Window offsets */
+#define GWLP_CONSOLE_LEADER_PID 0
+#define GWLP_CONSOLE_LEADER_TID 4
+
    PWND pWnd;
    DWORD Result;
    DECLARE_RETURN(UINT);
@@ -3733,12 +3786,34 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
    switch(Index)
    {
       case QUERY_WINDOW_UNIQUE_PROCESS_ID:
-         Result = (DWORD)IntGetWndProcessId(pWnd);
+      {
+         if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
+              (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
+         {
+            // IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_PID)
+            Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_PID)));
+         }
+         else
+         {
+            Result = (DWORD)IntGetWndProcessId(pWnd);
+         }
          break;
+      }
 
       case QUERY_WINDOW_UNIQUE_THREAD_ID:
-         Result = (DWORD)IntGetWndThreadId(pWnd);
+      {
+         if ( (pWnd->head.pti->TIF_flags & TIF_CSRSSTHREAD) &&
+              (pWnd->pcls->atomClassName == gaGuiConsoleWndClass) )
+         {
+            // IntGetWindowLong(offset == GWLP_CONSOLE_LEADER_TID)
+            Result = (DWORD)(*((LONG_PTR*)((PCHAR)(pWnd + 1) + GWLP_CONSOLE_LEADER_TID)));
+         }
+         else
+         {
+            Result = (DWORD)IntGetWndThreadId(pWnd);
+         }
          break;
+      }
 
       case QUERY_WINDOW_ACTIVE:
          Result = (DWORD)(pWnd->head.pti->MessageQueue->spwndActive ? UserHMGetHandle(pWnd->head.pti->MessageQueue->spwndActive) : 0);
@@ -3749,7 +3824,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
          break;
 
       case QUERY_WINDOW_ISHUNG:
-         Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue);
+         Result = (DWORD)MsqIsHung(pWnd->head.pti);
          break;
 
       case QUERY_WINDOW_REAL_ID:
@@ -3768,7 +3843,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
    RETURN( Result);
 
 CLEANUP:
-   TRACE("Leave NtUserQueryWindow, ret=%i\n",_ret_);
+   TRACE("Leave NtUserQueryWindow, ret=%u\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }
@@ -3807,7 +3882,7 @@ NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
    RETURN( Ret);
 
 CLEANUP:
-   TRACE("Leave NtUserRegisterWindowMessage, ret=%i\n",_ret_);
+   TRACE("Leave NtUserRegisterWindowMessage, ret=%u\n", _ret_);
    UserLeave();
    END_CLEANUP;
 }