[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / window.c
index 1e71a1c..4d80898 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-
-/* dialog resources appear to pass this in 16 bits, handle them properly */
-#define CW_USEDEFAULT16 (0x8000)
-
 #define POINT_IN_RECT(p, r) (((r.bottom >= p.y) && (r.top <= p.y))&&((r.left <= p.x )&&( r.right >= p.x )))
 
 /* PRIVATE FUNCTIONS **********************************************************/
@@ -29,7 +25,9 @@
  * Initialize windowing implementation.
  */
 
-NTSTATUS FASTCALL
+INIT_FUNCTION
+NTSTATUS
+NTAPI
 InitWindowImpl(VOID)
 {
    return STATUS_SUCCESS;
@@ -56,14 +54,14 @@ BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam)
 
     if (Flags & ~(UISF_HIDEFOCUS | UISF_HIDEACCEL | UISF_ACTIVE))
     {
-        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        EngSetLastError(ERROR_INVALID_PARAMETER);
         return FALSE;
     }
 
     switch (Action)
     {
         case UIS_INITIALIZE:
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            EngSetLastError(ERROR_INVALID_PARAMETER);
             return FALSE;
 
         case UIS_SET:
@@ -84,9 +82,9 @@ BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam)
     return TRUE;
 }
 
-PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
+PWND FASTCALL IntGetWindowObject(HWND hWnd)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
 
    if (!hWnd) return NULL;
 
@@ -96,45 +94,41 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
       ASSERT(Window->head.cLockObj >= 0);
 
       Window->head.cLockObj++;
-
-      ASSERT(Window->Wnd);
    }
    return Window;
 }
 
 /* temp hack */
-PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
+PWND FASTCALL UserGetWindowObject(HWND hWnd)
 {
    PTHREADINFO ti;
-   PWINDOW_OBJECT Window;
+   PWND Window;
 
    if (PsGetCurrentProcess() != PsInitialSystemProcess)
    {
        ti = GetW32ThreadInfo();
        if (ti == NULL)
        {
-          SetLastWin32Error(ERROR_ACCESS_DENIED);
+          EngSetLastError(ERROR_ACCESS_DENIED);
           return NULL;
        }
    }
 
    if (!hWnd)
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
 
-   Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
-   if (!Window || 0 != (Window->state & WINDOWSTATUS_DESTROYED))
+   Window = (PWND)UserGetObject(gHandleTable, hWnd, otWindow);
+   if (!Window || 0 != (Window->state & WNDS_DESTROYED))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
 
    ASSERT(Window->head.cLockObj >= 0);
 
-   ASSERT(Window->Wnd);
-
    return Window;
 }
 
@@ -158,7 +152,7 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
 BOOL FASTCALL
 IntIsWindow(HWND hWnd)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
 
    if (!(Window = UserGetWindowObject(hWnd)))
       return FALSE;
@@ -167,15 +161,14 @@ IntIsWindow(HWND hWnd)
 }
 
 
-
-PWINDOW_OBJECT FASTCALL
-IntGetParent(PWINDOW_OBJECT Wnd)
+PWND FASTCALL
+IntGetParent(PWND Wnd)
 {
-   if (Wnd->Wnd->style & WS_POPUP)
+   if (Wnd->style & WS_POPUP)
    {
        return Wnd->spwndOwner;
    }
-   else if (Wnd->Wnd->style & WS_CHILD)
+   else if (Wnd->style & WS_CHILD)
    {
       return Wnd->spwndParent;
    }
@@ -183,7 +176,6 @@ IntGetParent(PWINDOW_OBJECT Wnd)
    return NULL;
 }
 
-
 /*
  * IntWinListChildren
  *
@@ -195,9 +187,9 @@ IntGetParent(PWINDOW_OBJECT Wnd)
  */
 
 HWND* FASTCALL
-IntWinListChildren(PWINDOW_OBJECT Window)
+IntWinListChildren(PWND Window)
 {
-   PWINDOW_OBJECT Child;
+   PWND Child;
    HWND *List;
    UINT Index, NumChildren = 0;
 
@@ -206,17 +198,17 @@ IntWinListChildren(PWINDOW_OBJECT Window)
    for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
       ++NumChildren;
 
-   List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
+   List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), USERTAG_WINDOWLIST);
    if(!List)
    {
       DPRINT1("Failed to allocate memory for children array\n");
-      SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+      EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
       return NULL;
    }
    for (Child = Window->spwndChild, Index = 0;
          Child != NULL;
          Child = Child->spwndNext, ++Index)
-      List[Index] = Child->hSelf;
+      List[Index] = Child->head.h;
    List[Index] = NULL;
 
    return List;
@@ -228,7 +220,7 @@ IntWinListChildren(PWINDOW_OBJECT Window)
 static void IntSendDestroyMsg(HWND hWnd)
 {
 
-   PWINDOW_OBJECT Window;
+   PWND Window;
 #if 0 /* FIXME */
 
    GUITHREADINFO info;
@@ -297,17 +289,16 @@ static void IntSendDestroyMsg(HWND hWnd)
 }
 
 static VOID
-UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
+UserFreeWindowInfo(PTHREADINFO ti, PWND Wnd)
 {
     PCLIENTINFO ClientInfo = GetWin32ClientInfo();
-    PWND Wnd = WindowObject->Wnd;
 
     if (!Wnd) return;
-    
-    if (ClientInfo->CallbackWnd.pvWnd == DesktopHeapAddressToUser(WindowObject->Wnd))
+
+    if (ClientInfo->CallbackWnd.pWnd == DesktopHeapAddressToUser(Wnd))
     {
         ClientInfo->CallbackWnd.hWnd = NULL;
-        ClientInfo->CallbackWnd.pvWnd = NULL;
+        ClientInfo->CallbackWnd.pWnd = NULL;
     }
 
    if (Wnd->strName.Buffer != NULL)
@@ -319,8 +310,8 @@ UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
        Wnd->strName.Buffer = NULL;
    }
 
-    DesktopHeapFree(Wnd->head.rpdesk, Wnd);
-    WindowObject->Wnd = NULL;
+//    DesktopHeapFree(Wnd->head.rpdesk, Wnd);
+//    WindowObject->Wnd = NULL;
 }
 
 /***********************************************************************
@@ -332,31 +323,28 @@ UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
  * done in CreateWindow is undone here and not in DestroyWindow:-P
 
  */
-static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
+static LRESULT co_UserFreeWindow(PWND Window,
                                    PPROCESSINFO ProcessData,
                                    PTHREADINFO ThreadData,
                                    BOOLEAN SendMessages)
 {
    HWND *Children;
    HWND *ChildHandle;
-   PWINDOW_OBJECT Child;
+   PWND Child;
    PMENU_OBJECT Menu;
    BOOLEAN BelongsToThreadData;
-   PWND Wnd;
 
    ASSERT(Window);
 
-   Wnd = Window->Wnd;
-
-   if(Window->state & WINDOWSTATUS_DESTROYING)
+   if(Window->state2 & WNDS2_INDESTROY)
    {
       DPRINT("Tried to call IntDestroyWindow() twice\n");
       return 0;
    }
-   Window->state |= WINDOWSTATUS_DESTROYING;
-   Wnd->style &= ~WS_VISIBLE;
+   Window->state2 |= WNDS2_INDESTROY;
+   Window->style &= ~WS_VISIBLE;
 
-   IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Wnd, OBJID_WINDOW, 0);
+   IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Window, OBJID_WINDOW, CHILDID_SELF, 0);
 
    /* remove the window already at this point from the thread window list so we
       don't get into trouble when destroying the thread windows while we're still
@@ -365,12 +353,12 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 
    BelongsToThreadData = IntWndBelongsToThread(Window, ThreadData);
 
-   IntDeRegisterShellHookWindow(Window->hSelf);
+   IntDeRegisterShellHookWindow(Window->head.h);
 
    if(SendMessages)
    {
       /* Send destroy messages */
-      IntSendDestroyMsg(Window->hSelf);
+      IntSendDestroyMsg(Window->head.h);
    }
 
    /* free child windows */
@@ -384,7 +372,7 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
             if(!IntWndBelongsToThread(Child, ThreadData))
             {
                /* send WM_DESTROY messages to windows not belonging to the same thread */
-               IntSendDestroyMsg(Child->hSelf);
+               IntSendDestroyMsg(Child->head.h);
             }
             else
                co_UserFreeWindow(Child, ProcessData, ThreadData, SendMessages);
@@ -405,53 +393,53 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
                           RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE |
                           RDW_NOINTERNALPAINT | RDW_NOCHILDREN);
       if(BelongsToThreadData)
-         co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0);
+         co_IntSendMessage(Window->head.h, WM_NCDESTROY, 0, 0);
    }
+
    DestroyTimersForWindow(ThreadData, Window);
-   HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
+
+   /* Unregister hot keys */
+   UnregisterWindowHotKeys (Window);
 
    /* flush the message queue */
    MsqRemoveWindowMessagesFromQueue(Window);
 
    /* from now on no messages can be sent to this window anymore */
-   Window->state |= WINDOWSTATUS_DESTROYED;
-   Wnd->state |= WNDS_DESTROYED;
-   Wnd->fnid |= FNID_FREED;
+   Window->state |= WNDS_DESTROYED;
+   Window->fnid |= FNID_FREED;
 
    /* don't remove the WINDOWSTATUS_DESTROYING bit */
 
    /* reset shell window handles */
    if(ThreadData->rpdesk)
    {
-      if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
+      if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
          ThreadData->rpdesk->rpwinstaParent->ShellWindow = NULL;
 
-      if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellListView)
+      if (Window->head.h == ThreadData->rpdesk->rpwinstaParent->ShellListView)
          ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
    }
 
-   /* Unregister hot keys */
-   UnregisterWindowHotKeys (Window);
-
    /* FIXME: do we need to fake QS_MOUSEMOVE wakebit? */
 
 #if 0 /* FIXME */
 
-   WinPosCheckInternalPos(Window->hSelf);
-   if (Window->hSelf == GetCapture())
+   WinPosCheckInternalPos(Window->head.h);
+   if (Window->head.h == GetCapture())
    {
       ReleaseCapture();
    }
 
    /* free resources associated with the window */
-   TIMER_RemoveWindowTimers(Window->hSelf);
+   TIMER_RemoveWindowTimers(Window->head.h);
 #endif
 
-   if (!(Wnd->style & WS_CHILD) && Wnd->IDMenu
-       && (Menu = UserGetMenuObject((HMENU)Wnd->IDMenu)))
+   if ( ((Window->style & (WS_CHILD|WS_POPUP)) != WS_CHILD) &&
+        Window->IDMenu &&
+        (Menu = UserGetMenuObject((HMENU)Window->IDMenu)))
    {
       IntDestroyMenuObject(Menu, TRUE, TRUE);
-      Wnd->IDMenu = 0;
+      Window->IDMenu = 0;
    }
 
    if(Window->SystemMenu
@@ -471,23 +459,24 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
    IntUnlinkWindow(Window);
 
    UserReferenceObject(Window);
-   UserDeleteObject(Window->hSelf, otWindow);
+   UserDeleteObject(Window->head.h, otWindow);
 
    IntDestroyScrollBars(Window);
 
    /* dereference the class */
-   IntDereferenceClass(Wnd->pcls,
-                       Window->pti->pDeskInfo,
-                       Window->pti->ppi);
-   Wnd->pcls = NULL;
+   IntDereferenceClass(Window->pcls,
+                       Window->head.pti->pDeskInfo,
+                       Window->head.pti->ppi);
+   Window->pcls = NULL;
 
    if(Window->hrgnClip)
    {
       GreDeleteObject(Window->hrgnClip);
+      Window->hrgnClip = NULL;
    }
 
-   ASSERT(Window->Wnd != NULL);
-   UserFreeWindowInfo(Window->pti, Window);
+//   ASSERT(Window != NULL);
+   UserFreeWindowInfo(Window->head.pti, Window);
 
    UserDereferenceObject(Window);
 
@@ -497,9 +486,8 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 }
 
 VOID FASTCALL
-IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
+IntGetWindowBorderMeasures(PWND Wnd, UINT *cx, UINT *cy)
 {
-   PWND Wnd = Window->Wnd;
    if(HAS_DLGFRAME(Wnd->style, Wnd->ExStyle) && !(Wnd->style & WS_MINIMIZE))
    {
       *cx = UserGetSystemMetrics(SM_CXDLGFRAME);
@@ -667,36 +655,17 @@ IntSetWindowProc(PWND pWnd,
    return Ret;
 }
 
-// Move this to user space!
-BOOL FASTCALL
-IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
-{
-   PWND Wnd = Window->Wnd;
-
-   pwi->cbSize = sizeof(WINDOWINFO);
-   pwi->rcWindow = Window->Wnd->rcWindow;
-   pwi->rcClient = Window->Wnd->rcClient;
-   pwi->dwStyle = Wnd->style;
-   pwi->dwExStyle = Wnd->ExStyle;
-   pwi->dwWindowStatus = (UserGetForegroundWindow() == Window->hSelf); /* WS_ACTIVECAPTION */
-   IntGetWindowBorderMeasures(Window, &pwi->cxWindowBorders, &pwi->cyWindowBorders);
-   pwi->atomWindowType = (Wnd->pcls ? Wnd->pcls->atomClassName : 0);
-   pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
-   return TRUE;
-}
-
 static BOOL FASTCALL
 IntSetMenu(
-   PWINDOW_OBJECT Window,
+   PWND Wnd,
    HMENU Menu,
    BOOL *Changed)
 {
    PMENU_OBJECT OldMenu, NewMenu = NULL;
-   PWND Wnd = Window->Wnd;
 
    if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
    }
 
@@ -709,7 +678,7 @@ IntSetMenu(
    if (Wnd->IDMenu)
    {
       OldMenu = IntGetMenuObject((HMENU) Wnd->IDMenu);
-      ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Window->hSelf);
+      ASSERT(NULL == OldMenu || OldMenu->MenuInfo.Wnd == Wnd->head.h);
    }
    else
    {
@@ -725,7 +694,7 @@ IntSetMenu(
          {
             IntReleaseMenuObject(OldMenu);
          }
-         SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+         EngSetLastError(ERROR_INVALID_MENU_HANDLE);
          return FALSE;
       }
       if (NULL != NewMenu->MenuInfo.Wnd)
@@ -735,7 +704,7 @@ IntSetMenu(
          {
             IntReleaseMenuObject(OldMenu);
          }
-         SetLastWin32Error(ERROR_INVALID_MENU_HANDLE);
+         EngSetLastError(ERROR_INVALID_MENU_HANDLE);
          return FALSE;
       }
 
@@ -744,7 +713,7 @@ IntSetMenu(
    Wnd->IDMenu = (UINT) Menu;
    if (NULL != NewMenu)
    {
-      NewMenu->MenuInfo.Wnd = Window->hSelf;
+      NewMenu->MenuInfo.Wnd = Wnd->head.h;
       IntReleaseMenuObject(NewMenu);
    }
    if (NULL != OldMenu)
@@ -765,14 +734,14 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
 {
    PTHREADINFO WThread;
    PLIST_ENTRY Current;
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    USER_REFERENCE_ENTRY Ref;
    WThread = (PTHREADINFO)Thread->Tcb.Win32Thread;
 
    while (!IsListEmpty(&WThread->WindowListHead))
    {
       Current = WThread->WindowListHead.Flink;
-      Wnd = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+      Wnd = CONTAINING_RECORD(Current, WND, ThreadListEntry);
 
       DPRINT("thread cleanup: while destroy wnds, wnd=0x%x\n",Wnd);
 
@@ -803,38 +772,19 @@ co_DestroyThreadWindows(struct _ETHREAD *Thread)
  * \note Does not check the validity of the parameters
 */
 VOID FASTCALL
-IntGetClientRect(PWINDOW_OBJECT Window, RECTL *Rect)
+IntGetClientRect(PWND Window, RECTL *Rect)
 {
    ASSERT( Window );
    ASSERT( Rect );
 
    Rect->left = Rect->top = 0;
-   Rect->right = Window->Wnd->rcClient.right - Window->Wnd->rcClient.left;
-   Rect->bottom = Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top;
+   Rect->right = Window->rcClient.right - Window->rcClient.left;
+   Rect->bottom = Window->rcClient.bottom - Window->rcClient.top;
 }
 
 
-#if 0
-HWND FASTCALL
-IntGetFocusWindow(VOID)
-{
-   PUSER_MESSAGE_QUEUE Queue;
-   PDESKTOP pdo = IntGetActiveDesktop();
-
-   if( !pdo )
-      return NULL;
-
-   Queue = (PUSER_MESSAGE_QUEUE)pdo->ActiveMessageQueue;
-
-   if (Queue == NULL)
-      return(NULL);
-   else
-      return(Queue->FocusWindow);
-}
-#endif
-
 PMENU_OBJECT FASTCALL
-IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
+IntGetSystemMenu(PWND Window, BOOL bRevert, BOOL RetMenu)
 {
    PMENU_OBJECT Menu, NewMenu = NULL, SysMenu = NULL, ret = NULL;
    PTHREADINFO W32Thread;
@@ -870,7 +820,7 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
          {
             Window->SystemMenu = NewMenu->MenuInfo.Self;
             NewMenu->MenuInfo.Flags |= MF_SYSMENU;
-            NewMenu->MenuInfo.Wnd = Window->hSelf;
+            NewMenu->MenuInfo.Wnd = Window->head.h;
             ret = NewMenu;
             //IntReleaseMenuObject(NewMenu);
          }
@@ -889,7 +839,7 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
             return NULL;
          }
          SysMenu->MenuInfo.Flags |= MF_SYSMENU;
-         SysMenu->MenuInfo.Wnd = Window->hSelf;
+         SysMenu->MenuInfo.Wnd = Window->head.h;
          hNewMenu = co_IntLoadSysMenuTemplate();
          if(!hNewMenu)
          {
@@ -943,23 +893,17 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
 
 
 BOOL FASTCALL
-IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
+IntIsChildWindow(PWND Parent, PWND BaseWindow)
 {
-   PWINDOW_OBJECT Window;
-   PWND Wnd;
+   PWND Window;
 
    Window = BaseWindow;
-   while (Window)
+   while (Window && ((Window->style & (WS_POPUP|WS_CHILD)) == WS_CHILD))
    {
-      Wnd = Window->Wnd;
       if (Window == Parent)
       {
          return(TRUE);
       }
-      if(!(Wnd->style & WS_CHILD))
-      {
-         break;
-      }
 
       Window = Window->spwndParent;
    }
@@ -968,20 +912,18 @@ IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
 }
 
 BOOL FASTCALL
-IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
+IntIsWindowVisible(PWND BaseWindow)
 {
-   PWINDOW_OBJECT Window;
-   PWND Wnd;
+   PWND Window;
 
    Window = BaseWindow;
    while(Window)
    {
-      Wnd = Window->Wnd;
-      if(!(Wnd->style & WS_CHILD))
+      if(!(Window->style & WS_CHILD))
       {
          break;
       }
-      if(!(Wnd->style & WS_VISIBLE))
+      if(!(Window->style & WS_VISIBLE))
       {
          return FALSE;
       }
@@ -989,7 +931,7 @@ IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
       Window = Window->spwndParent;
    }
 
-   if(Window && Wnd->style & WS_VISIBLE)
+   if(Window && Window->style & WS_VISIBLE)
    {
       return TRUE;
    }
@@ -997,17 +939,21 @@ IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
    return FALSE;
 }
 
+
+/*
+   link the window into siblings list
+   children and parent are kept in place.
+*/
 VOID FASTCALL
-IntLinkWnd(
+IntLinkWindow(
    PWND Wnd,
-   PWND WndParent,
-   PWND WndPrevSibling) /* set to NULL if top sibling */
+   PWND WndInsertAfter /* set to NULL if top sibling */
+)
 {
-   Wnd->spwndParent = WndParent;
-   if ((Wnd->spwndPrev = WndPrevSibling))
+  if ((Wnd->spwndPrev = WndInsertAfter))
    {
-      /* link after WndPrevSibling */
-      if ((Wnd->spwndNext = WndPrevSibling->spwndNext))
+      /* link after WndInsertAfter */
+      if ((Wnd->spwndNext = WndInsertAfter->spwndNext))
          Wnd->spwndNext->spwndPrev = Wnd;
 
       Wnd->spwndPrev->spwndNext = Wnd;
@@ -1015,59 +961,104 @@ IntLinkWnd(
    else
    {
       /* link at top */
-      if ((Wnd->spwndNext = WndParent->spwndChild))
+     if ((Wnd->spwndNext = Wnd->spwndParent->spwndChild))
          Wnd->spwndNext->spwndPrev = Wnd;
-      
-      WndParent->spwndChild = Wnd;
-   }
 
+     Wnd->spwndParent->spwndChild = Wnd;
+   }
 }
 
-/* link the window into siblings and parent. children are kept in place. */
-VOID FASTCALL
-IntLinkWindow(
-   PWINDOW_OBJECT Wnd,
-   PWINDOW_OBJECT WndParent,
-   PWINDOW_OBJECT WndPrevSibling /* set to NULL if top sibling */
-)
+
+VOID FASTCALL IntLinkHwnd(PWND Wnd, HWND hWndPrev)
 {
-   PWINDOW_OBJECT Parent;
+    if (hWndPrev == HWND_NOTOPMOST)
+    {
+        if (!(Wnd->ExStyle & WS_EX_TOPMOST) &&
+            (Wnd->ExStyle2 & WS_EX2_LINKED)) return;  /* nothing to do */
+        Wnd->ExStyle &= ~WS_EX_TOPMOST;
+        hWndPrev = HWND_TOP;  /* fallback to the HWND_TOP case */
+    }
 
-   IntLinkWnd(Wnd->Wnd, 
-              WndParent->Wnd, 
-              WndPrevSibling ? WndPrevSibling->Wnd : NULL);
+    IntUnlinkWindow(Wnd);  /* unlink it from the previous location */
 
-   Wnd->spwndParent = WndParent;
-   if ((Wnd->spwndPrev = WndPrevSibling))
-   {
-      /* link after WndPrevSibling */
-      if ((Wnd->spwndNext = WndPrevSibling->spwndNext))
-         Wnd->spwndNext->spwndPrev = Wnd;
-      Wnd->spwndPrev->spwndNext = Wnd;
-   }
-   else
-   {
-      /* link at top */
-      Parent = Wnd->spwndParent;
-      if ((Wnd->spwndNext = WndParent->spwndChild))
-         Wnd->spwndNext->spwndPrev = Wnd;
-      else if (Parent)
-      {
-         Parent->spwndChild = Wnd;
-         return;
-      }
-      if(Parent)
-      {
-         Parent->spwndChild = Wnd;
-      }
-   }
+    if (hWndPrev == HWND_BOTTOM)
+    {
+        /* Link in the bottom of the list */
+        PWND WndInsertAfter;
+
+        WndInsertAfter = Wnd->spwndParent->spwndChild;
+        while( WndInsertAfter && WndInsertAfter->spwndNext)
+            WndInsertAfter = WndInsertAfter->spwndNext;
+
+        IntLinkWindow(Wnd, WndInsertAfter);
+        Wnd->ExStyle &= ~WS_EX_TOPMOST;
+    }
+    else if (hWndPrev == HWND_TOPMOST)
+    {
+        /* Link in the top of the list */
+        IntLinkWindow(Wnd, NULL);
+
+        Wnd->ExStyle |= WS_EX_TOPMOST;
+    }
+    else if (hWndPrev == HWND_TOP)
+    {
+        /* Link it after the last topmost window */
+        PWND WndInsertBefore;
+
+        WndInsertBefore = Wnd->spwndParent->spwndChild;
+
+        if (!(Wnd->ExStyle & WS_EX_TOPMOST))  /* put it above the first non-topmost window */
+        {
+            while (WndInsertBefore != NULL && WndInsertBefore->spwndNext != NULL)
+            {
+                if (!(WndInsertBefore->ExStyle & WS_EX_TOPMOST)) break;
+                if (WndInsertBefore == Wnd->spwndOwner)  /* keep it above owner */
+                {
+                    Wnd->ExStyle |= WS_EX_TOPMOST;
+                    break;
+                }
+                WndInsertBefore = WndInsertBefore->spwndNext;
+            }
+        }
+
+        IntLinkWindow(Wnd, WndInsertBefore ? WndInsertBefore->spwndPrev : NULL);
+    }
+    else
+    {
+        /* Link it after hWndPrev */
+        PWND WndInsertAfter;
+
+        WndInsertAfter = UserGetWindowObject(hWndPrev);
+        /* Are we called with an erroneous handle */
+        if(WndInsertAfter == NULL)
+        {
+            /* Link in a default position */
+            IntLinkHwnd(Wnd, HWND_TOP);
+            return;
+        }
+
+        IntLinkWindow(Wnd, WndInsertAfter);
 
+        /* Fix the WS_EX_TOPMOST flag */
+        if (!(WndInsertAfter->ExStyle & WS_EX_TOPMOST))
+        {
+            Wnd->ExStyle &= ~WS_EX_TOPMOST;
+        }
+        else
+        {
+            if(WndInsertAfter->spwndNext &&
+               WndInsertAfter->spwndNext->ExStyle & WS_EX_TOPMOST)
+            {
+                Wnd->ExStyle |= WS_EX_TOPMOST;
+            }
+        }
+    }
 }
 
 HWND FASTCALL
 IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 {
-   PWINDOW_OBJECT Wnd, WndOldOwner, WndNewOwner;
+   PWND Wnd, WndOldOwner, WndNewOwner;
    HWND ret;
 
    Wnd = IntGetWindowObject(hWnd);
@@ -1076,28 +1067,25 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner)
 
    WndOldOwner = Wnd->spwndOwner;
 
-   ret = WndOldOwner ? WndOldOwner->hSelf : 0;
+   ret = WndOldOwner ? WndOldOwner->head.h : 0;
 
    if((WndNewOwner = UserGetWindowObject(hWndNewOwner)))
    {
        Wnd->spwndOwner= WndNewOwner;
-       Wnd->Wnd->spwndOwner = WndNewOwner->Wnd;
    }
    else
    {
        Wnd->spwndOwner = NULL;
-       Wnd->Wnd->spwndOwner = NULL;
    }
 
    UserDereferenceObject(Wnd);
    return ret;
 }
 
-PWINDOW_OBJECT FASTCALL
-co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
+PWND FASTCALL
+co_IntSetParent(PWND Wnd, PWND WndNewParent)
 {
-   PWINDOW_OBJECT WndOldParent, Sibling, InsertAfter;
-//   HWND hWnd, hWndNewParent;
+   PWND WndOldParent, pWndExam;
    BOOL WasVisible;
 
    ASSERT(Wnd);
@@ -1105,28 +1093,39 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
    ASSERT_REFS_CO(Wnd);
    ASSERT_REFS_CO(WndNewParent);
 
-//   hWnd = Wnd->hSelf;
-//   hWndNewParent = WndNewParent->hSelf;
+   if (Wnd == Wnd->head.rpdesk->spwndMessage)
+   {
+      EngSetLastError(ERROR_ACCESS_DENIED);
+      return( NULL);
+   }
 
    /* Some applications try to set a child as a parent */
    if (IntIsChildWindow(Wnd, WndNewParent))
    {
-      SetLastWin32Error( ERROR_INVALID_PARAMETER );
+      EngSetLastError( ERROR_INVALID_PARAMETER );
       return NULL;
    }
 
+   pWndExam = WndNewParent; // Load parent Window to examine.
+   // Now test for set parent to parent hit.
+   while (pWndExam)
+   {
+      if (Wnd == pWndExam)
+      {
+         EngSetLastError(ERROR_INVALID_PARAMETER);
+         return NULL;
+      }
+      pWndExam = pWndExam->spwndParent;
+   }
+
    /*
     * Windows hides the window first, then shows it again
     * including the WM_SHOWWINDOW messages and all
     */
    WasVisible = co_WinPosShowWindow(Wnd, SW_HIDE);
 
-//   /* Validate that window and parent still exist */
-//   if (!IntIsWindow(hWnd) || !IntIsWindow(hWndNewParent))
-//      return NULL;
-
    /* Window must belong to current process */
-   if (Wnd->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
+   if (Wnd->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
       return NULL;
 
    WndOldParent = Wnd->spwndParent;
@@ -1135,36 +1134,24 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
 
    if (WndNewParent != WndOldParent)
    {
+      /* Unlink the window from the siblings list */
       IntUnlinkWindow(Wnd);
-      InsertAfter = NULL;
-      if (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST))
-      {
-         /* Not a TOPMOST window, put after TOPMOSTs of new parent */
-         Sibling = WndNewParent->spwndChild;
-         while (NULL != Sibling && 0 != (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
-         {
-            InsertAfter = Sibling;
-            Sibling = Sibling->spwndNext;
-         }
-      }
-      if (NULL == InsertAfter)
-      {
-         IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
-      }
-      else
-      {
-//         UserReferenceObject(InsertAfter);
-         IntLinkWindow(Wnd, WndNewParent, InsertAfter /*prev sibling*/);
-//         UserDereferenceObject(InsertAfter);
-      }
+
+      /* Set the new parent */
+      Wnd->spwndParent = WndNewParent;
+
+      /* Link the window with its new siblings*/
+      IntLinkHwnd(Wnd, HWND_TOP);
+
    }
 
+   IntNotifyWinEvent(EVENT_OBJECT_PARENTCHANGE, Wnd ,OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
    /*
     * SetParent additionally needs to make hwnd the top window
     * in the z-order and send the expected WM_WINDOWPOSCHANGING and
     * WM_WINDOWPOSCHANGED notification messages.
     */
-   co_WinPosSetWindowPos(Wnd, (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
+   co_WinPosSetWindowPos(Wnd, (0 == (Wnd->ExStyle & WS_EX_TOPMOST) ? HWND_TOP : HWND_TOPMOST),
                          0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE
                          | (WasVisible ? SWP_SHOWWINDOW : 0));
 
@@ -1173,28 +1160,67 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
     * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE
     */
 
-   /*
-    * Validate that the old parent still exist, since it migth have been
-    * destroyed during the last callbacks to user-mode
-    */
-//   if(WndOldParent)
-//   {
-//      if(!IntIsWindow(WndOldParent->hSelf))
-//      {
-//         UserDereferenceObject(WndOldParent);
-//         return NULL;
-//      }
-
-      /* don't dereference the window object here, it must be done by the caller
-         of IntSetParent() */
-//      return WndOldParent;
-//   }
-
-   return WndOldParent;//NULL;
+   return WndOldParent;
+}
+
+HWND FASTCALL
+co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
+{
+   PWND Wnd = NULL, WndParent = NULL, WndOldParent;
+   HWND hWndOldParent = NULL;
+   USER_REFERENCE_ENTRY Ref, ParentRef;
+
+   if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
+   {
+      EngSetLastError(ERROR_INVALID_PARAMETER);
+      return( NULL);
+   }
+
+   if (hWndChild == IntGetDesktopWindow())
+   {
+      EngSetLastError(ERROR_ACCESS_DENIED);
+      return( NULL);
+   }
+
+   if (hWndNewParent)
+   {
+      if (!(WndParent = UserGetWindowObject(hWndNewParent)))
+      {
+         return( NULL);
+      }
+   }
+   else
+   {
+      if (!(WndParent = UserGetWindowObject(IntGetDesktopWindow())))
+      {
+         return( NULL);
+      }
+   }
+
+   if (!(Wnd = UserGetWindowObject(hWndChild)))
+   {
+      return( NULL);
+   }
+
+   UserRefObjectCo(Wnd, &Ref);
+   UserRefObjectCo(WndParent, &ParentRef);
+
+   WndOldParent = co_IntSetParent(Wnd, WndParent);
+
+   UserDerefObjectCo(WndParent);
+   UserDerefObjectCo(Wnd);
+
+   if (WndOldParent)
+   {
+      hWndOldParent = WndOldParent->head.h;
+      UserDereferenceObject(WndOldParent);
+   }
+
+   return( hWndOldParent);
 }
 
 BOOL FASTCALL
-IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu)
+IntSetSystemMenu(PWND Window, PMENU_OBJECT Menu)
 {
    PMENU_OBJECT OldMenu;
    if(Window->SystemMenu)
@@ -1219,57 +1245,28 @@ IntSetSystemMenu(PWINDOW_OBJECT Window, PMENU_OBJECT Menu)
    return TRUE;
 }
 
-/* unlink the window from siblings and parent. children are kept in place. */
-VOID FASTCALL
-IntUnlinkWnd(PWND Wnd)
-{
-   if (Wnd->spwndNext)
-      Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
-
-   if (Wnd->spwndPrev)
-      Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
-  
-   if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
-      Wnd->spwndParent->spwndChild = Wnd->spwndNext;
-
-   Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL;
-}
-
-
-/* unlink the window from siblings and parent. children are kept in place. */
+/* unlink the window from siblings. children and parent are kept in place. */
 VOID FASTCALL
-IntUnlinkWindow(PWINDOW_OBJECT Wnd)
+IntUnlinkWindow(PWND Wnd)
 {
-   PWINDOW_OBJECT WndParent = Wnd->spwndParent;
-
-   IntUnlinkWnd(Wnd->Wnd);
-
    if (Wnd->spwndNext)
-      Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
+       Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
 
    if (Wnd->spwndPrev)
-      Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
-   else if (WndParent && WndParent->spwndChild == Wnd)
-      WndParent->spwndChild = Wnd->spwndNext;
+       Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
 
-   Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL;
-}
+   if (Wnd->spwndParent && Wnd->spwndParent->spwndChild == Wnd)
+       Wnd->spwndParent->spwndChild = Wnd->spwndNext;
 
-BOOL FASTCALL
-IntIsWindowInDestroy(PWINDOW_OBJECT Window)
-{
-   return ((Window->state & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
+   Wnd->spwndPrev = Wnd->spwndNext = NULL;
 }
 
-
 BOOL
 FASTCALL
-IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
+IntGetWindowPlacement(PWND Wnd, WINDOWPLACEMENT *lpwndpl)
 {
-   PWND Wnd;
    POINT Size;
 
-   Wnd = Window->Wnd;
    if (!Wnd) return FALSE;
 
    if(lpwndpl->length != sizeof(WINDOWPLACEMENT))
@@ -1282,7 +1279,7 @@ IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
    {
       lpwndpl->showCmd = SW_HIDE;
    }
-   else if (0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
+   else if (0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
             0 != (Wnd->style & WS_MAXIMIZE))
    {
       lpwndpl->showCmd = SW_MAXIMIZE;
@@ -1298,7 +1295,7 @@ IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
 
    Size.x = Wnd->rcWindow.left;
    Size.y = Wnd->rcWindow.top;
-   WinPosInitInternalPos(Window, &Size,
+   WinPosInitInternalPos(Wnd, &Size,
                          &Wnd->rcWindow);
 
    lpwndpl->rcNormalPosition = Wnd->InternalPos.NormalRect;
@@ -1311,19 +1308,6 @@ IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
 
 /* FUNCTIONS *****************************************************************/
 
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserAlterWindowStyle(DWORD Unknown0,
-                       DWORD Unknown1,
-                       DWORD Unknown2)
-{
-   UNIMPLEMENTED
-
-   return(0);
-}
-
 /*
  * As best as I can figure, this function is used by EnumWindows,
  * EnumChildWindows, EnumDesktopWindows, & EnumThreadWindows.
@@ -1355,7 +1339,7 @@ NtUserBuildHwndList(
    if (hwndParent || !dwThreadId)
    {
       PDESKTOP Desktop;
-      PWINDOW_OBJECT Parent, Window;
+      PWND Parent, Window;
 
       if(!hwndParent)
       {
@@ -1397,7 +1381,7 @@ NtUserBuildHwndList(
                   _SEH2_TRY
                   {
                      ProbeForWrite(pWnd, sizeof(HWND), 1);
-                     *pWnd = Window->hSelf;
+                     *pWnd = Window->head.h;
                      pWnd++;
                   }
                   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
@@ -1437,45 +1421,54 @@ NtUserBuildHwndList(
          ObDereferenceObject(Desktop);
       }
    }
-   else
+   else // Build EnumThreadWindows list!
    {
       PETHREAD Thread;
       PTHREADINFO W32Thread;
       PLIST_ENTRY Current;
-      PWINDOW_OBJECT Window;
+      PWND Window;
 
       Status = PsLookupThreadByThreadId((HANDLE)dwThreadId, &Thread);
-      if(!NT_SUCCESS(Status))
+      if (!NT_SUCCESS(Status))
       {
+         DPRINT1("Thread Id is not valid!\n");
          return ERROR_INVALID_PARAMETER;
       }
-      if(!(W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread))
+      if (!(W32Thread = (PTHREADINFO)Thread->Tcb.Win32Thread))
       {
          ObDereferenceObject(Thread);
-         DPRINT("Thread is not a GUI Thread!\n");
+         DPRINT1("Thread is not initialized!\n");
          return ERROR_INVALID_PARAMETER;
       }
 
       Current = W32Thread->WindowListHead.Flink;
-      while(Current != &(W32Thread->WindowListHead))
+      while (Current != &(W32Thread->WindowListHead))
       {
-         Window = CONTAINING_RECORD(Current, WINDOW_OBJECT, ThreadListEntry);
+         Window = CONTAINING_RECORD(Current, WND, ThreadListEntry);
          ASSERT(Window);
 
-         if(bChildren || Window->spwndOwner != NULL)
+         if (dwCount < *pBufSize && pWnd)
          {
-             if(dwCount < *pBufSize && pWnd)
-             {
-                Status = MmCopyToCaller(pWnd++, &Window->hSelf, sizeof(HWND));
-                if(!NT_SUCCESS(Status))
-                {
-                   SetLastNtError(Status);
-                   break;
-                }
-             }
-             dwCount++;
+            _SEH2_TRY
+            {
+               ProbeForWrite(pWnd, sizeof(HWND), 1);
+               *pWnd = Window->head.h;
+               pWnd++;
+            }
+            _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+            {
+               Status = _SEH2_GetExceptionCode();
+            }
+            _SEH2_END
+            if (!NT_SUCCESS(Status))
+            {
+               DPRINT1("Failure to build window list!\n");
+               SetLastNtError(Status);
+               break;
+            }
          }
-         Current = Current->Flink;
+         dwCount++;
+         Current = Window->ThreadListEntry.Flink;
       }
 
       ObDereferenceObject(Thread);
@@ -1495,7 +1488,7 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
                              LONG y,
                              UINT uiFlags)
 {
-   PWINDOW_OBJECT Parent;
+   PWND Parent;
    POINTL Pt;
    HWND Ret;
    HWND *List, *phWnd;
@@ -1508,10 +1501,10 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
    Pt.x = x;
    Pt.y = y;
 
-   if(Parent->hSelf != IntGetDesktopWindow())
+   if(Parent->head.h != IntGetDesktopWindow())
    {
-      Pt.x += Parent->Wnd->rcClient.left;
-      Pt.y += Parent->Wnd->rcClient.top;
+      Pt.x += Parent->rcClient.left;
+      Pt.y += Parent->rcClient.top;
    }
 
    if(!IntPtInWindow(Parent, Pt.x, Pt.y))
@@ -1519,31 +1512,29 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
       return NULL;
    }
 
-   Ret = Parent->hSelf;
+   Ret = Parent->head.h;
    if((List = IntWinListChildren(Parent)))
    {
       for(phWnd = List; *phWnd; phWnd++)
       {
-         PWINDOW_OBJECT Child;
-         PWND ChildWnd;
+         PWND Child;
          if((Child = UserGetWindowObject(*phWnd)))
          {
-            ChildWnd = Child->Wnd;
-            if(!(ChildWnd->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
+            if(!(Child->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
             {
                continue;
             }
-            if((ChildWnd->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
+            if((Child->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
             {
                continue;
             }
-            if((ChildWnd->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
+            if((Child->ExStyle & WS_EX_TRANSPARENT) && (uiFlags & CWP_SKIPTRANSPARENT))
             {
                continue;
             }
             if(IntPtInWindow(Child, Pt.x, Pt.y))
             {
-               Ret = Child->hSelf;
+               Ret = Child->head.h;
                break;
             }
          }
@@ -1554,18 +1545,34 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
    return Ret;
 }
 
+static void IntSendParentNotify( PWND pWindow, UINT msg )
+{
+    if ( (pWindow->style & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
+         !(pWindow->style & WS_EX_NOPARENTNOTIFY))
+    {
+        if (pWindow->spwndParent && pWindow->spwndParent != UserGetDesktopWindow())
+        {
+            co_IntSendMessage( pWindow->spwndParent->head.h,
+                               WM_PARENTNOTIFY,
+                               MAKEWPARAM( msg, pWindow->IDMenu),
+                               (LPARAM)pWindow->head.h );
+        }
+    }
+}
+
 void FASTCALL
-IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWINDOW_OBJECT ParentWindow, DWORD* dwShowMode)
+IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWND ParentWindow, DWORD* dwShowMode)
 {
 #define IS_DEFAULT(x)  ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000)
 
    /* default positioning for overlapped windows */
     if(!(Cs->style & (WS_POPUP | WS_CHILD)))
    {
-      RECTL WorkArea;
+      PMONITOR pMonitor;
       PRTL_USER_PROCESS_PARAMETERS ProcessParams;
 
-      UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
+      pMonitor = IntGetPrimaryMonitor();
+      ASSERT(pMonitor);
 
       ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
 
@@ -1580,8 +1587,17 @@ IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWINDOW_OBJECT ParentWindow, DWORD* d
           }
           else
           {
-              Cs->x = WorkArea.left;
-              Cs->y = WorkArea.top;
+               Cs->x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
+               Cs->y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
+               if (Cs->x > ((pMonitor->rcWork.right - pMonitor->rcWork.left) / 4) ||
+                   Cs->y > ((pMonitor->rcWork.bottom - pMonitor->rcWork.top) / 4))
+               {
+                  /* reset counter and position */
+                  Cs->x = 0;
+                  Cs->y = 0;
+                  pMonitor->cWndStack = 0;
+               }
+               pMonitor->cWndStack++;
           }
       }
 
@@ -1594,8 +1610,8 @@ IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWINDOW_OBJECT ParentWindow, DWORD* d
           }
           else
           {
-              Cs->cx = (WorkArea.right - WorkArea.left) * 3 / 4 - Cs->x;
-              Cs->cy = (WorkArea.bottom - WorkArea.top) * 3 / 4 - Cs->y;
+              Cs->cx = (pMonitor->rcWork.right - pMonitor->rcWork.left) * 3 / 4;
+              Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
           }
       }
       /* neither x nor cx are default. Check the y values .
@@ -1605,7 +1621,7 @@ IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWINDOW_OBJECT ParentWindow, DWORD* d
       else if (IS_DEFAULT(Cs->cy))
       {
           DPRINT("Strange use of CW_USEDEFAULT in nHeight\n");
-          Cs->cy = (WorkArea.bottom - WorkArea.top) * 3 / 4 - Cs->y;
+          Cs->cy = (pMonitor->rcWork.bottom - pMonitor->rcWork.top) * 3 / 4;
       }
    }
    else
@@ -1627,14 +1643,13 @@ IntFixWindowCoordinates(CREATESTRUCTW* Cs, PWINDOW_OBJECT ParentWindow, DWORD* d
 }
 
 /* Allocates and initializes a window*/
-PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs, 
-                                        PLARGE_STRING WindowName, 
+PWND FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
+                                        PLARGE_STRING WindowName,
                                         PCLS Class,
-                                        PWINDOW_OBJECT ParentWindow,
-                                        PWINDOW_OBJECT OwnerWindow)
+                                        PWND ParentWindow,
+                                        PWND OwnerWindow)
 {
-   PWND Wnd = NULL;
-   PWINDOW_OBJECT Window;
+   PWND pWnd = NULL;
    HWND hWnd;
    PTHREADINFO pti = NULL;
    PMENU_OBJECT SystemMenu;
@@ -1643,6 +1658,33 @@ PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
 
    pti = PsGetCurrentThreadWin32Thread();
 
+   if (!(Cs->dwExStyle & WS_EX_LAYOUTRTL))
+   {
+      if (ParentWindow)
+      {
+         if ( (Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD &&
+              ParentWindow->ExStyle & WS_EX_LAYOUTRTL &&
+             !(ParentWindow->ExStyle & WS_EX_NOINHERITLAYOUT) )
+            Cs->dwExStyle |= WS_EX_LAYOUTRTL;
+      }
+      else
+      {/*
+        Note from MSDN http://msdn.microsoft.com/en-us/library/aa913269.aspx :
+
+        Dialog boxes and message boxes do not inherit layout, so you must
+        set the layout explicitly.
+       */
+         if ( Class && Class->fnid != FNID_DIALOG)
+         {
+            PPROCESSINFO ppi = PsGetCurrentProcessWin32Process();
+            if (ppi->dwLayout & LAYOUT_RTL)
+            {
+               Cs->dwExStyle |= WS_EX_LAYOUTRTL;
+            }
+         }
+      }
+   }
+
    /* Automatically add WS_EX_WINDOWEDGE */
    if ((Cs->dwExStyle & WS_EX_DLGMODALFRAME) ||
          ((!(Cs->dwExStyle & WS_EX_STATICEDGE)) &&
@@ -1656,66 +1698,50 @@ PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    Cs->dwExStyle &= ~WS_EX_SETANSICREATOR;
 
    /* Allocate the new window */
-   Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable,
-                                               pti->rpdesk,
-                                               (PHANDLE)&hWnd,
-                                               otWindow,
-                                               sizeof(WINDOW_OBJECT));
-   if (!Window)
-   {
-      goto AllocError;
-   }
-
-   Wnd = DesktopHeapAlloc(pti->rpdesk, sizeof(WND) + Class->cbwndExtra);
+   pWnd = (PWND) UserCreateObject( gHandleTable,
+                                   pti->rpdesk,
+                                  (PHANDLE)&hWnd,
+                                   otWindow,
+                                   sizeof(WND) + Class->cbwndExtra);
 
-   if (!Wnd)
+   if (!pWnd)
    {
       goto AllocError;
    }
 
-   RtlZeroMemory(Wnd, sizeof(WND) + Class->cbwndExtra);
-
    DPRINT("Created object with handle %X\n", hWnd);
 
    if (NULL == pti->rpdesk->DesktopWindow)
    {
       /* If there is no desktop window yet, we must be creating it */
       pti->rpdesk->DesktopWindow = hWnd;
-      pti->rpdesk->pDeskInfo->spwnd = Wnd;
+      pti->rpdesk->pDeskInfo->spwnd = pWnd;
    }
 
    /*
     * Fill out the structure describing it.
     */
-   Window->Wnd = Wnd;
-   Window->pti = pti;
-   Window->hSelf = hWnd;
-   Window->spwndParent = ParentWindow;
-   Window->spwndOwner = OwnerWindow;
-
-   Wnd->head.h = hWnd;
-   Wnd->head.pti = pti;
-   Wnd->head.rpdesk = pti->rpdesk;
-   Wnd->fnid = 0;
-   Wnd->hWndLastActive = hWnd;
-   Wnd->state2 |= WNDS2_WIN40COMPAT;
-   Wnd->pcls = Class;
-   Wnd->hModule = Cs->hInstance;
-   Wnd->style = Cs->style & ~WS_VISIBLE;
-   Wnd->ExStyle = Cs->dwExStyle;
-   Wnd->cbwndExtra = Wnd->pcls->cbwndExtra;
-   Wnd->spwndOwner = OwnerWindow ? OwnerWindow->Wnd : NULL;
-   Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL;      
-
-   IntReferenceMessageQueue(Window->pti->MessageQueue);
-   if (Wnd->spwndParent != NULL && Cs->hwndParent != 0)
-   {
-       Wnd->HideFocus = Wnd->spwndParent->HideFocus;
-       Wnd->HideAccel = Wnd->spwndParent->HideAccel;
-   }
-
-   if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
-      Wnd->state |= WNDS_SERVERSIDEWINDOWPROC;
+   /* Remember, pWnd->head is setup in object.c ...*/
+   pWnd->spwndParent = ParentWindow;
+   pWnd->spwndOwner = OwnerWindow;
+   pWnd->fnid = 0;
+   pWnd->hWndLastActive = hWnd;
+   pWnd->state2 |= WNDS2_WIN40COMPAT;
+   pWnd->pcls = Class;
+   pWnd->hModule = Cs->hInstance;
+   pWnd->style = Cs->style & ~WS_VISIBLE;
+   pWnd->ExStyle = Cs->dwExStyle;
+   pWnd->cbwndExtra = pWnd->pcls->cbwndExtra;
+
+   IntReferenceMessageQueue(pWnd->head.pti->MessageQueue);
+   if (pWnd->spwndParent != NULL && Cs->hwndParent != 0)
+   {
+       pWnd->HideFocus = pWnd->spwndParent->HideFocus;
+       pWnd->HideAccel = pWnd->spwndParent->HideAccel;
+   }
+
+   if (pWnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
+      pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
 
  /* BugBoy Comments: Comment below say that System classes are always created
     as UNICODE. In windows, creating a window with the ANSI version of CreateWindow
@@ -1726,31 +1752,31 @@ PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
     see what problems this would cause.*/
 
    // Set WndProc from Class.
-   Wnd->lpfnWndProc  = Wnd->pcls->lpfnWndProc;
+   pWnd->lpfnWndProc  = pWnd->pcls->lpfnWndProc;
 
    // GetWindowProc, test for non server side default classes and set WndProc.
-    if ( Wnd->pcls->fnid <= FNID_GHOST && Wnd->pcls->fnid >= FNID_BUTTON )
+    if ( pWnd->pcls->fnid <= FNID_GHOST && pWnd->pcls->fnid >= FNID_BUTTON )
     {
       if (bUnicodeWindow)
       {
-         if (GETPFNCLIENTA(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
-            Wnd->lpfnWndProc = GETPFNCLIENTW(Wnd->pcls->fnid);  
+         if (GETPFNCLIENTA(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
+            pWnd->lpfnWndProc = GETPFNCLIENTW(pWnd->pcls->fnid);
       }
       else
       {
-         if (GETPFNCLIENTW(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
-            Wnd->lpfnWndProc = GETPFNCLIENTA(Wnd->pcls->fnid);
+         if (GETPFNCLIENTW(pWnd->pcls->fnid) == pWnd->lpfnWndProc)
+            pWnd->lpfnWndProc = GETPFNCLIENTA(pWnd->pcls->fnid);
       }
     }
 
    // If not an Unicode caller, set Ansi creator bit.
-   if (!bUnicodeWindow) Wnd->state |= WNDS_ANSICREATOR;
+   if (!bUnicodeWindow) pWnd->state |= WNDS_ANSICREATOR;
 
    // Clone Class Ansi/Unicode proc type.
-   if (Wnd->pcls->CSF_flags & CSF_ANSIPROC)
+   if (pWnd->pcls->CSF_flags & CSF_ANSIPROC)
    {
-      Wnd->state |= WNDS_ANSIWINDOWPROC;
-      Wnd->Unicode = FALSE;
+      pWnd->state |= WNDS_ANSIWINDOWPROC;
+      pWnd->Unicode = FALSE;
    }
    else
    { /*
@@ -1768,76 +1794,76 @@ PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
             Class->atomClassName == gpsi->atomSysClass[ICLS_MDICLIENT] ||
             Class->atomClassName == gpsi->atomSysClass[ICLS_STATIC] ) )
       { // Override Class and set the window Ansi WndProc.
-         Wnd->state |= WNDS_ANSIWINDOWPROC;
-         Wnd->Unicode = FALSE;
+         pWnd->state |= WNDS_ANSIWINDOWPROC;
+         pWnd->Unicode = FALSE;
       }
       else
       { // Set the window Unicode WndProc.
-         Wnd->state &= ~WNDS_ANSIWINDOWPROC;
-         Wnd->Unicode = TRUE;
+         pWnd->state &= ~WNDS_ANSIWINDOWPROC;
+         pWnd->Unicode = TRUE;
       }
    }
 
    /* BugBoy Comments: if the window being created is a edit control, ATOM 0xCxxx,
-      then my testing shows that windows (2k and XP) creates a CallProc for it immediately 
+      then my testing shows that windows (2k and XP) creates a CallProc for it immediately
       Dont understand why it does this. */
    if (Class->atomClassName == gpsi->atomSysClass[ICLS_EDIT])
    {
       PCALLPROCDATA CallProc;
-      //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi);
-      CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi);
+      CallProc = CreateCallProc(NULL, pWnd->lpfnWndProc, pWnd->Unicode , pWnd->head.pti->ppi);
 
       if (!CallProc)
       {
-         SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+         EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
          DPRINT1("Warning: Unable to create CallProc for edit control. Control may not operate correctly! hwnd %x\n",hWnd);
       }
       else
       {
-         UserAddCallProcToClass(Wnd->pcls, CallProc);
+         UserAddCallProcToClass(pWnd->pcls, CallProc);
       }
    }
 
-   InitializeListHead(&Wnd->PropListHead);
+   InitializeListHead(&pWnd->PropListHead);
 
    if ( WindowName->Buffer != NULL && WindowName->Length > 0 )
    {
-      Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk,
+      pWnd->strName.Buffer = DesktopHeapAlloc(pWnd->head.rpdesk,
                                              WindowName->Length + sizeof(UNICODE_NULL));
-      if (Wnd->strName.Buffer == NULL)
+      if (pWnd->strName.Buffer == NULL)
       {
           goto AllocError;
       }
 
-      RtlCopyMemory(Wnd->strName.Buffer, WindowName->Buffer, WindowName->Length);
-      Wnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
-      Wnd->strName.Length = WindowName->Length;
+      RtlCopyMemory(pWnd->strName.Buffer, WindowName->Buffer, WindowName->Length);
+      pWnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
+      pWnd->strName.Length = WindowName->Length;
+      pWnd->strName.MaximumLength = WindowName->Length + sizeof(UNICODE_NULL);
    }
 
    /* Correct the window style. */
-   if ((Wnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
+   if ((pWnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
    {
-      Wnd->style |= WS_CLIPSIBLINGS;
-      if (!(Wnd->style & WS_POPUP))
+      pWnd->style |= WS_CLIPSIBLINGS;
+      if (!(pWnd->style & WS_POPUP))
       {
-         Wnd->style |= WS_CAPTION;
-         Window->state |= WINDOWOBJECT_NEED_SIZE;
+         pWnd->style |= WS_CAPTION;
+         pWnd->state |= WNDS_SENDSIZEMOVEMSGS;
       }
    }
 
-   if ((Wnd->ExStyle & WS_EX_DLGMODALFRAME) ||
-          (Wnd->style & (WS_DLGFRAME | WS_THICKFRAME)))
-        Wnd->ExStyle |= WS_EX_WINDOWEDGE;
+   if ((pWnd->ExStyle & WS_EX_DLGMODALFRAME) ||
+          (pWnd->style & (WS_DLGFRAME | WS_THICKFRAME)))
+        pWnd->ExStyle |= WS_EX_WINDOWEDGE;
     else
-        Wnd->ExStyle &= ~WS_EX_WINDOWEDGE;
+        pWnd->ExStyle &= ~WS_EX_WINDOWEDGE;
 
    /* create system menu */
    if((Cs->style & WS_SYSMENU) )//&& (dwStyle & WS_CAPTION) == WS_CAPTION)
    {
-      SystemMenu = IntGetSystemMenu(Window, TRUE, TRUE);
+      SystemMenu = IntGetSystemMenu(pWnd, TRUE, TRUE);
       if(SystemMenu)
       {
-         Window->SystemMenu = SystemMenu->MenuInfo.Self;
+         pWnd->SystemMenu = SystemMenu->MenuInfo.Self;
          IntReleaseMenuObject(SystemMenu);
       }
    }
@@ -1846,52 +1872,49 @@ PWINDOW_OBJECT FASTCALL IntCreateWindow(CREATESTRUCTW* Cs,
    if ((Cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
    {
        if (Cs->hMenu)
-         IntSetMenu(Window, Cs->hMenu, &MenuChanged);
-      else if (Wnd->pcls->lpszMenuName) // Take it from the parent.
+         IntSetMenu(pWnd, Cs->hMenu, &MenuChanged);
+      else if (pWnd->pcls->lpszMenuName) // Take it from the parent.
       {
           UNICODE_STRING MenuName;
           HMENU hMenu;
 
-          if (IS_INTRESOURCE(Wnd->pcls->lpszMenuName))
+          if (IS_INTRESOURCE(pWnd->pcls->lpszMenuName))
           {
              MenuName.Length = 0;
              MenuName.MaximumLength = 0;
-             MenuName.Buffer = Wnd->pcls->lpszMenuName;
+             MenuName.Buffer = pWnd->pcls->lpszMenuName;
           }
           else
           {
-             RtlInitUnicodeString( &MenuName, Wnd->pcls->lpszMenuName);
+             RtlInitUnicodeString( &MenuName, pWnd->pcls->lpszMenuName);
           }
-          hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
-          if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
+          hMenu = co_IntCallLoadMenu( pWnd->pcls->hModule, &MenuName);
+          if (hMenu) IntSetMenu(pWnd, hMenu, &MenuChanged);
       }
    }
    else // Not a child
-      Wnd->IDMenu = (UINT) Cs->hMenu;
+      pWnd->IDMenu = (UINT) Cs->hMenu;
 
    /* Insert the window into the thread's window list. */
-   InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry);
+   InsertTailList (&pti->WindowListHead, &pWnd->ThreadListEntry);
 
    /*  Handle "CS_CLASSDC", it is tested first. */
-   if ( (Wnd->pcls->style & CS_CLASSDC) && !(Wnd->pcls->pdce) )
+   if ( (pWnd->pcls->style & CS_CLASSDC) && !(pWnd->pcls->pdce) )
    {  /* One DCE per class to have CLASS. */
-      Wnd->pcls->pdce = DceAllocDCE( Window, DCE_CLASS_DC );
+      pWnd->pcls->pdce = DceAllocDCE( pWnd, DCE_CLASS_DC );
    }
-   else if ( Wnd->pcls->style & CS_OWNDC)
+   else if ( pWnd->pcls->style & CS_OWNDC)
    {  /* Allocate a DCE for this window. */
-      DceAllocDCE(Window, DCE_WINDOW_DC);
+      DceAllocDCE(pWnd, DCE_WINDOW_DC);
    }
 
-   return Window;
+   return pWnd;
 
 AllocError:
 
-   if(Window)
-      UserDereferenceObject(Window);
+   if(pWnd)
+      UserDereferenceObject(pWnd);
 
-   if(Wnd)
-       DesktopHeapFree(Wnd->head.rpdesk, Wnd);
-   
    SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
    return NULL;
 }
@@ -1904,19 +1927,19 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
                      PUNICODE_STRING ClassName,
                      PLARGE_STRING WindowName)
 {
-   PWINDOW_OBJECT Window = NULL, ParentWindow = NULL, OwnerWindow;
-   HWND hWnd, hWndParent, hWndOwner;
-   DWORD dwStyle;
+   PWND Window = NULL, ParentWindow = NULL, OwnerWindow;
+   HWND hWnd, hWndParent, hWndOwner, hwndInsertAfter;
    PWINSTATION_OBJECT WinSta;
-   PWND Wnd = NULL;
    PCLS Class = NULL;
    SIZE Size;
    POINT MaxPos;
-   CBT_CREATEWNDW CbtCreate;
+   CBT_CREATEWNDW * pCbtCreate;
    LRESULT Result;
    USER_REFERENCE_ENTRY ParentRef, Ref;
    PTHREADINFO pti;
    DWORD dwShowMode = SW_SHOW;
+   CREATESTRUCTW *pCsw = NULL;
+   PVOID pszClass = NULL, pszName = NULL;
    DECLARE_RETURN(PWND);
 
    /* Get the current window station and reference it */
@@ -1929,6 +1952,9 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    WinSta = pti->rpdesk->rpwinstaParent;
    ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
 
+   pCsw = NULL;
+   pCbtCreate = NULL;
+
    /* Get the class and reference it*/
    Class = IntGetAndReferenceClass(ClassName, Cs->hInstance);
    if(!Class)
@@ -1955,7 +1981,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
     else if ((Cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
     {
          DPRINT1("Cannot create a child window without a parrent!\n");
-         SetLastWin32Error(ERROR_TLW_WITH_WSCHILD);
+         EngSetLastError(ERROR_TLW_WITH_WSCHILD);
          RETURN(NULL);  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
     }
 
@@ -1967,17 +1993,17 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
         OwnerWindow = UserGetAncestor(OwnerWindow, GA_ROOT);
 
    /* Fix the position and the size of the window */
-   if (ParentWindow) 
+   if (ParentWindow)
    {
        UserRefObjectCo(ParentWindow, &ParentRef);
        IntFixWindowCoordinates(Cs, ParentWindow, &dwShowMode);
    }
 
    /* Allocate and initialize the new window */
-   Window = IntCreateWindow(Cs, 
-                            WindowName, 
-                            Class, 
-                            ParentWindow, 
+   Window = IntCreateWindow(Cs,
+                            WindowName,
+                            Class,
+                            ParentWindow,
                             OwnerWindow);
    if(!Window)
    {
@@ -1985,32 +2011,101 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
        RETURN(0);
    }
 
-   Wnd = Window->Wnd;
-   hWnd = Window->hSelf;
+   hWnd = UserHMGetHandle(Window);
+   hwndInsertAfter = HWND_TOP;
 
    UserRefObjectCo(Window, &Ref);
    ObDereferenceObject(WinSta);
 
-   /* Call the WH_CBT hook */
-   dwStyle = Cs->style;
-   Cs->style = Wnd->style; /* HCBT_CREATEWND needs the real window style */
-   CbtCreate.lpcs = Cs;
-   CbtCreate.hwndInsertAfter = HWND_TOP;
-   if (ISITHOOKED(WH_CBT))
+   //// Check for a hook to eliminate overhead. ////
+   if ( ISITHOOKED(WH_CBT) ||  (pti->rpdesk->pDeskInfo->fsHooks & HOOKID_TO_FLAG(WH_CBT)) )
    {
-      if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
-      {
-         DPRINT1("HCBT_CREATEWND hook failed!\n");
-         RETURN( (PWND) NULL);
-      }
-   }
-   Cs->style = dwStyle; /* NCCREATE and WM_NCCALCSIZE need the original values*/
+      // Allocate the calling structures Justin Case this goes Global.
+      pCsw = ExAllocatePoolWithTag(NonPagedPool, sizeof(CREATESTRUCTW), TAG_HOOK);
+      pCbtCreate = ExAllocatePoolWithTag(NonPagedPool, sizeof(CBT_CREATEWNDW), TAG_HOOK);
 
-   /* Send the WM_GETMINMAXINFO message*/
+      /* Fill the new CREATESTRUCTW */
+      RtlCopyMemory(pCsw, Cs, sizeof(CREATESTRUCTW));
+      pCsw->style = Window->style; /* HCBT_CREATEWND needs the real window style */
+
+      // Based on the assumption this is from "unicode source" user32, ReactOS, answer is yes.
+      if (!IS_ATOM(ClassName->Buffer))
+      {
+         if (Window->state & WNDS_ANSICREATOR)
+         {
+            ANSI_STRING AnsiString;
+            AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(ClassName)+sizeof(CHAR);
+            pszClass = UserHeapAlloc(AnsiString.MaximumLength);
+            RtlZeroMemory(pszClass, AnsiString.MaximumLength);
+            AnsiString.Buffer = (PCHAR)pszClass;
+            RtlUnicodeStringToAnsiString(&AnsiString, ClassName, FALSE);
+         }
+         else
+         {
+            UNICODE_STRING UnicodeString;
+            UnicodeString.MaximumLength = ClassName->Length + sizeof(UNICODE_NULL);
+            pszClass = UserHeapAlloc(UnicodeString.MaximumLength);
+            RtlZeroMemory(pszClass, UnicodeString.MaximumLength);
+            UnicodeString.Buffer = (PWSTR)pszClass;
+            RtlCopyUnicodeString(&UnicodeString, ClassName);
+         }
+         if (pszClass) pCsw->lpszClass = UserHeapAddressToUser(pszClass);
+      }
+      if (WindowName->Length)
+      {
+         UNICODE_STRING Name;
+         Name.Buffer = WindowName->Buffer;
+         Name.Length = WindowName->Length;
+         Name.MaximumLength = WindowName->MaximumLength;
+
+         if (Window->state & WNDS_ANSICREATOR)
+         {
+            ANSI_STRING AnsiString;
+            AnsiString.MaximumLength = RtlUnicodeStringToAnsiSize(&Name)+sizeof(CHAR);
+            pszName = UserHeapAlloc(AnsiString.MaximumLength);
+            RtlZeroMemory(pszName, AnsiString.MaximumLength);
+            AnsiString.Buffer = (PCHAR)pszName;
+            RtlUnicodeStringToAnsiString(&AnsiString, &Name, FALSE);
+         }
+         else
+         {
+            UNICODE_STRING UnicodeString;
+            UnicodeString.MaximumLength = Name.Length + sizeof(UNICODE_NULL);
+            pszName = UserHeapAlloc(UnicodeString.MaximumLength);
+            RtlZeroMemory(pszName, UnicodeString.MaximumLength);
+            UnicodeString.Buffer = (PWSTR)pszName;
+            RtlCopyUnicodeString(&UnicodeString, &Name);
+         }
+         if (pszName) pCsw->lpszName = UserHeapAddressToUser(pszName);
+      }
+
+      pCbtCreate->lpcs = pCsw;
+      pCbtCreate->hwndInsertAfter = hwndInsertAfter;
+
+      //// Call the WH_CBT hook ////
+      Result = co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) pCbtCreate);
+      if (Result != 0)
+      {
+         DPRINT1("WH_CBT HCBT_CREATEWND hook failed! 0x%x\n", Result);
+         RETURN( (PWND) NULL);
+      }
+      // Write back changes.
+      Cs->cx = pCsw->cx;
+      Cs->cy = pCsw->cy;
+      Cs->x = pCsw->x;
+      Cs->y = pCsw->y;
+      hwndInsertAfter = pCbtCreate->hwndInsertAfter;
+   }
+
+   /* NCCREATE and WM_NCCALCSIZE need the original values */
+   Cs->lpszName = (LPCWSTR) WindowName;
+   Cs->lpszClass = (LPCWSTR) ClassName;
+
+   /* Send the WM_GETMINMAXINFO message*/
    Size.cx = Cs->cx;
    Size.cy = Cs->cy;
 
-   if ((dwStyle & WS_THICKFRAME) || !(dwStyle & (WS_POPUP | WS_CHILD)))
+   if ((Cs->style & WS_THICKFRAME) || !(Cs->style & (WS_POPUP | WS_CHILD)))
    {
       POINT MaxSize, MaxPos, MinTrack, MaxTrack;
 
@@ -2021,63 +2116,30 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
       if (Size.cy < MinTrack.y) Size.cy = MinTrack.y;
    }
 
-   Wnd->rcWindow.left = Cs->x;
-   Wnd->rcWindow.top = Cs->y;
-   Wnd->rcWindow.right = Cs->x + Size.cx;
-   Wnd->rcWindow.bottom = Cs->y + Size.cy;
-   if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
+   Window->rcWindow.left = Cs->x;
+   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)
    {
-      RECTL_vOffsetRect(&Wnd->rcWindow, 
-                        ParentWindow->Wnd->rcClient.left,
-                        ParentWindow->Wnd->rcClient.top);
+      RECTL_vOffsetRect(&Window->rcWindow,
+                        ParentWindow->rcClient.left,
+                        ParentWindow->rcClient.top);
    }
-   Wnd->rcClient = Wnd->rcWindow;
-
+   Window->rcClient = Window->rcWindow;
 
    /* Link the window*/
    if (NULL != ParentWindow)
    {
-      /* link the window into the parent's child list */
-      if ((dwStyle & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
-      {
-         PWINDOW_OBJECT PrevSibling;
-
-         PrevSibling = ParentWindow->spwndChild;
-
-         if(PrevSibling)
-         {
-            while (PrevSibling->spwndNext)
-               PrevSibling = PrevSibling->spwndNext;
-         }
-
-         /* link window as bottom sibling */
-         IntLinkWindow(Window, ParentWindow, PrevSibling /*prev sibling*/);
-      }
+      /* link the window into the siblings list */
+      if ((Cs->style & (WS_CHILD|WS_MAXIMIZE)) == WS_CHILD)
+          IntLinkHwnd(Window, HWND_BOTTOM);
       else
-      {
-         /* link window as top sibling (but after topmost siblings) */
-         PWINDOW_OBJECT InsertAfter, Sibling;
-         if (!(Cs->dwExStyle & WS_EX_TOPMOST))
-         {
-            InsertAfter = NULL;
-            Sibling = ParentWindow->spwndChild;
-            while (Sibling && (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
-            {
-               InsertAfter = Sibling;
-               Sibling = Sibling->spwndNext;
-            }
-         }
-         else
-         {
-            InsertAfter = NULL;
-         }
-
-         IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */);
-      }
+          IntLinkHwnd(Window, hwndInsertAfter);
    }
-   
+
    /* Send the NCCREATE message */
-   Result = co_IntSendMessage(Window->hSelf, WM_NCCREATE, 0, (LPARAM) Cs);
+   Result = co_IntSendMessage(UserHMGetHandle(Window), WM_NCCREATE, 0, (LPARAM) Cs);
    if (!Result)
    {
       DPRINT1("co_UserCreateWindowEx(): NCCREATE message failed\n");
@@ -2085,49 +2147,48 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    }
 
    /* Send the WM_NCCALCSIZE message */
-   MaxPos.x = Window->Wnd->rcWindow.left;
-   MaxPos.y = Window->Wnd->rcWindow.top;
+   MaxPos.x = Window->rcWindow.left;
+   MaxPos.y = Window->rcWindow.top;
 
-   Result = co_WinPosGetNonClientSize(Window, &Wnd->rcWindow, &Wnd->rcClient);
+   Result = co_WinPosGetNonClientSize(Window, &Window->rcWindow, &Window->rcClient);
 
-   RECTL_vOffsetRect(&Wnd->rcWindow, MaxPos.x - Wnd->rcWindow.left,
-                                     MaxPos.y - Wnd->rcWindow.top);
+   RECTL_vOffsetRect(&Window->rcWindow, MaxPos.x - Window->rcWindow.left,
+                                     MaxPos.y - Window->rcWindow.top);
 
 
    /* Send the WM_CREATE message. */
-   Result = co_IntSendMessage(Window->hSelf, WM_CREATE, 0, (LPARAM) Cs);
+   Result = co_IntSendMessage(UserHMGetHandle(Window), WM_CREATE, 0, (LPARAM) Cs);
    if (Result == (LRESULT)-1)
    {
       DPRINT1("co_UserCreateWindowEx(): WM_CREATE message failed\n");
-      IntUnlinkWindow(Window);
       RETURN((PWND)0);
    }
 
    /* Send the EVENT_OBJECT_CREATE event*/
-   IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0);
+   IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, CHILDID_SELF, 0);
 
    /* By setting the flag below it can be examined to determine if the window
       was created successfully and a valid pwnd was passed back to caller since
       from here the function has to succeed. */
-   Window->Wnd->state2 |= WNDS2_WMCREATEMSGPROCESSED;
+   Window->state2 |= WNDS2_WMCREATEMSGPROCESSED;
 
    /* Send the WM_SIZE and WM_MOVE messages. */
-   if (!(Window->state & WINDOWOBJECT_NEED_SIZE))
+   if (!(Window->state & WNDS_SENDSIZEMOVEMSGS))
    {
         co_WinPosSendSizeMove(Window);
    }
 
    /* Show or maybe minimize or maximize the window. */
-   if (Wnd->style & (WS_MINIMIZE | WS_MAXIMIZE))
+   if (Window->style & (WS_MINIMIZE | WS_MAXIMIZE))
    {
       RECTL NewPos;
       UINT16 SwFlag;
 
-      SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
+      SwFlag = (Window->style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
 
       co_WinPosMinMaximize(Window, SwFlag, &NewPos);
 
-      SwFlag = ((Wnd->style & WS_CHILD) || UserGetActiveWindow()) ?
+      SwFlag = ((Window->style & WS_CHILD) || UserGetActiveWindow()) ?
                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
                 SWP_NOZORDER | SWP_FRAMECHANGED;
 
@@ -2136,14 +2197,7 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    }
 
    /* Send the WM_PARENTNOTIFY message */
-   if ((Wnd->style & WS_CHILD) &&
-       (!(Wnd->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
-   {
-      co_IntSendMessage(ParentWindow->hSelf,
-                        WM_PARENTNOTIFY,
-                        MAKEWPARAM(WM_CREATE, Wnd->IDMenu),
-                        (LPARAM)Window->hSelf);
-   }
+   IntSendParentNotify(Window, WM_CREATE);
 
    /* Notify the shell that a new window was created */
    if ((!hWndParent) && (!hWndOwner))
@@ -2152,11 +2206,11 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    }
 
    /* Initialize and show the window's scrollbars */
-   if (Wnd->style & WS_VSCROLL)
+   if (Window->style & WS_VSCROLL)
    {
       co_UserShowScrollBar(Window, SB_VERT, TRUE);
    }
-   if (Wnd->style & WS_HSCROLL)
+   if (Window->style & WS_HSCROLL)
    {
       co_UserShowScrollBar(Window, SB_HORZ, TRUE);
    }
@@ -2164,34 +2218,40 @@ co_UserCreateWindowEx(CREATESTRUCTW* Cs,
    /* Show the new window */
    if (Cs->style & WS_VISIBLE)
    {
-      if (Wnd->style & WS_MAXIMIZE)
+      if (Window->style & WS_MAXIMIZE)
          dwShowMode = SW_SHOW;
-      else if (Wnd->style & WS_MINIMIZE)
+      else if (Window->style & WS_MINIMIZE)
          dwShowMode = SW_SHOWMINIMIZED;
 
       co_WinPosShowWindow(Window, dwShowMode);
 
-      if (Wnd->ExStyle & WS_EX_MDICHILD)
+      if (Window->ExStyle & WS_EX_MDICHILD)
       {
-        co_IntSendMessage(ParentWindow->hSelf, WM_MDIREFRESHMENU, 0, 0);
+        co_IntSendMessage(UserHMGetHandle(ParentWindow), WM_MDIREFRESHMENU, 0, 0);
         /* ShowWindow won't activate child windows */
         co_WinPosSetWindowPos(Window, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE);
       }
    }
 
    DPRINT("co_UserCreateWindowEx(): Created window %X\n", hWnd);
-   RETURN( Wnd);
+   RETURN( Window);
 
 CLEANUP:
    if (!_ret_)
    {
+       DPRINT("co_UserCreateWindowEx(): Error Created window!\n");
        /* If the window was created, the class will be dereferenced by co_UserDestroyWindow */
-       if (Window) 
+       if (Window)
             co_UserDestroyWindow(Window);
        else if (Class)
            IntDereferenceClass(Class, pti->pDeskInfo, pti->ppi);
    }
 
+   if (pCsw) ExFreePoolWithTag(pCsw, TAG_HOOK);
+   if (pCbtCreate) ExFreePoolWithTag(pCbtCreate, TAG_HOOK);
+   if (pszName) UserHeapFree(pszName);
+   if (pszClass) UserHeapFree(pszClass);
+
    if (Window)
    {
       UserDerefObjectCo(Window);
@@ -2340,10 +2400,11 @@ NtUserCreateWindowEx(
     Cs.cy = nHeight;
     Cs.x = x;
     Cs.y = y;
-//   Cs.lpszName = (LPCWSTR) WindowName->Buffer;
-//   Cs.lpszClass = (LPCWSTR) ClassName->Buffer;
-    Cs.lpszName = (LPCWSTR) plstrWindowName;
-    Cs.lpszClass = (LPCWSTR) &ustrClassName;
+    Cs.lpszName = (LPCWSTR) plstrWindowName->Buffer;
+    if (IS_ATOM(plstrClassName))
+       Cs.lpszClass = (LPCWSTR) plstrClassName;
+    else
+       Cs.lpszClass = (LPCWSTR) plstrClassName->Buffer;
     Cs.dwExStyle = dwExStyle;
 
     UserEnterExclusive();
@@ -2351,7 +2412,7 @@ NtUserCreateWindowEx(
     /* Call the internal function */
     pwnd = co_UserCreateWindowEx(&Cs, &ustrClassName, plstrWindowName);
 
-       if(!pwnd)
+    if(!pwnd)
     {
         DPRINT1("co_UserCreateWindowEx failed!\n");
     }
@@ -2372,55 +2433,41 @@ cleanup:
    return hwnd;
 }
 
-/*
- * @unimplemented
- */
-HDWP APIENTRY
-NtUserDeferWindowPos(HDWP WinPosInfo,
-                     HWND Wnd,
-                     HWND WndInsertAfter,
-                     int x,
-                     int y,
-                     int cx,
-                     int cy,
-                     UINT Flags)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
 
-BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
+BOOLEAN FASTCALL co_UserDestroyWindow(PWND Window)
 {
-   BOOLEAN isChild;
-   PWND Wnd;
    HWND hWnd;
    PTHREADINFO ti;
    MSG msg;
 
    ASSERT_REFS_CO(Window); // FIXME: temp hack?
 
-   hWnd = Window->hSelf;
-
-   Wnd = Window->Wnd;
-
-   if (!Wnd) return TRUE; // FIXME: Need to finish object rewrite or lock the thread when killing the window!
+   hWnd = Window->head.h;
 
    DPRINT("co_UserDestroyWindow \n");
 
    /* Check for owner thread */
-   if ( (Window->pti->pEThread != PsGetCurrentThread()) ||
-        Wnd->head.pti != PsGetCurrentThreadWin32Thread() )
+   if ( (Window->head.pti->pEThread != PsGetCurrentThread()) ||
+        Window->head.pti != PsGetCurrentThreadWin32Thread() )
    {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
+      EngSetLastError(ERROR_ACCESS_DENIED);
       return FALSE;
    }
 
    /* If window was created successfully and it is hooked */
-   if ((Wnd->state2 & WNDS2_WMCREATEMSGPROCESSED) && (ISITHOOKED(WH_CBT)))
+   if ((Window->state2 & WNDS2_WMCREATEMSGPROCESSED))
+   {
+      if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0))
+      {
+         DPRINT1("Destroy Window WH_CBT Call Hook return!\n");
+         return FALSE;
+      }
+   }
+
+   /* Inform the parent */
+   if (Window->style & WS_CHILD)
    {
-      if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE;
+      IntSendParentNotify(Window, WM_DESTROY);
    }
 
    /* Look whether the focus is within the tree of windows we will
@@ -2428,18 +2475,18 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
     */
    if (!co_WinPosShowWindow(Window, SW_HIDE))
    {
-      if (UserGetActiveWindow() == Window->hSelf)
+      if (UserGetActiveWindow() == Window->head.h)
       {
          co_WinPosActivateOtherWindow(Window);
       }
    }
 
-   if (Window->pti->MessageQueue->ActiveWindow == Window->hSelf)
-      Window->pti->MessageQueue->ActiveWindow = NULL;
-   if (Window->pti->MessageQueue->FocusWindow == Window->hSelf)
-      Window->pti->MessageQueue->FocusWindow = NULL;
-   if (Window->pti->MessageQueue->CaptureWindow == Window->hSelf)
-      Window->pti->MessageQueue->CaptureWindow = NULL;
+   if (Window->head.pti->MessageQueue->ActiveWindow == Window->head.h)
+      Window->head.pti->MessageQueue->ActiveWindow = NULL;
+   if (Window->head.pti->MessageQueue->FocusWindow == Window->head.h)
+      Window->head.pti->MessageQueue->FocusWindow = NULL;
+   if (Window->head.pti->MessageQueue->CaptureWindow == Window->head.h)
+      Window->head.pti->MessageQueue->CaptureWindow = NULL;
 
    /*
     * Check if this window is the Shell's Desktop Window. If so set hShellWindow to NULL
@@ -2456,41 +2503,25 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
       }
    }
 
-   IntDereferenceMessageQueue(Window->pti->MessageQueue);
+   IntDereferenceMessageQueue(Window->head.pti->MessageQueue);
 
    IntEngWindowChanged(Window, WOC_DELETE);
-   isChild = (0 != (Wnd->style & WS_CHILD));
 
-#if 0 /* FIXME */
-
-   if (isChild)
-   {
-      if (! USER_IsExitingThread(GetCurrentThreadId()))
-      {
-         send_parent_notify(hwnd, WM_DESTROY);
-      }
-   }
-   else if (NULL != GetWindow(Wnd, GW_OWNER))
-   {
-      co_HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWDESTROYED, (WPARAM)hwnd, 0L, TRUE );
-      /* FIXME: clean up palette - see "Internals" p.352 */
-   }
-#endif
-
-   if (!IntIsWindow(Window->hSelf))
+   if (!IntIsWindow(Window->head.h))
    {
       return TRUE;
    }
 
    /* Recursively destroy owned windows */
-   if (! isChild)
+
+   if (! (Window->style & WS_CHILD))
    {
       for (;;)
       {
          BOOL GotOne = FALSE;
          HWND *Children;
          HWND *ChildHandle;
-         PWINDOW_OBJECT Child, Desktop;
+         PWND Child, Desktop;
 
          Desktop = IntIsDesktopWindow(Window) ? Window :
                    UserGetWindowObject(IntGetDesktopWindow());
@@ -2522,7 +2553,6 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
                if (Child->spwndOwner != NULL)
                {
                   Child->spwndOwner = NULL;
-                  Child->Wnd->spwndOwner = NULL;
                }
 
             }
@@ -2540,9 +2570,9 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
     msg.wParam = IntGetSysCursorInfo()->ButtonsDown;
     msg.lParam = MAKELPARAM(gpsi->ptCursor.x, gpsi->ptCursor.y);
     msg.pt = gpsi->ptCursor;
-    MsqInsertSystemMessage(&msg);
+    co_MsqInsertMouseMessage(&msg);
 
-   if (!IntIsWindow(Window->hSelf))
+   if (!IntIsWindow(Window->head.h))
    {
       return TRUE;
    }
@@ -2560,7 +2590,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
 BOOLEAN APIENTRY
 NtUserDestroyWindow(HWND Wnd)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    DECLARE_RETURN(BOOLEAN);
    BOOLEAN ret;
    USER_REFERENCE_ENTRY Ref;
@@ -2586,59 +2616,9 @@ CLEANUP:
 }
 
 
-
-/*
- * @unimplemented
- */
-DWORD
-APIENTRY
-NtUserDrawMenuBarTemp(
-   HWND hWnd,
-   HDC hDC,
-   PRECT hRect,
-   HMENU hMenu,
-   HFONT hFont)
-{
-   /* we'll use this function just for caching the menu bar */
-   UNIMPLEMENTED
-   return 0;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserEndDeferWindowPosEx(DWORD Unknown0,
-                          DWORD Unknown1)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-
-/*
- * FillWindow: Called from User; Dialog, Edit and ListBox procs during a WM_ERASEBKGND.
- */
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserFillWindow(HWND hWndPaint,
-                 HWND hWndPaint1,
-                 HDC  hDC,
-                 HBRUSH hBrush)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-
 static HWND FASTCALL
-IntFindWindow(PWINDOW_OBJECT Parent,
-              PWINDOW_OBJECT ChildAfter,
+IntFindWindow(PWND Parent,
+              PWND ChildAfter,
               RTL_ATOM ClassAtom,
               PUNICODE_STRING WindowName)
 {
@@ -2657,14 +2637,14 @@ IntFindWindow(PWINDOW_OBJECT Parent,
       if(ChildAfter)
       {
          /* skip handles before and including ChildAfter */
-         while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+         while(*phWnd && (*(phWnd++) != ChildAfter->head.h))
             ;
       }
 
       /* search children */
       while(*phWnd)
       {
-         PWINDOW_OBJECT Child;
+         PWND Child;
          if(!(Child = UserGetWindowObject(*(phWnd++))))
          {
             continue;
@@ -2673,17 +2653,17 @@ IntFindWindow(PWINDOW_OBJECT Parent,
          /* Do not send WM_GETTEXT messages in the kernel mode version!
             The user mode version however calls GetWindowText() which will
             send WM_GETTEXT messages to windows belonging to its processes */
-         if (!ClassAtom || Child->Wnd->pcls->atomClassName == ClassAtom)
+         if (!ClassAtom || Child->pcls->atomClassName == ClassAtom)
          {
              // HACK: use UNICODE_STRING instead of LARGE_STRING
-             CurrentWindowName.Buffer = Child->Wnd->strName.Buffer;
-             CurrentWindowName.Length = Child->Wnd->strName.Length;
-             CurrentWindowName.MaximumLength = Child->Wnd->strName.MaximumLength;
-             if(!CheckWindowName || 
-                (Child->Wnd->strName.Length < 0xFFFF &&
+             CurrentWindowName.Buffer = Child->strName.Buffer;
+             CurrentWindowName.Length = Child->strName.Length;
+             CurrentWindowName.MaximumLength = Child->strName.MaximumLength;
+             if(!CheckWindowName ||
+                (Child->strName.Length < 0xFFFF &&
                  !RtlCompareUnicodeString(WindowName, &CurrentWindowName, TRUE)))
              {
-            Ret = Child->hSelf;
+            Ret = Child->head.h;
             break;
          }
       }
@@ -2725,7 +2705,7 @@ NtUserFindWindowEx(HWND hwndParent,
                    PUNICODE_STRING ucWindowName,
                    DWORD dwUnknown)
 {
-   PWINDOW_OBJECT Parent, ChildAfter;
+   PWND Parent, ChildAfter;
    UNICODE_STRING ClassName = {0}, WindowName = {0};
    HWND Desktop, Ret = NULL;
    RTL_ATOM ClassAtom = (RTL_ATOM)0;
@@ -2749,7 +2729,7 @@ NtUserFindWindowEx(HWND hwndParent,
                }
                else if (!IS_ATOM(ClassName.Buffer))
                {
-                   SetLastWin32Error(ERROR_INVALID_PARAMETER);
+                   EngSetLastError(ERROR_INVALID_PARAMETER);
                    _SEH2_LEAVE;
                }
 
@@ -2783,7 +2763,7 @@ NtUserFindWindowEx(HWND hwndParent,
            if (ClassName.Length == 0 && ClassName.Buffer != NULL &&
                !IS_ATOM(ClassName.Buffer))
            {
-               SetLastWin32Error(ERROR_INVALID_PARAMETER);
+               EngSetLastError(ERROR_INVALID_PARAMETER);
                RETURN(NULL);
            }
            else if (ClassAtom == (RTL_ATOM)0)
@@ -2816,10 +2796,10 @@ NtUserFindWindowEx(HWND hwndParent,
 
    _SEH2_TRY
    {
-       if(Parent->hSelf == Desktop)
+       if(Parent->head.h == Desktop)
        {
           HWND *List, *phWnd;
-          PWINDOW_OBJECT TopLevelWindow;
+          PWND TopLevelWindow;
           BOOLEAN CheckWindowName;
           BOOLEAN WindowMatches;
           BOOLEAN ClassMatches;
@@ -2834,7 +2814,7 @@ NtUserFindWindowEx(HWND hwndParent,
              if(ChildAfter)
              {
                 /* skip handles before and including ChildAfter */
-                while(*phWnd && (*(phWnd++) != ChildAfter->hSelf))
+                while(*phWnd && (*(phWnd++) != ChildAfter->head.h))
                    ;
              }
 
@@ -2853,18 +2833,18 @@ NtUserFindWindowEx(HWND hwndParent,
                 /* Do not send WM_GETTEXT messages in the kernel mode version!
                    The user mode version however calls GetWindowText() which will
                    send WM_GETTEXT messages to windows belonging to its processes */
-                ustr.Buffer = TopLevelWindow->Wnd->strName.Buffer;
-                ustr.Length = TopLevelWindow->Wnd->strName.Length;
-                ustr.MaximumLength = TopLevelWindow->Wnd->strName.MaximumLength;
-                WindowMatches = !CheckWindowName || 
-                                (TopLevelWindow->Wnd->strName.Length < 0xFFFF && 
+                ustr.Buffer = TopLevelWindow->strName.Buffer;
+                ustr.Length = TopLevelWindow->strName.Length;
+                ustr.MaximumLength = TopLevelWindow->strName.MaximumLength;
+                WindowMatches = !CheckWindowName ||
+                                (TopLevelWindow->strName.Length < 0xFFFF &&
                                  !RtlCompareUnicodeString(&WindowName, &ustr, TRUE));
                 ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
-                               ClassAtom == TopLevelWindow->Wnd->pcls->atomClassName;
+                               ClassAtom == TopLevelWindow->pcls->atomClassName;
 
                 if (WindowMatches && ClassMatches)
                 {
-                   Ret = TopLevelWindow->hSelf;
+                   Ret = TopLevelWindow->head.h;
                    break;
                 }
 
@@ -2872,7 +2852,7 @@ NtUserFindWindowEx(HWND hwndParent,
                 {
                    /* window returns the handle of the top-level window, in case it found
                       the child window */
-                   Ret = TopLevelWindow->hSelf;
+                   Ret = TopLevelWindow->head.h;
                    break;
                 }
 
@@ -2890,7 +2870,7 @@ NtUserFindWindowEx(HWND hwndParent,
           /* FIXME - if both hwndParent and hwndChildAfter are NULL, we also should
                      search the message-only windows. Should this also be done if
                      Parent is the desktop window??? */
-          PWINDOW_OBJECT MsgWindows;
+          PWND MsgWindows;
 
           if((MsgWindows = UserGetWindowObject(IntGetMessageWindow())))
           {
@@ -2915,26 +2895,14 @@ CLEANUP:
 }
 
 
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserFlashWindowEx(IN PFLASHWINFO pfwi)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-
 /*
  * @implemented
  */
-PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
+PWND FASTCALL UserGetAncestor(PWND Wnd, UINT Type)
 {
-   PWINDOW_OBJECT WndAncestor, Parent;
+   PWND WndAncestor, Parent;
 
-   if (Wnd->hSelf == IntGetDesktopWindow())
+   if (Wnd->head.h == IntGetDesktopWindow())
    {
       return NULL;
    }
@@ -2974,7 +2942,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 
             for (;;)
             {
-               PWINDOW_OBJECT Parent;
+               PWND Parent;
 
                Parent = IntGetParent(WndAncestor);
 
@@ -3003,7 +2971,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 HWND APIENTRY
 NtUserGetAncestor(HWND hWnd, UINT Type)
 {
-   PWINDOW_OBJECT Window, Ancestor;
+   PWND Window, Ancestor;
    DECLARE_RETURN(HWND);
 
    DPRINT("Enter NtUserGetAncestor\n");
@@ -3017,7 +2985,7 @@ NtUserGetAncestor(HWND hWnd, UINT Type)
    Ancestor = UserGetAncestor(Window, Type);
    /* faxme: can UserGetAncestor ever return NULL for a valid window? */
 
-   RETURN(Ancestor ? Ancestor->hSelf : NULL);
+   RETURN(Ancestor ? Ancestor->head.h : NULL);
 
 CLEANUP:
    DPRINT("Leave NtUserGetAncestor, ret=%i\n",_ret_);
@@ -3032,7 +3000,7 @@ NtUserGetComboBoxInfo(
    HWND hWnd,
    PCOMBOBOXINFO pcbi)
 {
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserGetComboBoxInfo\n");
@@ -3059,7 +3027,7 @@ NtUserGetComboBoxInfo(
    _SEH2_END;
 
    // Pass the user pointer, it was already probed.
-   RETURN( (BOOL) co_IntSendMessage( Wnd->hSelf, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
+   RETURN( (BOOL) co_IntSendMessage( Wnd->head.h, CB_GETCOMBOBOXINFO, 0, (LPARAM)pcbi));
 
 CLEANUP:
    DPRINT("Leave NtUserGetComboBoxInfo, ret=%i\n",_ret_);
@@ -3076,14 +3044,14 @@ NtUserGetInternalWindowPos( HWND hWnd,
                             LPRECT rectWnd,
                             LPPOINT ptIcon)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    DWORD Ret = 0;
    BOOL Hit = FALSE;
    WINDOWPLACEMENT wndpl;
 
    UserEnterShared();
 
-   if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+   if (!(Window = UserGetWindowObject(hWnd)))
    {
       Hit = FALSE;
       goto Exit;
@@ -3103,7 +3071,7 @@ NtUserGetInternalWindowPos( HWND hWnd,
                         sizeof(POINT),
                         1);
        }
-       
+
    }
    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
    {
@@ -3112,7 +3080,7 @@ NtUserGetInternalWindowPos( HWND hWnd,
    }
    _SEH2_END;
 
-   wndpl.length = sizeof(WINDOWPLACEMENT);   
+   wndpl.length = sizeof(WINDOWPLACEMENT);
 
    if (IntGetWindowPlacement(Window, &wndpl) && !Hit)
    {
@@ -3126,7 +3094,7 @@ NtUserGetInternalWindowPos( HWND hWnd,
           {
              RtlCopyMemory(ptIcon, &wndpl.ptMinPosition, sizeof(POINT));
           }
-       
+
       }
       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
@@ -3147,7 +3115,7 @@ APIENTRY
 NtUserGetListBoxInfo(
    HWND hWnd)
 {
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    DECLARE_RETURN(DWORD);
 
    DPRINT("Enter NtUserGetListBoxInfo\n");
@@ -3158,7 +3126,7 @@ NtUserGetListBoxInfo(
       RETURN( 0 );
    }
 
-   RETURN( (DWORD) co_IntSendMessage( Wnd->hSelf, LB_GETLISTBOXINFO, 0, 0 ));
+   RETURN( (DWORD) co_IntSendMessage( Wnd->head.h, LB_GETLISTBOXINFO, 0, 0 ));
 
 CLEANUP:
    DPRINT("Leave NtUserGetListBoxInfo, ret=%i\n",_ret_);
@@ -3166,63 +3134,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-
-HWND FASTCALL
-co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
-{
-   PWINDOW_OBJECT Wnd = NULL, WndParent = NULL, WndOldParent;
-   HWND hWndOldParent = NULL;
-   USER_REFERENCE_ENTRY Ref, ParentRef;
-
-   if (IntIsBroadcastHwnd(hWndChild) || IntIsBroadcastHwnd(hWndNewParent))
-   {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
-      return( NULL);
-   }
-
-   if (hWndChild == IntGetDesktopWindow())
-   {
-      SetLastWin32Error(ERROR_ACCESS_DENIED);
-      return( NULL);
-   }
-
-   if (hWndNewParent)
-   {
-      if (!(WndParent = UserGetWindowObject(hWndNewParent)))
-      {
-         return( NULL);
-      }
-   }
-   else
-   {
-      if (!(WndParent = UserGetWindowObject(IntGetDesktopWindow())))
-      {
-         return( NULL);
-      }
-   }
-
-   if (!(Wnd = UserGetWindowObject(hWndChild)))
-   {
-      return( NULL);
-   }
-
-   UserRefObjectCo(Wnd, &Ref);
-   UserRefObjectCo(WndParent, &ParentRef);
-
-   WndOldParent = co_IntSetParent(Wnd, WndParent);
-
-   UserDerefObjectCo(WndParent);
-   UserDerefObjectCo(Wnd);
-
-   if (WndOldParent)
-   {
-      hWndOldParent = WndOldParent->hSelf;
-      UserDereferenceObject(WndOldParent);
-   }
-
-   return( hWndOldParent);
-}
-
 /*
  * NtUserSetParent
  *
@@ -3311,7 +3222,7 @@ BOOL APIENTRY
 NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
 {
    PWINSTATION_OBJECT WinStaObject;
-   PWINDOW_OBJECT WndShell, WndListView;
+   PWND WndShell, WndListView;
    DECLARE_RETURN(BOOL);
    USER_REFERENCE_ENTRY Ref;
    NTSTATUS Status;
@@ -3363,14 +3274,14 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
       co_WinPosSetWindowPos(hwndListView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
 #endif
 
-      if (WndListView->Wnd->ExStyle & WS_EX_TOPMOST)
+      if (WndListView->ExStyle & WS_EX_TOPMOST)
       {
          ObDereferenceObject(WinStaObject);
          RETURN( FALSE);
       }
    }
 
-   if (WndShell->Wnd->ExStyle & WS_EX_TOPMOST)
+   if (WndShell->ExStyle & WS_EX_TOPMOST)
    {
       ObDereferenceObject(WinStaObject);
       RETURN( FALSE);
@@ -3426,7 +3337,7 @@ CLEANUP:
 HMENU APIENTRY
 NtUserGetSystemMenu(HWND hWnd, BOOL bRevert)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    PMENU_OBJECT Menu;
    DECLARE_RETURN(HMENU);
 
@@ -3462,7 +3373,7 @@ BOOL APIENTRY
 NtUserSetSystemMenu(HWND hWnd, HMENU hMenu)
 {
    BOOL Result = FALSE;
-   PWINDOW_OBJECT Window;
+   PWND Window;
    PMENU_OBJECT Menu;
    DECLARE_RETURN(BOOL);
 
@@ -3498,15 +3409,14 @@ CLEANUP:
 LONG FASTCALL
 co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 {
-   PWINDOW_OBJECT Window, Parent;
-   PWND Wnd;
+   PWND Window, Parent;
    PWINSTATION_OBJECT WindowStation;
    LONG OldValue;
    STYLESTRUCT Style;
 
    if (hWnd == IntGetDesktopWindow())
    {
-      SetLastWin32Error(STATUS_ACCESS_DENIED);
+      EngSetLastError(STATUS_ACCESS_DENIED);
       return( 0);
    }
 
@@ -3515,19 +3425,15 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
       return( 0);
    }
 
-   Wnd = Window->Wnd;
-
-   if (!Wnd) return 0; // No go on zero.
-
    if ((INT)Index >= 0)
    {
-      if ((Index + sizeof(LONG)) > Wnd->cbwndExtra)
+      if ((Index + sizeof(LONG)) > Window->cbwndExtra)
       {
-         SetLastWin32Error(ERROR_INVALID_INDEX);
+         EngSetLastError(ERROR_INVALID_INDEX);
          return( 0);
       }
 
-      OldValue = *((LONG *)((PCHAR)(Wnd + 1) + Index));
+      OldValue = *((LONG *)((PCHAR)(Window + 1) + Index));
 /*
       if ( Index == DWLP_DLGPROC && Wnd->state & WNDS_DIALOGWINDOW)
       {
@@ -3537,21 +3443,21 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
          if (!OldValue) return 0;
       }
 */
-      *((LONG *)((PCHAR)(Wnd + 1) + Index)) = NewValue;
+      *((LONG *)((PCHAR)(Window + 1) + Index)) = NewValue;
    }
    else
    {
       switch (Index)
       {
          case GWL_EXSTYLE:
-            OldValue = (LONG) Wnd->ExStyle;
+            OldValue = (LONG) Window->ExStyle;
             Style.styleOld = OldValue;
             Style.styleNew = NewValue;
 
             /*
              * Remove extended window style bit WS_EX_TOPMOST for shell windows.
              */
-            WindowStation = Window->pti->rpdesk->rpwinstaParent;
+            WindowStation = Window->head.pti->rpdesk->rpwinstaParent;
             if(WindowStation)
             {
                if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
@@ -3559,59 +3465,59 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             }
 
             co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_EXSTYLE, (LPARAM) &Style);
-            Wnd->ExStyle = (DWORD)Style.styleNew;
+            Window->ExStyle = (DWORD)Style.styleNew;
             co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_EXSTYLE, (LPARAM) &Style);
             break;
 
          case GWL_STYLE:
-            OldValue = (LONG) Wnd->style;
+            OldValue = (LONG) Window->style;
             Style.styleOld = OldValue;
             Style.styleNew = NewValue;
             co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM) &Style);
-            Wnd->style = (DWORD)Style.styleNew;
+            Window->style = (DWORD)Style.styleNew;
             co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
             break;
 
          case GWL_WNDPROC:
          {
-            if ( Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
-                 Wnd->fnid & FNID_FREED)
+            if ( Window->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
+                 Window->fnid & FNID_FREED)
             {
-               SetLastWin32Error(ERROR_ACCESS_DENIED);
+               EngSetLastError(ERROR_ACCESS_DENIED);
                return( 0);
             }
-            OldValue = (LONG)IntSetWindowProc(Wnd,
+            OldValue = (LONG)IntSetWindowProc(Window,
                                               (WNDPROC)NewValue,
                                               Ansi);
             break;
          }
 
          case GWL_HINSTANCE:
-            OldValue = (LONG) Wnd->hModule;
-            Wnd->hModule = (HINSTANCE) NewValue;
+            OldValue = (LONG) Window->hModule;
+            Window->hModule = (HINSTANCE) NewValue;
             break;
 
          case GWL_HWNDPARENT:
             Parent = Window->spwndParent;
-            if (Parent && (Parent->hSelf == IntGetDesktopWindow()))
-               OldValue = (LONG) IntSetOwner(Window->hSelf, (HWND) NewValue);
+            if (Parent && (Parent->head.h == IntGetDesktopWindow()))
+               OldValue = (LONG) IntSetOwner(Window->head.h, (HWND) NewValue);
             else
-               OldValue = (LONG) co_UserSetParent(Window->hSelf, (HWND) NewValue);
+               OldValue = (LONG) co_UserSetParent(Window->head.h, (HWND) NewValue);
             break;
 
          case GWL_ID:
-            OldValue = (LONG) Wnd->IDMenu;
-            Wnd->IDMenu = (UINT) NewValue;
+            OldValue = (LONG) Window->IDMenu;
+            Window->IDMenu = (UINT) NewValue;
             break;
 
          case GWL_USERDATA:
-            OldValue = Wnd->dwUserData;
-            Wnd->dwUserData = NewValue;
+            OldValue = Window->dwUserData;
+            Window->dwUserData = NewValue;
             break;
 
          default:
             DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index);
-            SetLastWin32Error(ERROR_INVALID_INDEX);
+            EngSetLastError(ERROR_INVALID_INDEX);
             OldValue = 0;
             break;
       }
@@ -3659,7 +3565,7 @@ CLEANUP:
 WORD APIENTRY
 NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    WORD OldValue;
    DECLARE_RETURN(WORD);
 
@@ -3676,23 +3582,23 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
       case GWL_ID:
       case GWL_HINSTANCE:
       case GWL_HWNDPARENT:
-         RETURN( co_UserSetWindowLong(Window->hSelf, Index, (UINT)NewValue, TRUE));
+         RETURN( co_UserSetWindowLong(Window->head.h, Index, (UINT)NewValue, TRUE));
       default:
          if (Index < 0)
          {
-            SetLastWin32Error(ERROR_INVALID_INDEX);
+            EngSetLastError(ERROR_INVALID_INDEX);
             RETURN( 0);
          }
    }
 
-   if (Index > Window->Wnd->cbwndExtra - sizeof(WORD))
+   if (Index > Window->cbwndExtra - sizeof(WORD))
    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      EngSetLastError(ERROR_INVALID_PARAMETER);
       RETURN( 0);
    }
 
-   OldValue = *((WORD *)((PCHAR)(Window->Wnd + 1) + Index));
-   *((WORD *)((PCHAR)(Window->Wnd + 1) + Index)) = NewValue;
+   OldValue = *((WORD *)((PCHAR)(Window + 1) + Index));
+   *((WORD *)((PCHAR)(Window + 1) + Index)) = NewValue;
 
    RETURN( OldValue);
 
@@ -3709,7 +3615,6 @@ BOOL APIENTRY
 NtUserGetWindowPlacement(HWND hWnd,
                          WINDOWPLACEMENT *lpwndpl)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    POINT Size;
    WINDOWPLACEMENT Safepl;
@@ -3719,11 +3624,10 @@ NtUserGetWindowPlacement(HWND hWnd,
    DPRINT("Enter NtUserGetWindowPlacement\n");
    UserEnterShared();
 
-   if (!(Window = UserGetWindowObject(hWnd)))
+   if (!(Wnd = UserGetWindowObject(hWnd)))
    {
       RETURN( FALSE);
    }
-   Wnd = Window->Wnd;
 
    Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
    if(!NT_SUCCESS(Status))
@@ -3741,7 +3645,7 @@ NtUserGetWindowPlacement(HWND hWnd,
    {
       Safepl.showCmd = SW_HIDE;
    }
-   else if ((0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
+   else if ((0 != (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN) ||
             0 != (Wnd->style & WS_MAXIMIZE)) &&
             0 == (Wnd->style & WS_MINIMIZE))
    {
@@ -3758,7 +3662,7 @@ NtUserGetWindowPlacement(HWND hWnd,
 
    Size.x = Wnd->rcWindow.left;
    Size.y = Wnd->rcWindow.top;
-   WinPosInitInternalPos(Window, &Size,
+   WinPosInitInternalPos(Wnd, &Size,
                          &Wnd->rcWindow);
 
    Safepl.rcNormalPosition = Wnd->InternalPos.NormalRect;
@@ -3780,36 +3684,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserLockWindowUpdate(HWND hWnd)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserMoveWindow(
-   HWND hWnd,
-   int X,
-   int Y,
-   int nWidth,
-   int nHeight,
-   BOOL bRepaint)
-{
-   return NtUserSetWindowPos(hWnd, 0, X, Y, nWidth, nHeight,
-                             (bRepaint ? SWP_NOZORDER | SWP_NOACTIVATE :
-                              SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW));
-}
-
 /*
  QueryWindow based on KJK::Hyperion and James Tabor.
 
@@ -3830,7 +3704,6 @@ NtUserMoveWindow(
 DWORD APIENTRY
 NtUserQueryWindow(HWND hWnd, DWORD Index)
 {
-   PWINDOW_OBJECT Window;
    PWND pWnd;
    DWORD Result;
    DECLARE_RETURN(UINT);
@@ -3838,21 +3711,19 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
    DPRINT("Enter NtUserQueryWindow\n");
    UserEnterShared();
 
-   if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+   if (!(pWnd = UserGetWindowObject(hWnd)))
    {
       RETURN( 0);
    }
 
-   pWnd = Window->Wnd;
-
    switch(Index)
    {
       case QUERY_WINDOW_UNIQUE_PROCESS_ID:
-         Result = (DWORD)IntGetWndProcessId(Window);
+         Result = (DWORD)IntGetWndProcessId(pWnd);
          break;
 
       case QUERY_WINDOW_UNIQUE_THREAD_ID:
-         Result = (DWORD)IntGetWndThreadId(Window);
+         Result = (DWORD)IntGetWndThreadId(pWnd);
          break;
 
       case QUERY_WINDOW_ACTIVE:
@@ -3864,7 +3735,7 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
          break;
 
       case QUERY_WINDOW_ISHUNG:
-         Result = (DWORD)MsqIsHung(Window->pti->MessageQueue);
+         Result = (DWORD)MsqIsHung(pWnd->head.pti->MessageQueue);
          break;
 
       case QUERY_WINDOW_REAL_ID:
@@ -3884,20 +3755,6 @@ CLEANUP:
 }
 
 
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserRealChildWindowFromPoint(DWORD Unknown0,
-                               DWORD Unknown1,
-                               DWORD Unknown2)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-
 /*
  * @implemented
  */
@@ -3914,7 +3771,7 @@ NtUserRegisterWindowMessage(PUNICODE_STRING MessageNameUnsafe)
 
    if(MessageNameUnsafe == NULL)
    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      EngSetLastError(ERROR_INVALID_PARAMETER);
       RETURN( 0);
    }
 
@@ -3937,62 +3794,6 @@ CLEANUP:
 }
 
 
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserSetImeOwnerWindow(DWORD Unknown0,
-                        DWORD Unknown1)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-
-/*
- * @unimplemented
- */
-DWORD APIENTRY
-NtUserSetInternalWindowPos(
-   HWND    hwnd,
-   UINT    showCmd,
-   LPRECT  rect,
-   LPPOINT pt)
-{
-   UNIMPLEMENTED
-
-   return 0;
-
-}
-
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserSetLayeredWindowAttributes(HWND hwnd,
-                          COLORREF crKey,
-                          BYTE bAlpha,
-                          DWORD dwFlags)
-{
-  UNIMPLEMENTED;
-  return FALSE;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserSetLogonNotifyWindow(HWND hWnd)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-
 /*
  * @implemented
  */
@@ -4002,7 +3803,7 @@ NtUserSetMenu(
    HMENU Menu,
    BOOL Repaint)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    BOOL Changed;
    DECLARE_RETURN(BOOL);
 
@@ -4046,377 +3847,43 @@ BOOL APIENTRY
 NtUserSetWindowFNID(HWND hWnd,
                     WORD fnID)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserSetWindowFNID\n");
    UserEnterExclusive();
 
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN( FALSE);
-   }
-   Wnd = Window->Wnd;
-
-   if (Wnd->pcls)
-   {  // From user land we only set these.
-      if ((fnID != FNID_DESTROY) || ((fnID < FNID_BUTTON) && (fnID > FNID_IME)) )
-      {
-         RETURN( FALSE);
-      }
-      else
-         Wnd->pcls->fnid |= fnID;
-   }
-   RETURN( TRUE);
-
-CLEANUP:
-   DPRINT("Leave NtUserSetWindowFNID\n");
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserSetWindowPlacement(HWND hWnd,
-                         WINDOWPLACEMENT *lpwndpl)
-{
-   PWINDOW_OBJECT Window;
-   PWND Wnd;
-   WINDOWPLACEMENT Safepl;
-   NTSTATUS Status;
-   DECLARE_RETURN(BOOL);
-   USER_REFERENCE_ENTRY Ref;
-
-   DPRINT("Enter NtUserSetWindowPlacement\n");
-   UserEnterExclusive();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
+   if (!(Wnd = UserGetWindowObject(hWnd)))
    {
       RETURN( FALSE);
    }
-   Wnd = Window->Wnd;
 
-   Status = MmCopyFromCaller(&Safepl, lpwndpl, sizeof(WINDOWPLACEMENT));
-   if(!NT_SUCCESS(Status))
+   if (Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process())
    {
-      SetLastNtError(Status);
+      EngSetLastError(ERROR_ACCESS_DENIED);
       RETURN( FALSE);
    }
-   if(Safepl.length != sizeof(WINDOWPLACEMENT))
-   {
-      RETURN( FALSE);
-   }
-
-   UserRefObjectCo(Window, &Ref);
-
-   if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
-   {
-      co_WinPosSetWindowPos(Window, NULL,
-                            Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
-                            Safepl.rcNormalPosition.right - Safepl.rcNormalPosition.left,
-                            Safepl.rcNormalPosition.bottom - Safepl.rcNormalPosition.top,
-                            SWP_NOZORDER | SWP_NOACTIVATE);
-   }
-
-   /* FIXME - change window status */
-   co_WinPosShowWindow(Window, Safepl.showCmd);
-
-   Wnd->InternalPosInitialized = TRUE;
-   Wnd->InternalPos.NormalRect = Safepl.rcNormalPosition;
-   Wnd->InternalPos.IconPos = Safepl.ptMinPosition;
-   Wnd->InternalPos.MaxPos = Safepl.ptMaxPosition;
-
-   UserDerefObjectCo(Window);
-   RETURN(TRUE);
-
-CLEANUP:
-   DPRINT("Leave NtUserSetWindowPlacement, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserSetWindowPos(
-   HWND hWnd,
-   HWND hWndInsertAfter,
-   int X,
-   int Y,
-   int cx,
-   int cy,
-   UINT uFlags)
-{
-   DECLARE_RETURN(BOOL);
-   PWINDOW_OBJECT Window;
-   BOOL ret;
-   USER_REFERENCE_ENTRY Ref;
-
-   DPRINT("Enter NtUserSetWindowPos\n");
-   UserEnterExclusive();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN(FALSE);
-   }
 
-   /* First make sure that coordinates are valid for WM_WINDOWPOSCHANGING */
-   if (!(uFlags & SWP_NOMOVE))
-   {
-      if (X < -32768) X = -32768;
-      else if (X > 32767) X = 32767;
-      if (Y < -32768) Y = -32768;
-      else if (Y > 32767) Y = 32767;
-   }
-   if (!(uFlags & SWP_NOSIZE))
-   {
-      if (cx < 0) cx = 0;
-      else if (cx > 32767) cx = 32767;
-      if (cy < 0) cy = 0;
-      else if (cy > 32767) cy = 32767;
-   }
-
-   UserRefObjectCo(Window, &Ref);
-   ret = co_WinPosSetWindowPos(Window, hWndInsertAfter, X, Y, cx, cy, uFlags);
-   UserDerefObjectCo(Window);
-
-   RETURN(ret);
-
-CLEANUP:
-   DPRINT("Leave NtUserSetWindowPos, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-INT FASTCALL
-IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
-{
-   INT Ret;
-   HRGN VisRgn;
-   ROSRGNDATA *pRgn;
-   PWND Wnd;
-
-   if(!Window)
-   {
-      return ERROR;
-   }
-   if(!hRgn)
-   {
-      return ERROR;
-   }
-
-   Wnd = Window->Wnd;
-
-   /* Create a new window region using the window rectangle */
-   VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
-   NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
-   /* if there's a region assigned to the window, combine them both */
-   if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
-   /* Copy the region into hRgn */
-   NtGdiCombineRgn(hRgn, VisRgn, NULL, RGN_COPY);
-
-   if((pRgn = RGNOBJAPI_Lock(hRgn, NULL)))
-   {
-      Ret = REGION_Complexity(pRgn);
-      RGNOBJAPI_Unlock(pRgn);
-   }
-   else
-      Ret = ERROR;
-
-   REGION_FreeRgnByHandle(VisRgn);
-
-   return Ret;
-}
-
-INT FASTCALL
-IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
-{
-   INT Ret;
-   HRGN VisRgn;
-   ROSRGNDATA *pRgn;
-   PWND Wnd;
-
-   if(!Window)
-   {
-      return ERROR;
-   }
-   if(!Rect)
-   {
-      return ERROR;
-   }
-
-   Wnd = Window->Wnd;
-
-   /* Create a new window region using the window rectangle */
-   VisRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
-   NtGdiOffsetRgn(VisRgn, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
-   /* if there's a region assigned to the window, combine them both */
-   if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
-
-   if((pRgn = RGNOBJAPI_Lock(VisRgn, NULL)))
-   {
-      Ret = REGION_Complexity(pRgn);
-      *Rect = pRgn->rdh.rcBound;
-      RGNOBJAPI_Unlock(pRgn);
-   }
-   else
-      Ret = ERROR;
-
-   REGION_FreeRgnByHandle(VisRgn);
-
-   return Ret;
-}
-
-
-/*
- * @implemented
- */
-INT APIENTRY
-NtUserSetWindowRgn(
-   HWND hWnd,
-   HRGN hRgn,
-   BOOL bRedraw)
-{
-   HRGN hrgnCopy;
-   PWINDOW_OBJECT Window;
-   DECLARE_RETURN(INT);
-
-   DPRINT("Enter NtUserSetWindowRgn\n");
-   UserEnterExclusive();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN( 0);
-   }
-
-   if (hRgn) // The region will be deleted in user32.
-   {
-      if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION))
+   // From user land we only set these.
+   if (fnID != FNID_DESTROY)
+   { //       Hacked so we can mark desktop~!
+      if ( (/*(fnID < FNID_BUTTON)*/ (fnID < FNID_FIRST) && (fnID > FNID_GHOST)) ||
+           Wnd->fnid != 0 )
       {
-         hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
-         NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
+         EngSetLastError(ERROR_INVALID_PARAMETER);
+         RETURN( FALSE);
       }
-      else
-         RETURN( 0);
-   }
-   else
-      hrgnCopy = (HRGN) 1;
-
-   if (Window->hrgnClip)
-   {
-      /* Delete no longer needed region handle */
-      GreDeleteObject(Window->hrgnClip);
-   }
-   Window->hrgnClip = hrgnCopy;
-
-   /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
-
-   if(bRedraw)
-   {
-      USER_REFERENCE_ENTRY Ref;
-      UserRefObjectCo(Window, &Ref);
-      co_UserRedrawWindow(Window, NULL, NULL, RDW_INVALIDATE);
-      UserDerefObjectCo(Window);
    }
 
-   RETURN( (INT)hRgn);
-
-CLEANUP:
-   DPRINT("Leave NtUserSetWindowRgn, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-/*
- * @implemented
- */
-BOOL APIENTRY
-NtUserShowWindow(HWND hWnd, LONG nCmdShow)
-{
-   PWINDOW_OBJECT Window;
-   BOOL ret;
-   DECLARE_RETURN(BOOL);
-   USER_REFERENCE_ENTRY Ref;
-
-   DPRINT("Enter NtUserShowWindow\n");
-   UserEnterExclusive();
-
-   if (!(Window = UserGetWindowObject(hWnd)))
-   {
-      RETURN(FALSE);
-   }
-
-   UserRefObjectCo(Window, &Ref);
-   ret = co_WinPosShowWindow(Window, nCmdShow);
-   UserDerefObjectCo(Window);
-
-   RETURN(ret);
+   Wnd->fnid |= fnID;
+   RETURN( TRUE);
 
 CLEANUP:
-   DPRINT("Leave NtUserShowWindow, ret=%i\n",_ret_);
+   DPRINT("Leave NtUserSetWindowFNID\n");
    UserLeave();
    END_CLEANUP;
 }
 
-
-/*
- * @unimplemented
- */
-BOOL APIENTRY
-NtUserShowWindowAsync(HWND hWnd, LONG nCmdShow)
-{
-#if 0
-   UNIMPLEMENTED
-   return 0;
-#else
-   return NtUserShowWindow(hWnd, nCmdShow);
-#endif
-}
-
-
-/*
- * @unimplemented
- */
-BOOL
-APIENTRY
-NtUserUpdateLayeredWindow(
-   HWND hwnd,
-   HDC hdcDst,
-   POINT *pptDst,
-   SIZE *psize,
-   HDC hdcSrc,
-   POINT *pptSrc,
-   COLORREF crKey,
-   BLENDFUNCTION *pblend,
-   DWORD dwFlags,
-   RECT *prcDirty)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-/*
- *    @unimplemented
- */
-HWND APIENTRY
-NtUserWindowFromPhysicalPoint(POINT Point)
-{
-   UNIMPLEMENTED
-
-   return NULL;
-}
-
 /*
  *    @implemented
  */
@@ -4425,7 +3892,8 @@ NtUserWindowFromPoint(LONG X, LONG Y)
 {
    POINT pt;
    HWND Ret;
-   PWINDOW_OBJECT DesktopWindow = NULL, Window = NULL;
+   PWND DesktopWindow = NULL, Window = NULL;
+   USHORT hittest;
    DECLARE_RETURN(HWND);
    USER_REFERENCE_ENTRY Ref;
 
@@ -4444,11 +3912,11 @@ NtUserWindowFromPoint(LONG X, LONG Y)
       UserRefObjectCo(DesktopWindow, &Ref);
 
       pti = PsGetCurrentThreadWin32Thread();
-      co_WinPosWindowFromPoint(DesktopWindow, pti->MessageQueue, &pt, &Window);
+      Window = co_WinPosWindowFromPoint(DesktopWindow, &pt, &hittest);
 
       if(Window)
       {
-         Ret = Window->hSelf;
+         Ret = Window->head.h;
 
          RETURN( Ret);
       }
@@ -4479,7 +3947,6 @@ CLEANUP:
 BOOL APIENTRY
 NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    LARGE_STRING SafeText;
    UNICODE_STRING UnicodeString;
@@ -4508,12 +3975,11 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
 
    UserEnterExclusive();
 
-   if(!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
+   if(!(Wnd = UserGetWindowObject(hWnd)))
    {
       UserLeave();
       return FALSE;
    }
-   Wnd = Window->Wnd;
 
    // ReactOS uses Unicode and not mixed. Up/Down converting will take time.
    // Brought to you by: The Wine Project! Dysfunctional Thought Processes!
@@ -4575,7 +4041,7 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
          }
          else
          {
-            SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+            EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
             Ret = FALSE;
             goto Exit;
          }
@@ -4592,7 +4058,7 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
    // In User32, these are called after: NotifyWinEvent EVENT_OBJECT_NAMECHANGE than
    // RepaintButton, StaticRepaint, NtUserCallHwndLock HWNDLOCK_ROUTINE_REDRAWFRAMEANDHOOK, etc.
    /* Send shell notifications */
-   if (!Window->spwndOwner && !IntGetParent(Window))
+   if (!Wnd->spwndOwner && !IntGetParent(Wnd))
    {
       co_IntShellHookNotify(HSHELL_REDRAW, (LPARAM) hWnd);
    }
@@ -4615,7 +4081,6 @@ Exit:
 INT APIENTRY
 NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
 {
-   PWINDOW_OBJECT Window;
    PWND Wnd;
    NTSTATUS Status;
    INT Result;
@@ -4626,15 +4091,14 @@ NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
 
    if(lpString && (nMaxCount <= 1))
    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      EngSetLastError(ERROR_INVALID_PARAMETER);
       RETURN( 0);
    }
 
-   if(!(Window = UserGetWindowObject(hWnd)))
+   if(!(Wnd = UserGetWindowObject(hWnd)))
    {
       RETURN( 0);
    }
-   Wnd = Window->Wnd;
 
    Result = Wnd->strName.Length / sizeof(WCHAR);
    if(lpString)
@@ -4676,10 +4140,10 @@ CLEANUP:
 
 BOOL
 FASTCALL
-IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
+IntShowOwnedPopups(PWND OwnerWnd, BOOL fShow )
 {
    int count = 0;
-   PWINDOW_OBJECT pWnd;
+   PWND pWnd;
    HWND *win_array;
 
 //   ASSERT(OwnerWnd);
@@ -4700,7 +4164,7 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
 
       if (fShow)
       {
-         if (pWnd->Wnd->state & WNDS_HIDDENPOPUP)
+         if (pWnd->state & WNDS_HIDDENPOPUP)
          {
             /* In Windows, ShowOwnedPopups(TRUE) generates
              * WM_SHOWWINDOW messages with SW_PARENTOPENING,
@@ -4712,7 +4176,7 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
       }
       else
       {
-         if (pWnd->Wnd->style & WS_VISIBLE)
+         if (pWnd->style & WS_VISIBLE)
          {
             /* In Windows, ShowOwnedPopups(FALSE) generates
              * WM_SHOWWINDOW messages with SW_PARENTCLOSING,
@@ -4748,7 +4212,7 @@ NtUserValidateHandleSecure(
        PUSER_HANDLE_ENTRY entry;
        if (!(entry = handle_to_entry(gHandleTable, handle )))
        {
-          SetLastWin32Error(ERROR_INVALID_HANDLE);
+          EngSetLastError(ERROR_INVALID_HANDLE);
           return FALSE;
        }
        uType = entry->type;
@@ -4757,7 +4221,7 @@ NtUserValidateHandleSecure(
      {
        case otWindow:
        {
-         PWINDOW_OBJECT Window;
+         PWND Window;
          if ((Window = UserGetWindowObject((HWND) handle))) return TRUE;
          return FALSE;
        }
@@ -4797,7 +4261,7 @@ NtUserValidateHandleSecure(
          return UserGetCallProcInfo( handle, &Proc );
        }
        default:
-         SetLastWin32Error(ERROR_INVALID_HANDLE);
+         EngSetLastError(ERROR_INVALID_HANDLE);
      }
    }
    else