[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / window.c
index 6b4e696..4445fff 100644 (file)
@@ -1,26 +1,8 @@
-/*
- *  ReactOS W32 Subsystem
- *  Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
 /*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Windows
- * FILE:             subsys/win32k/ntuser/window.c
+ * FILE:             subsystems/win32/win32k/ntuser/window.c
  * PROGRAMER:        Casper S. Hornstrup (chorns@users.sourceforge.net)
  * REVISION HISTORY:
  *       06-06-2001  CSH  Created
@@ -67,7 +49,7 @@ CleanupWindowImpl(VOID)
 
 /* HELPER FUNCTIONS ***********************************************************/
 
-BOOL FASTCALL UserUpdateUiState(PWINDOW Wnd, WPARAM wParam)
+BOOL FASTCALL UserUpdateUiState(PWND Wnd, WPARAM wParam)
 {
     WORD Action = LOWORD(wParam);
     WORD Flags = HIWORD(wParam);
@@ -111,9 +93,9 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
    Window = UserGetWindowObject(hWnd);
    if (Window)
    {
-      ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+      ASSERT(Window->head.cLockObj >= 0);
 
-      USER_BODY_TO_HEADER(Window)->RefCount++;
+      Window->head.cLockObj++;
    }
    return Window;
 }
@@ -121,7 +103,7 @@ PWINDOW_OBJECT FASTCALL IntGetWindowObject(HWND hWnd)
 /* temp hack */
 PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
 {
-   PW32THREADINFO ti;
+   PTHREADINFO ti;
    PWINDOW_OBJECT Window;
 
    if (PsGetCurrentProcess() != PsInitialSystemProcess)
@@ -141,13 +123,13 @@ PWINDOW_OBJECT FASTCALL UserGetWindowObject(HWND hWnd)
    }
 
    Window = (PWINDOW_OBJECT)UserGetObject(gHandleTable, hWnd, otWindow);
-   if (!Window || 0 != (Window->Status & WINDOWSTATUS_DESTROYED))
+   if (!Window || 0 != (Window->state & WINDOWSTATUS_DESTROYED))
    {
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return NULL;
    }
 
-   ASSERT(USER_BODY_TO_HEADER(Window)->RefCount >= 0);
+   ASSERT(Window->head.cLockObj >= 0);
    return Window;
 }
 
@@ -190,13 +172,15 @@ IntIsWindow(HWND hWnd)
 PWINDOW_OBJECT FASTCALL
 IntGetParent(PWINDOW_OBJECT Wnd)
 {
-   if (Wnd->Wnd->Style & WS_POPUP)
+   if (!Wnd->Wnd) return NULL;
+
+   if (Wnd->Wnd->style & WS_POPUP)
    {
       return UserGetWindowObject(Wnd->hOwner);
    }
-   else if (Wnd->Wnd->Style & WS_CHILD)
+   else if (Wnd->Wnd->style & WS_CHILD)
    {
-      return Wnd->Parent;
+      return Wnd->spwndParent;
    }
 
    return NULL;
@@ -234,7 +218,9 @@ IntWinListChildren(PWINDOW_OBJECT Window)
    HWND *List;
    UINT Index, NumChildren = 0;
 
-   for (Child = Window->FirstChild; Child; Child = Child->NextSibling)
+   if (!Window) return NULL;
+
+   for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
       ++NumChildren;
 
    List = ExAllocatePoolWithTag(PagedPool, (NumChildren + 1) * sizeof(HWND), TAG_WINLIST);
@@ -244,9 +230,9 @@ IntWinListChildren(PWINDOW_OBJECT Window)
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
       return NULL;
    }
-   for (Child = Window->FirstChild, Index = 0;
+   for (Child = Window->spwndChild, Index = 0;
          Child != NULL;
-         Child = Child->NextSibling, ++Index)
+         Child = Child->spwndNext, ++Index)
       List[Index] = Child->hSelf;
    List[Index] = NULL;
 
@@ -328,27 +314,29 @@ static void IntSendDestroyMsg(HWND hWnd)
 }
 
 static VOID
-UserFreeWindowInfo(PW32THREADINFO ti, PWINDOW_OBJECT WindowObject)
+UserFreeWindowInfo(PTHREADINFO ti, PWINDOW_OBJECT WindowObject)
 {
     PCLIENTINFO ClientInfo = GetWin32ClientInfo();
-    PWINDOW Wnd = WindowObject->Wnd;
+    PWND Wnd = WindowObject->Wnd;
 
+    if (!Wnd) return;
+    
     if (ClientInfo->CallbackWnd.pvWnd == DesktopHeapAddressToUser(WindowObject->Wnd))
     {
         ClientInfo->CallbackWnd.hWnd = NULL;
         ClientInfo->CallbackWnd.pvWnd = NULL;
     }
 
-   if (Wnd->WindowName.Buffer != NULL)
+   if (Wnd->strName.Buffer != NULL)
    {
-       Wnd->WindowName.Length = 0;
-       Wnd->WindowName.MaximumLength = 0;
-       DesktopHeapFree(Wnd->pdesktop,
-                       Wnd->WindowName.Buffer);
-       Wnd->WindowName.Buffer = NULL;
+       Wnd->strName.Length = 0;
+       Wnd->strName.MaximumLength = 0;
+       DesktopHeapFree(Wnd->head.rpdesk,
+                       Wnd->strName.Buffer);
+       Wnd->strName.Buffer = NULL;
    }
 
-    DesktopHeapFree(Wnd->pdesktop, Wnd);
+    DesktopHeapFree(Wnd->head.rpdesk, Wnd);
     WindowObject->Wnd = NULL;
 }
 
@@ -362,7 +350,7 @@ UserFreeWindowInfo(PW32THREADINFO ti, PWINDOW_OBJECT WindowObject)
 
  */
 static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
-                                   PW32PROCESS ProcessData,
+                                   PPROCESSINFO ProcessData,
                                    PTHREADINFO ThreadData,
                                    BOOLEAN SendMessages)
 {
@@ -371,19 +359,22 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
    PWINDOW_OBJECT Child;
    PMENU_OBJECT Menu;
    BOOLEAN BelongsToThreadData;
-   PWINDOW Wnd;
+   PWND Wnd;
 
    ASSERT(Window);
 
    Wnd = Window->Wnd;
 
-   if(Window->Status & WINDOWSTATUS_DESTROYING)
+   if(Window->state & WINDOWSTATUS_DESTROYING)
    {
       DPRINT("Tried to call IntDestroyWindow() twice\n");
       return 0;
    }
-   Window->Status |= WINDOWSTATUS_DESTROYING;
-   Wnd->Style &= ~WS_VISIBLE;
+   Window->state |= WINDOWSTATUS_DESTROYING;
+   Wnd->style &= ~WS_VISIBLE;
+
+   IntNotifyWinEvent(EVENT_OBJECT_DESTROY, Wnd, OBJID_WINDOW, 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
       in IntDestroyWindow() */
@@ -434,22 +425,26 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
          co_IntSendMessage(Window->hSelf, WM_NCDESTROY, 0, 0);
    }
    MsqRemoveTimersWindow(ThreadData->MessageQueue, Window->hSelf);
+   HOOK_DestroyThreadHooks(ThreadData->pEThread); // This is needed here too!
 
    /* flush the message queue */
    MsqRemoveWindowMessagesFromQueue(Window);
 
    /* from now on no messages can be sent to this window anymore */
-   Window->Status |= WINDOWSTATUS_DESTROYED;
+   Window->state |= WINDOWSTATUS_DESTROYED;
+   Wnd->state |= WNDS_DESTROYED;
+   Wnd->fnid |= FNID_FREED;
+
    /* don't remove the WINDOWSTATUS_DESTROYING bit */
 
    /* reset shell window handles */
-   if(ThreadData->Desktop)
+   if(ThreadData->rpdesk)
    {
-      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellWindow)
-         ThreadData->Desktop->WindowStation->ShellWindow = NULL;
+      if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellWindow)
+         ThreadData->rpdesk->rpwinstaParent->ShellWindow = NULL;
 
-      if (Window->hSelf == ThreadData->Desktop->WindowStation->ShellListView)
-         ThreadData->Desktop->WindowStation->ShellListView = NULL;
+      if (Window->hSelf == ThreadData->rpdesk->rpwinstaParent->ShellListView)
+         ThreadData->rpdesk->rpwinstaParent->ShellListView = NULL;
    }
 
    /* Unregister hot keys */
@@ -469,7 +464,7 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
    TIMER_RemoveWindowTimers(Window->hSelf);
 #endif
 
-   if (!(Wnd->Style & WS_CHILD) && Wnd->IDMenu
+   if (!(Wnd->style & WS_CHILD) && Wnd->IDMenu
        && (Menu = UserGetMenuObject((HMENU)Wnd->IDMenu)))
    {
       IntDestroyMenuObject(Menu, TRUE, TRUE);
@@ -498,18 +493,18 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
    IntDestroyScrollBars(Window);
 
    /* dereference the class */
-   IntDereferenceClass(Wnd->Class,
-                       Window->ti->pDeskInfo,
-                       Window->ti->ppi);
-   Wnd->Class = NULL;
+   IntDereferenceClass(Wnd->pcls,
+                       Window->pti->pDeskInfo,
+                       Window->pti->ppi);
+   Wnd->pcls = NULL;
 
-   if(Window->WindowRegion)
+   if(Window->hrgnClip)
    {
-      GreDeleteObject(Window->WindowRegion);
+      GreDeleteObject(Window->hrgnClip);
    }
 
    ASSERT(Window->Wnd != NULL);
-   UserFreeWindowInfo(Window->ti, Window);
+   UserFreeWindowInfo(Window->pti, Window);
 
    UserDereferenceObject(Window);
 
@@ -521,20 +516,20 @@ static LRESULT co_UserFreeWindow(PWINDOW_OBJECT Window,
 VOID FASTCALL
 IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
 {
-   PWINDOW Wnd = Window->Wnd;
-   if(HAS_DLGFRAME(Wnd->Style, Wnd->ExStyle) && !(Wnd->Style & WS_MINIMIZE))
+   PWND Wnd = Window->Wnd;
+   if(HAS_DLGFRAME(Wnd->style, Wnd->ExStyle) && !(Wnd->style & WS_MINIMIZE))
    {
       *cx = UserGetSystemMetrics(SM_CXDLGFRAME);
       *cy = UserGetSystemMetrics(SM_CYDLGFRAME);
    }
    else
    {
-      if(HAS_THICKFRAME(Wnd->Style, Wnd->ExStyle)&& !(Wnd->Style & WS_MINIMIZE))
+      if(HAS_THICKFRAME(Wnd->style, Wnd->ExStyle)&& !(Wnd->style & WS_MINIMIZE))
       {
          *cx = UserGetSystemMetrics(SM_CXFRAME);
          *cy = UserGetSystemMetrics(SM_CYFRAME);
       }
-      else if(HAS_THINFRAME(Wnd->Style, Wnd->ExStyle))
+      else if(HAS_THINFRAME(Wnd->style, Wnd->ExStyle))
       {
          *cx = UserGetSystemMetrics(SM_CXBORDER);
          *cy = UserGetSystemMetrics(SM_CYBORDER);
@@ -546,77 +541,163 @@ IntGetWindowBorderMeasures(PWINDOW_OBJECT Window, UINT *cx, UINT *cy)
    }
 }
 
-static WNDPROC
-IntGetWindowProc(IN PWINDOW_OBJECT Window,
-                 IN BOOL Ansi)
+//
+// Same as User32:IntGetWndProc.
+//
+WNDPROC FASTCALL
+IntGetWindowProc(PWND pWnd,
+                 BOOL Ansi)
 {
-    PWINDOW Wnd = Window->Wnd;
+   INT i;
+   PCLS Class;
+   WNDPROC gcpd, Ret = 0;
 
-    ASSERT(UserIsEnteredExclusive() == TRUE);
+   ASSERT(UserIsEnteredExclusive() == TRUE);
 
-    if (Wnd->IsSystem)
-    {
-        return (Ansi ? Wnd->WndProcExtra : Wnd->WndProc);
-    }
-    else
-    {
-        if (!Ansi == Wnd->Unicode)
-        {
-            return Wnd->WndProc;
-        }
-        else
-        {
-            if (Wnd->CallProc != NULL)
-            {
-                return GetCallProcHandle(Wnd->CallProc);
-            }
-            /* BUGBOY Comments: Maybe theres something Im not undestanding here, but why would a CallProc be created
-               on a function that I thought is only suppose to return the current Windows Proc? */
+   Class = pWnd->pcls;
+
+   if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
+   {
+      for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
+      {
+         if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
+         {
+            if (Ansi)
+               Ret = GETPFNCLIENTA(i);
             else
-            {
-                PCALLPROC NewCallProc, CallProc;
+               Ret = GETPFNCLIENTW(i);
+         }
+      }
+      return Ret;
+   }
 
-                NewCallProc = UserFindCallProc(Wnd->Class,
-                                               Wnd->WndProc,
-                                               Wnd->Unicode);
-                if (NewCallProc == NULL)
-                {
-                    NewCallProc = CreateCallProc(Wnd->ti->pDeskInfo,
-                                                 Wnd->WndProc,
-                                                 Wnd->Unicode,
-                                                 Wnd->ti->ppi);
-                    if (NewCallProc == NULL)
-                    {
-                        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-                        return NULL;
-                    }
-
-                    UserAddCallProcToClass(Wnd->Class,
-                                           NewCallProc);
-                }
+   if (Class->fnid == FNID_EDIT)
+      Ret = pWnd->lpfnWndProc;
+   else
+   {
+      Ret = pWnd->lpfnWndProc;
+
+      if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
+      {
+         if (Ansi)
+         {
+            if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
+               Ret = GETPFNCLIENTA(Class->fnid);
+         }
+         else
+         {
+            if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
+               Ret = GETPFNCLIENTW(Class->fnid);
+         }
+      }
+      if ( Ret != pWnd->lpfnWndProc)
+         return Ret;
+   }
+   if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
+      return Ret;
 
-                CallProc = Wnd->CallProc;
-                Wnd->CallProc = NewCallProc;
+   gcpd = (WNDPROC)UserGetCPD(
+                       pWnd,
+                      (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
+                      (ULONG_PTR)Ret);
 
-                return GetCallProcHandle((CallProc == NULL ? NewCallProc : CallProc));
-            }
-        }
-    }
+   return (gcpd ? gcpd : Ret);
 }
 
+static WNDPROC
+IntSetWindowProc(PWND pWnd,
+                 WNDPROC NewWndProc,
+                 BOOL Ansi)
+{
+   INT i;
+   PCALLPROCDATA CallProc;
+   PCLS Class;
+   WNDPROC Ret, chWndProc = NULL;
+
+   // Retrieve previous window proc.
+   Ret = IntGetWindowProc(pWnd, Ansi);
+
+   Class = pWnd->pcls;
+
+   if (IsCallProcHandle(NewWndProc))
+   {
+      CallProc = UserGetObject(gHandleTable, NewWndProc, otCallProc);
+      if (CallProc)
+      {  // Reset new WndProc.
+         NewWndProc = CallProc->pfnClientPrevious;
+         // Reset Ansi from CallProc handle. This is expected with wine "deftest".
+         Ansi = !!(CallProc->wType & UserGetCPDU2A);
+      }
+   }
+   // Switch from Client Side call to Server Side call if match. Ref: "deftest".
+   for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
+   {
+       if (GETPFNCLIENTW(i) == NewWndProc)
+       {
+          chWndProc = GETPFNSERVER(i);
+          break;
+       }
+       if (GETPFNCLIENTA(i) == NewWndProc)
+       {
+          chWndProc = GETPFNSERVER(i);
+          break;
+       }
+   }
+   // If match, set/reset to Server Side and clear ansi.
+   if (chWndProc)
+   {
+      pWnd->lpfnWndProc = chWndProc;
+      pWnd->Unicode = TRUE;
+      pWnd->state &= ~WNDS_ANSIWINDOWPROC;
+      pWnd->state |= WNDS_SERVERSIDEWINDOWPROC;
+   }
+   else
+   {
+      pWnd->Unicode = !Ansi;
+      // Handle the state change in here.
+      if (Ansi)
+         pWnd->state |= WNDS_ANSIWINDOWPROC;
+      else
+         pWnd->state &= ~WNDS_ANSIWINDOWPROC;
+
+      if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
+         pWnd->state &= ~WNDS_SERVERSIDEWINDOWPROC;
+
+      if (!NewWndProc) NewWndProc = pWnd->lpfnWndProc;
+
+      if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
+      {
+         if (Ansi)
+         {
+            if (GETPFNCLIENTW(Class->fnid) == NewWndProc)
+               chWndProc = GETPFNCLIENTA(Class->fnid);
+         }
+         else
+         {
+            if (GETPFNCLIENTA(Class->fnid) == NewWndProc)
+               chWndProc = GETPFNCLIENTW(Class->fnid);
+         }
+      }
+      // Now set the new window proc.
+      pWnd->lpfnWndProc = (chWndProc ? chWndProc : NewWndProc);
+   }
+   return Ret;
+}
+
+// Move this to user space!
 BOOL FASTCALL
 IntGetWindowInfo(PWINDOW_OBJECT Window, PWINDOWINFO pwi)
 {
-   PWINDOW Wnd = Window->Wnd;
+   PWND Wnd = Window->Wnd;
 
    pwi->cbSize = sizeof(WINDOWINFO);
-   pwi->rcWindow = Window->Wnd->WindowRect;
-   pwi->rcClient = Window->Wnd->ClientRect;
-   pwi->dwStyle = Wnd->Style;
+   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->Class ? Wnd->Class->Atom : 0);
+   pwi->atomWindowType = (Wnd->pcls ? Wnd->pcls->atomClassName : 0);
    pwi->wCreatorVersion = 0x400; /* FIXME - return a real version number */
    return TRUE;
 }
@@ -628,9 +709,9 @@ IntSetMenu(
    BOOL *Changed)
 {
    PMENU_OBJECT OldMenu, NewMenu = NULL;
-   PWINDOW Wnd = Window->Wnd;
+   PWND Wnd = Window->Wnd;
 
-   if ((Wnd->Style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+   if ((Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
    {
       SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
@@ -745,8 +826,8 @@ IntGetClientRect(PWINDOW_OBJECT Window, RECTL *Rect)
    ASSERT( Rect );
 
    Rect->left = Rect->top = 0;
-   Rect->right = Window->Wnd->ClientRect.right - Window->Wnd->ClientRect.left;
-   Rect->bottom = Window->Wnd->ClientRect.bottom - Window->Wnd->ClientRect.top;
+   Rect->right = Window->Wnd->rcClient.right - Window->Wnd->rcClient.left;
+   Rect->bottom = Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top;
 }
 
 
@@ -781,7 +862,7 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
    {
       W32Thread = PsGetCurrentThreadWin32Thread();
 
-      if(!W32Thread->Desktop)
+      if(!W32Thread->rpdesk)
          return NULL;
 
       if(Window->SystemMenu)
@@ -794,10 +875,10 @@ IntGetSystemMenu(PWINDOW_OBJECT Window, BOOL bRevert, BOOL RetMenu)
          }
       }
 
-      if(W32Thread->Desktop->WindowStation->SystemMenuTemplate)
+      if(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate)
       {
          /* clone system menu */
-         Menu = UserGetMenuObject(W32Thread->Desktop->WindowStation->SystemMenuTemplate);
+         Menu = UserGetMenuObject(W32Thread->rpdesk->rpwinstaParent->SystemMenuTemplate);
          if(!Menu)
             return NULL;
 
@@ -882,7 +963,7 @@ BOOL FASTCALL
 IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
 
    Window = BaseWindow;
    while (Window)
@@ -892,12 +973,12 @@ IntIsChildWindow(PWINDOW_OBJECT Parent, PWINDOW_OBJECT BaseWindow)
       {
          return(TRUE);
       }
-      if(!(Wnd->Style & WS_CHILD))
+      if(!(Wnd->style & WS_CHILD))
       {
          break;
       }
 
-      Window = Window->Parent;
+      Window = Window->spwndParent;
    }
 
    return(FALSE);
@@ -907,25 +988,25 @@ BOOL FASTCALL
 IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
 
    Window = BaseWindow;
    while(Window)
    {
       Wnd = Window->Wnd;
-      if(!(Wnd->Style & WS_CHILD))
+      if(!(Wnd->style & WS_CHILD))
       {
          break;
       }
-      if(!(Wnd->Style & WS_VISIBLE))
+      if(!(Wnd->style & WS_VISIBLE))
       {
          return FALSE;
       }
 
-      Window = Window->Parent;
+      Window = Window->spwndParent;
    }
 
-   if(Window && Wnd->Style & WS_VISIBLE)
+   if(Window && Wnd->style & WS_VISIBLE)
    {
       return TRUE;
    }
@@ -933,6 +1014,31 @@ IntIsWindowVisible(PWINDOW_OBJECT BaseWindow)
    return FALSE;
 }
 
+VOID FASTCALL
+IntLinkWnd(
+   PWND Wnd,
+   PWND WndParent,
+   PWND WndPrevSibling) /* set to NULL if top sibling */
+{
+   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 */
+      if ((Wnd->spwndNext = WndParent->spwndChild))
+         Wnd->spwndNext->spwndPrev = Wnd;
+      
+      WndParent->spwndChild = Wnd;
+   }
+
+}
 
 /* link the window into siblings and parent. children are kept in place. */
 VOID FASTCALL
@@ -944,35 +1050,32 @@ IntLinkWindow(
 {
    PWINDOW_OBJECT Parent;
 
-   Wnd->Parent = WndParent;
-   Wnd->Wnd->Parent = WndParent ? WndParent->Wnd : NULL;
-   if ((Wnd->PrevSibling = WndPrevSibling))
+   IntLinkWnd(Wnd->Wnd, 
+              WndParent->Wnd, 
+              WndPrevSibling ? WndPrevSibling->Wnd : NULL);
+
+   Wnd->spwndParent = WndParent;
+   if ((Wnd->spwndPrev = WndPrevSibling))
    {
       /* link after WndPrevSibling */
-      if ((Wnd->NextSibling = WndPrevSibling->NextSibling))
-         Wnd->NextSibling->PrevSibling = Wnd;
-      else if ((Parent = Wnd->Parent))
-      {
-         if(Parent->LastChild == WndPrevSibling)
-            Parent->LastChild = Wnd;
-      }
-      Wnd->PrevSibling->NextSibling = Wnd;
+      if ((Wnd->spwndNext = WndPrevSibling->spwndNext))
+         Wnd->spwndNext->spwndPrev = Wnd;
+      Wnd->spwndPrev->spwndNext = Wnd;
    }
    else
    {
       /* link at top */
-      Parent = Wnd->Parent;
-      if ((Wnd->NextSibling = WndParent->FirstChild))
-         Wnd->NextSibling->PrevSibling = Wnd;
+      Parent = Wnd->spwndParent;
+      if ((Wnd->spwndNext = WndParent->spwndChild))
+         Wnd->spwndNext->spwndPrev = Wnd;
       else if (Parent)
       {
-         Parent->LastChild = Wnd;
-         Parent->FirstChild = Wnd;
+         Parent->spwndChild = Wnd;
          return;
       }
       if(Parent)
       {
-         Parent->FirstChild = Wnd;
+         Parent->spwndChild = Wnd;
       }
    }
 
@@ -1002,12 +1105,12 @@ IntSetOwner(HWND hWnd, HWND hWndNewOwner)
    if((WndNewOwner = UserGetWindowObject(hWndNewOwner)))
    {
       Wnd->hOwner = hWndNewOwner;
-      Wnd->Wnd->Owner = WndNewOwner->Wnd;
+      Wnd->Wnd->spwndOwner = WndNewOwner->Wnd;
    }
    else
    {
       Wnd->hOwner = NULL;
-      Wnd->Wnd->Owner = NULL;
+      Wnd->Wnd->spwndOwner = NULL;
    }
 
    UserDereferenceObject(Wnd);
@@ -1029,6 +1132,13 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
 //   hWnd = Wnd->hSelf;
 //   hWndNewParent = WndNewParent->hSelf;
 
+   /* Some applications try to set a child as a parent */
+   if (IntIsChildWindow(Wnd, WndNewParent))
+   {
+      SetLastWin32Error( ERROR_INVALID_PARAMETER );
+      return NULL;
+   }
+
    /*
     * Windows hides the window first, then shows it again
     * including the WM_SHOWWINDOW messages and all
@@ -1040,10 +1150,10 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
 //      return NULL;
 
    /* Window must belong to current process */
-   if (Wnd->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
+   if (Wnd->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
       return NULL;
 
-   WndOldParent = Wnd->Parent;
+   WndOldParent = Wnd->spwndParent;
 
    if (WndOldParent) UserReferenceObject(WndOldParent); /* caller must deref */
 
@@ -1054,11 +1164,11 @@ co_IntSetParent(PWINDOW_OBJECT Wnd, PWINDOW_OBJECT WndNewParent)
       if (0 == (Wnd->Wnd->ExStyle & WS_EX_TOPMOST))
       {
          /* Not a TOPMOST window, put after TOPMOSTs of new parent */
-         Sibling = WndNewParent->FirstChild;
+         Sibling = WndNewParent->spwndChild;
          while (NULL != Sibling && 0 != (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
          {
             InsertAfter = Sibling;
-            Sibling = Sibling->NextSibling;
+            Sibling = Sibling->spwndNext;
          }
       }
       if (NULL == InsertAfter)
@@ -1133,26 +1243,40 @@ 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. */
 VOID FASTCALL
 IntUnlinkWindow(PWINDOW_OBJECT Wnd)
 {
-   PWINDOW_OBJECT WndParent = Wnd->Parent;
+   PWINDOW_OBJECT WndParent = Wnd->spwndParent;
+
+   IntUnlinkWnd(Wnd->Wnd);
 
-   if (Wnd->NextSibling)
-      Wnd->NextSibling->PrevSibling = Wnd->PrevSibling;
-   else if (WndParent && WndParent->LastChild == Wnd)
-      WndParent->LastChild = Wnd->PrevSibling;
+   if (Wnd->spwndNext)
+      Wnd->spwndNext->spwndPrev = Wnd->spwndPrev;
 
-   if (Wnd->PrevSibling)
-      Wnd->PrevSibling->NextSibling = Wnd->NextSibling;
-   else if (WndParent && WndParent->FirstChild == Wnd)
-      WndParent->FirstChild = Wnd->NextSibling;
+   if (Wnd->spwndPrev)
+      Wnd->spwndPrev->spwndNext = Wnd->spwndNext;
+   else if (WndParent && WndParent->spwndChild == Wnd)
+      WndParent->spwndChild = Wnd->spwndNext;
 
-   Wnd->PrevSibling = Wnd->NextSibling = Wnd->Parent = NULL;
-   if (Wnd->Wnd)
-       Wnd->Wnd->Parent = NULL;
+   Wnd->spwndPrev = Wnd->spwndNext = Wnd->spwndParent = NULL;
 }
 
 BOOL FASTCALL
@@ -1165,9 +1289,9 @@ IntAnyPopup(VOID)
       return FALSE;
    }
 
-   for(Child = Window->FirstChild; Child; Child = Child->NextSibling)
+   for(Child = Window->spwndChild; Child; Child = Child->spwndNext)
    {
-      if(Child->hOwner && Child->Wnd->Style & WS_VISIBLE)
+      if(Child->hOwner && Child->Wnd->style & WS_VISIBLE)
       {
          /*
           * The desktop has a popup window if one of them has
@@ -1183,7 +1307,7 @@ IntAnyPopup(VOID)
 BOOL FASTCALL
 IntIsWindowInDestroy(PWINDOW_OBJECT Window)
 {
-   return ((Window->Status & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
+   return ((Window->state & WINDOWSTATUS_DESTROYING) == WINDOWSTATUS_DESTROYING);
 }
 
 
@@ -1191,7 +1315,7 @@ BOOL
 FASTCALL
 IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
 {
-   PWINDOW Wnd;
+   PWND Wnd;
    POINT Size;
 
    Wnd = Window->Wnd;
@@ -1203,28 +1327,28 @@ IntGetWindowPlacement(PWINDOW_OBJECT Window, WINDOWPLACEMENT *lpwndpl)
    }
 
    lpwndpl->flags = 0;
-   if (0 == (Wnd->Style & WS_VISIBLE))
+   if (0 == (Wnd->style & WS_VISIBLE))
    {
       lpwndpl->showCmd = SW_HIDE;
    }
-   else if (0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
-            0 != (Wnd->Style & WS_MAXIMIZE))
+   else if (0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
+            0 != (Wnd->style & WS_MAXIMIZE))
    {
       lpwndpl->showCmd = SW_MAXIMIZE;
    }
-   else if (0 != (Wnd->Style & WS_MINIMIZE))
+   else if (0 != (Wnd->style & WS_MINIMIZE))
    {
       lpwndpl->showCmd = SW_MINIMIZE;
    }
-   else if (0 != (Wnd->Style & WS_VISIBLE))
+   else if (0 != (Wnd->style & WS_VISIBLE))
    {
       lpwndpl->showCmd = SW_SHOWNORMAL;
    }
 
-   Size.x = Wnd->WindowRect.left;
-   Size.y = Wnd->WindowRect.top;
+   Size.x = Wnd->rcWindow.left;
+   Size.y = Wnd->rcWindow.top;
    WinPosInitInternalPos(Window, &Size,
-                         &Wnd->WindowRect);
+                         &Wnd->rcWindow);
 
    lpwndpl->rcNormalPosition = Wnd->InternalPos.NormalRect;
    lpwndpl->ptMinPosition = Wnd->InternalPos.IconPos;
@@ -1308,7 +1432,7 @@ NtUserBuildHwndList(
       }
 
       if((Parent = UserGetWindowObject(hwndParent)) &&
-         (Window = Parent->FirstChild))
+         (Window = Parent->spwndChild))
       {
          BOOL bGoDown = TRUE;
 
@@ -1336,20 +1460,20 @@ NtUserBuildHwndList(
                      break;
                   }
                }
-               if (Window->FirstChild && bChildren)
+               if (Window->spwndChild && bChildren)
                {
-                  Window = Window->FirstChild;
+                  Window = Window->spwndChild;
                   continue;
                }
                bGoDown = FALSE;
             }
-            if (Window->NextSibling)
+            if (Window->spwndNext)
             {
-               Window = Window->NextSibling;
+               Window = Window->spwndNext;
                bGoDown = TRUE;
                continue;
             }
-            Window = Window->Parent;
+            Window = Window->spwndParent;
             if (Window == Parent)
             {
                break;
@@ -1435,8 +1559,8 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
 
    if(Parent->hSelf != IntGetDesktopWindow())
    {
-      Pt.x += Parent->Wnd->ClientRect.left;
-      Pt.y += Parent->Wnd->ClientRect.top;
+      Pt.x += Parent->Wnd->rcClient.left;
+      Pt.y += Parent->Wnd->rcClient.top;
    }
 
    if(!IntPtInWindow(Parent, Pt.x, Pt.y))
@@ -1450,15 +1574,15 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
       for(phWnd = List; *phWnd; phWnd++)
       {
          PWINDOW_OBJECT Child;
-         PWINDOW ChildWnd;
+         PWND ChildWnd;
          if((Child = UserGetWindowObject(*phWnd)))
          {
             ChildWnd = Child->Wnd;
-            if(!(ChildWnd->Style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
+            if(!(ChildWnd->style & WS_VISIBLE) && (uiFlags & CWP_SKIPINVISIBLE))
             {
                continue;
             }
-            if((ChildWnd->Style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
+            if((ChildWnd->style & WS_DISABLED) && (uiFlags & CWP_SKIPDISABLED))
             {
                continue;
             }
@@ -1484,28 +1608,31 @@ NtUserChildWindowFromPointEx(HWND hwndParent,
  * calculates the default position of a window
  */
 BOOL FASTCALL
-IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT Window, RECTL *rc, BOOL IncPos)
+IntCalcDefPosSize(PWINDOW_OBJECT Parent, RECTL *rc, BOOL IncPos)
 {
    SIZE Sz;
+   PMONITOR pMonitor;
    POINT Pos = {0, 0};
+   
+   pMonitor = IntGetPrimaryMonitor();
 
    if(Parent != NULL)
    {
-      RECTL_bIntersectRect(rc, rc, &Parent->Wnd->ClientRect);
+      RECTL_bIntersectRect(rc, rc, &pMonitor->rcMonitor);
 
       if(IncPos)
       {
-         Pos.x = Parent->TiledCounter * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
-         Pos.y = Parent->TiledCounter * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
-         if(Pos.x > ((rc->right - rc->left) / 4) ||
-               Pos.y > ((rc->bottom - rc->top) / 4))
+         Pos.x = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CXSIZE) + UserGetSystemMetrics(SM_CXFRAME));
+         Pos.y = pMonitor->cWndStack * (UserGetSystemMetrics(SM_CYSIZE) + UserGetSystemMetrics(SM_CYFRAME));
+         if (Pos.x > ((rc->right - rc->left) / 4) ||
+             Pos.y > ((rc->bottom - rc->top) / 4))
          {
             /* reset counter and position */
             Pos.x = 0;
             Pos.y = 0;
-            Parent->TiledCounter = 0;
+            pMonitor->cWndStack = 0;
          }
-         Parent->TiledCounter++;
+         pMonitor->cWndStack++;
       }
       Pos.x += rc->left;
       Pos.y += rc->top;
@@ -1530,7 +1657,7 @@ IntCalcDefPosSize(PWINDOW_OBJECT Parent, PWINDOW_OBJECT Window, RECTL *rc, BOOL
 /*
  * @implemented
  */
-HWND APIENTRY
+PWND APIENTRY
 co_IntCreateWindowEx(DWORD dwExStyle,
                      PUNICODE_STRING ClassName,
                      PUNICODE_STRING WindowName,
@@ -1547,18 +1674,18 @@ co_IntCreateWindowEx(DWORD dwExStyle,
                      BOOL bUnicodeWindow)
 {
    PWINSTATION_OBJECT WinSta;
-   PWINDOW Wnd = NULL;
-   PWINDOWCLASS *ClassLink, Class = NULL;
+   PWND Wnd = NULL;
+   PCLS *ClassLink, Class = NULL;
    RTL_ATOM ClassAtom;
    PWINDOW_OBJECT Window = NULL;
    PWINDOW_OBJECT ParentWindow = NULL, OwnerWindow;
-   HWND ParentWindowHandle;
+   HWND ParentWindowHandle = NULL;
    HWND OwnerWindowHandle;
    PMENU_OBJECT SystemMenu;
    HWND hWnd;
    POINT Pos;
    SIZE Size;
-   PW32THREADINFO ti = NULL;
+   PTHREADINFO ti = NULL;
 #if 0
 
    POINT MaxSize, MaxPos, MinTrack, MaxTrack;
@@ -1570,23 +1697,36 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    CBT_CREATEWNDW CbtCreate;
    LRESULT Result;
    BOOL MenuChanged;
-   DECLARE_RETURN(HWND);
+   DECLARE_RETURN(PWND);
    BOOL HasOwner;
    USER_REFERENCE_ENTRY ParentRef, Ref;
    PTHREADINFO pti;
 
    pti = PsGetCurrentThreadWin32Thread();
-   ParentWindowHandle = pti->Desktop->DesktopWindow;
+
+   if (pti->rpdesk)
+   {
+       ParentWindowHandle = pti->rpdesk->DesktopWindow;
+   }
+
+
+   if ( !(pti->ppi->W32PF_flags & W32PF_CLASSESREGISTERED ))
+   {
+      UserRegisterSystemClasses();
+   }
+   
    OwnerWindowHandle = NULL;
 
+   DPRINT("co_IntCreateWindowEx %wZ\n", ClassName);
+
    if (hWndParent == HWND_MESSAGE)
    {
       /*
        * native ole32.OleInitialize uses HWND_MESSAGE to create the
        * message window (style: WS_POPUP|WS_DISABLED)
        */
-      DPRINT("FIXME - Parent is HWND_MESSAGE\n");
-      // ParentWindowHandle set already.      
+      ParentWindowHandle = IntGetMessageWindow();
+      DPRINT("Parent is HWND_MESSAGE 0x%x\n", ParentWindowHandle);
    }
    else if (hWndParent)
    {
@@ -1602,32 +1742,34 @@ co_IntCreateWindowEx(DWORD dwExStyle,
    else if ((dwStyle & (WS_CHILD | WS_POPUP)) == WS_CHILD)
    {
       SetLastWin32Error(ERROR_TLW_WITH_WSCHILD);
-      RETURN( (HWND)0);  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
+      RETURN( (PWND)0);  /* WS_CHILD needs a parent, but WS_POPUP doesn't */
    }
 
-//   if (NULL != ParentWindowHandle)
-//   {
-   ParentWindow = UserGetWindowObject(ParentWindowHandle);
+   if (ParentWindowHandle)
+   {
+      ParentWindow = UserGetWindowObject(ParentWindowHandle);
 
-   if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef);
-//   }
-//   else
-//   {
-//      ParentWindow = NULL;
-//   }
+      if (ParentWindow) UserRefObjectCo(ParentWindow, &ParentRef);
+   }
+   else
+   {
+      ParentWindow = NULL;
+   }
 
    /* FIXME: parent must belong to the current process */
 
    /* Check the window station. */
    ti = GetW32ThreadInfo();
-   if (ti == NULL || pti->Desktop == NULL)
+   if (ti == NULL || pti->rpdesk == NULL)
    {
       DPRINT1("Thread is not attached to a desktop! Cannot create window!\n");
-      RETURN( (HWND)0);
+      RETURN( (PWND)0);
    }
 
    /* Check the class. */
 
+   DPRINT("Class %wZ\n", ClassName);
+
    ClassAtom = IntGetClassAtom(ClassName,
                                hInstance,
                                ti->ppi,
@@ -1646,42 +1788,45 @@ co_IntCreateWindowEx(DWORD dwExStyle,
       }
 
       SetLastWin32Error(ERROR_CANNOT_FIND_WND_CLASS);
-      RETURN((HWND)0);
+      RETURN((PWND)0);
    }
-
+   DPRINT("ClassAtom %x\n", ClassAtom);
    Class = IntReferenceClass(Class,
                              ClassLink,
-                             pti->Desktop);
+                             pti->rpdesk);
    if (Class == NULL)
    {
        DPRINT1("Failed to reference window class!\n");
        RETURN(NULL);
    }
 
-   WinSta = pti->Desktop->WindowStation;
+   WinSta = pti->rpdesk->rpwinstaParent;
 
    //FIXME: Reference thread/desktop instead
    ObReferenceObjectByPointer(WinSta, KernelMode, ExWindowStationObjectType, 0);
 
    /* Create the window object. */
-   Window = (PWINDOW_OBJECT)
-            UserCreateObject(gHandleTable, (PHANDLE)&hWnd,
-                            otWindow, sizeof(WINDOW_OBJECT));
+   Window = (PWINDOW_OBJECT) UserCreateObject( gHandleTable,
+                                               pti->rpdesk,
+                                               (PHANDLE)&hWnd,
+                                               otWindow,
+                                               sizeof(WINDOW_OBJECT));
    if (Window)
    {
-       Window->Wnd = DesktopHeapAlloc(pti->Desktop,
-                                      sizeof(WINDOW) + Class->WndExtra);
+       Window->Wnd = DesktopHeapAlloc(pti->rpdesk,
+                                      sizeof(WND) + Class->cbwndExtra);
        if (!Window->Wnd)
            goto AllocErr;
        RtlZeroMemory(Window->Wnd,
-                     sizeof(WINDOW) + Class->WndExtra);
-       Window->Wnd->hdr.Handle = hWnd; /* FIXME: Remove hack */
+                     sizeof(WND) + Class->cbwndExtra);
+       Window->Wnd->head.h = hWnd;
        Wnd = Window->Wnd;
+       Wnd->fnid = 0;
 
-       Wnd->ti = ti;
-       Wnd->pi = ti->ppi;
-       Wnd->pdesktop = pti->Desktop;
+       Wnd->head.pti = ti;
+       Wnd->head.rpdesk = pti->rpdesk;
        Wnd->hWndLastActive = hWnd;
+       Wnd->state2 |= WNDS2_WIN40COMPAT;
    }
 
    DPRINT("Created object with handle %X\n", hWnd);
@@ -1690,113 +1835,154 @@ co_IntCreateWindowEx(DWORD dwExStyle,
 AllocErr:
       ObDereferenceObject(WinSta);
       SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-      RETURN( (HWND)0);
+      RETURN( (PWND)0);
    }
 
    UserRefObjectCo(Window, &Ref);
 
    ObDereferenceObject(WinSta);
 
-   if (NULL == pti->Desktop->DesktopWindow)
+   if (NULL == pti->rpdesk->DesktopWindow)
    {
       /* If there is no desktop window yet, we must be creating it */
-      pti->Desktop->DesktopWindow = hWnd;
-      pti->Desktop->DesktopInfo->Wnd = Wnd;
+      pti->rpdesk->DesktopWindow = hWnd;
+      pti->rpdesk->pDeskInfo->spwnd = Wnd;
    }
 
    /*
     * Fill out the structure describing it.
     */
-   Window->ti = ti;
-   Wnd->Class = Class;
+   Window->pti = ti;
+   Wnd->pcls = Class;
    Class = NULL;
 
    Window->SystemMenu = (HMENU)0;
-   Wnd->ContextHelpId = 0;
    Wnd->IDMenu = 0;
-   Wnd->Instance = hInstance;
+   Wnd->hModule = hInstance;
    Window->hSelf = hWnd;
 
-   Window->MessageQueue = pti->MessageQueue;
-   IntReferenceMessageQueue(Window->MessageQueue);
-   Window->Parent = ParentWindow;
-   Wnd->Parent = ParentWindow ? ParentWindow->Wnd : NULL;
-   if (Wnd->Parent != NULL && hWndParent != 0)
+   IntReferenceMessageQueue(Window->pti->MessageQueue);
+   Window->spwndParent = ParentWindow;
+   Wnd->spwndParent = ParentWindow ? ParentWindow->Wnd : NULL;
+   if (Wnd->spwndParent != NULL && hWndParent != 0)
    {
-       Wnd->HideFocus = Wnd->Parent->HideFocus;
-       Wnd->HideAccel = Wnd->Parent->HideAccel;
+       Wnd->HideFocus = Wnd->spwndParent->HideFocus;
+       Wnd->HideAccel = Wnd->spwndParent->HideAccel;
    }
 
    if((OwnerWindow = UserGetWindowObject(OwnerWindowHandle)))
    {
       Window->hOwner = OwnerWindowHandle;
-      Wnd->Owner = OwnerWindow->Wnd;
+      Wnd->spwndOwner = OwnerWindow->Wnd;
       HasOwner = TRUE;
    }
    else
    {
       Window->hOwner = NULL;
-      Wnd->Owner = NULL;
+      Wnd->spwndOwner = NULL;
       HasOwner = FALSE;
    }
 
-   Wnd->UserData = 0;
+   Wnd->dwUserData = 0;
+
+   if (Wnd->pcls->CSF_flags & CSF_SERVERSIDEPROC)
+      Wnd->state |= WNDS_SERVERSIDEWINDOWPROC;
 
-   Wnd->IsSystem = Wnd->Class->System;
+ /* BugBoy Comments: Comment below say that System classes are always created
+    as UNICODE. In windows, creating a window with the ANSI version of CreateWindow
+    sets the window to ansi as verified by testing with IsUnicodeWindow API.
+
+    No where can I see in code or through testing does the window change back
+    to ANSI after being created as UNICODE in ROS. I didnt do more testing to
+    see what problems this would cause.*/
+
+   // Set WndProc from Class.
+   Wnd->lpfnWndProc  = Wnd->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 (bUnicodeWindow)
+      {
+         if (GETPFNCLIENTA(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
+            Wnd->lpfnWndProc = GETPFNCLIENTW(Wnd->pcls->fnid);  
+      }
+      else
+      {
+         if (GETPFNCLIENTW(Wnd->pcls->fnid) == Wnd->lpfnWndProc)
+            Wnd->lpfnWndProc = GETPFNCLIENTA(Wnd->pcls->fnid);
+      }
+    }
 
-   /* BugBoy Comments: Comment below say that System classes are always created as UNICODE.
-      In windows, creating a window with the ANSI version of CreateWindow sets the window
-      to ansi as verified by testing with IsUnicodeWindow API.
+   // If not an Unicode caller, set Ansi creator bit.
+   if (!bUnicodeWindow) Wnd->state |= WNDS_ANSICREATOR;
 
-      No where can I see in code or through testing does the window change back to ANSI
-      after being created as UNICODE in ROS. I didnt do more testing to see what problems this would cause.*/
-    // See NtUserDefSetText! We convert to Unicode all the time and never use Mix. (jt)
-   if (Wnd->Class->System)
+   // Clone Class Ansi/Unicode proc type.
+   if (Wnd->pcls->CSF_flags & CSF_ANSIPROC)
    {
-       /* NOTE: Always create a unicode window for system classes! */
-       Wnd->Unicode = TRUE;
-       Wnd->WndProc = Wnd->Class->WndProc;
-       Wnd->WndProcExtra = Wnd->Class->WndProcExtra;
+      Wnd->state |= WNDS_ANSIWINDOWPROC;
+      Wnd->Unicode = FALSE;
    }
    else
-   {
-       Wnd->Unicode = Wnd->Class->Unicode;
-       Wnd->WndProc = Wnd->Class->WndProc;
-       Wnd->CallProc = NULL;
+   { /*
+       It seems there can be both an Ansi creator and Unicode Class Window
+       WndProc, unless the following overriding conditions occur:
+     */
+      if ( !bUnicodeWindow &&
+          ( ClassAtom == gpsi->atomSysClass[ICLS_BUTTON]    ||
+            ClassAtom == gpsi->atomSysClass[ICLS_COMBOBOX]  ||
+            ClassAtom == gpsi->atomSysClass[ICLS_COMBOLBOX] ||
+            ClassAtom == gpsi->atomSysClass[ICLS_DIALOG]    ||
+            ClassAtom == gpsi->atomSysClass[ICLS_EDIT]      ||
+            ClassAtom == gpsi->atomSysClass[ICLS_IME]       ||
+            ClassAtom == gpsi->atomSysClass[ICLS_LISTBOX]   ||
+            ClassAtom == gpsi->atomSysClass[ICLS_MDICLIENT] ||
+            ClassAtom == gpsi->atomSysClass[ICLS_STATIC] ) )
+      { // Override Class and set the window Ansi WndProc.
+         Wnd->state |= WNDS_ANSIWINDOWPROC;
+         Wnd->Unicode = FALSE;
+      }
+      else
+      { // Set the window Unicode WndProc.
+         Wnd->state &= ~WNDS_ANSIWINDOWPROC;
+         Wnd->Unicode = TRUE;
+      }
    }
 
-   Window->OwnerThread = PsGetCurrentThread();
-   Window->FirstChild = NULL;
-   Window->LastChild = NULL;
-   Window->PrevSibling = NULL;
-   Window->NextSibling = NULL;
-   Wnd->ExtraDataSize = Wnd->Class->WndExtra;
+   Window->spwndChild = NULL;
+   Window->spwndPrev = NULL;
+   Window->spwndNext = NULL;
+
+   Wnd->spwndNext = NULL;
+   Wnd->spwndPrev = NULL;
+   Wnd->spwndChild = NULL;
+
+   Wnd->cbwndExtra = Wnd->pcls->cbwndExtra;
 
    InitializeListHead(&Wnd->PropListHead);
-   InitializeListHead(&Window->WndObjListHead);
 
-   if (NULL != WindowName->Buffer && WindowName->Length > 0)
+   if ( NULL != WindowName->Buffer && WindowName->Length > 0 )
    {
-      Wnd->WindowName.Buffer = DesktopHeapAlloc(Wnd->pdesktop,
+      Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk,
                                                 WindowName->Length + sizeof(UNICODE_NULL));
-      if (Wnd->WindowName.Buffer == NULL)
+      if (Wnd->strName.Buffer == NULL)
       {
           SetLastNtError(STATUS_INSUFFICIENT_RESOURCES);
-          RETURN( (HWND)0);
+          RETURN( (PWND)0);
       }
 
-      Wnd->WindowName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
+      Wnd->strName.Buffer[WindowName->Length / sizeof(WCHAR)] = L'\0';
       _SEH2_TRY
       {
-          RtlCopyMemory(Wnd->WindowName.Buffer,
+          RtlCopyMemory(Wnd->strName.Buffer,
                         WindowName->Buffer,
                         WindowName->Length);
-          Wnd->WindowName.Length = WindowName->Length;
+          Wnd->strName.Length = WindowName->Length;
       }
       _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
       {
           WindowName->Length = 0;
-          Wnd->WindowName.Buffer[0] = L'\0';
+          Wnd->strName.Buffer[0] = L'\0';
       }
       _SEH2_END;
    }
@@ -1820,7 +2006,7 @@ AllocErr:
       if (!(dwStyle & WS_POPUP))
       {
          dwStyle |= WS_CAPTION;
-         Window->Flags |= WINDOWOBJECT_NEED_SIZE;
+         Window->state |= WINDOWOBJECT_NEED_SIZE;
          DPRINT("4: Style is now %lx\n", dwStyle);
       }
    }
@@ -1841,24 +2027,38 @@ AllocErr:
    {
       if (hMenu)
          IntSetMenu(Window, hMenu, &MenuChanged);
-      else
+      else if (Wnd->pcls->lpszMenuName) // Take it from the parent.
       {
-          hMenu = Wnd->Class->hMenu;
+          UNICODE_STRING MenuName;
+          if (IS_INTRESOURCE(Wnd->pcls->lpszMenuName))
+          {
+             MenuName.Length = 0;
+             MenuName.MaximumLength = 0;
+             MenuName.Buffer = Wnd->pcls->lpszMenuName;
+          }
+          else
+          {
+             RtlInitUnicodeString( &MenuName, Wnd->pcls->lpszMenuName);
+          }
+          hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName);
           if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged);
       }
    }
-   else
-       Wnd->IDMenu = (UINT) hMenu;
+   else // Not a child
+      Wnd->IDMenu = (UINT) hMenu;
 
    /* Insert the window into the thread's window list. */
    InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry);
 
    /*  Handle "CS_CLASSDC", it is tested first. */
-   if ((Wnd->Class->Style & CS_CLASSDC) && !(Wnd->Class->Dce)) // One DCE per class to have CLASS.
-      Wnd->Class->Dce = DceAllocDCE(Window, DCE_CLASS_DC);
-   /* Allocate a DCE for this window. */
-   else if ( Wnd->Class->Style & CS_OWNDC)
-      Window->Dce = DceAllocDCE(Window, DCE_WINDOW_DC);
+   if ( (Wnd->pcls->style & CS_CLASSDC) && !(Wnd->pcls->pdce) )
+   {  /* One DCE per class to have CLASS. */
+      Wnd->pcls->pdce = DceAllocDCE( Window, DCE_CLASS_DC );
+   }
+   else if ( Wnd->pcls->style & CS_OWNDC)
+   {  /* Allocate a DCE for this window. */
+      DceAllocDCE(Window, DCE_WINDOW_DC);
+   }
 
    Pos.x = x;
    Pos.y = y;
@@ -1866,7 +2066,7 @@ AllocErr:
    Size.cy = nHeight;
 
    Wnd->ExStyle = dwExStyle;
-   Wnd->Style = dwStyle & ~WS_VISIBLE;
+   Wnd->style = dwStyle & ~WS_VISIBLE;
 
    /* call hook */
    Cs.lpCreateParams = lpParam;
@@ -1877,40 +2077,46 @@ AllocErr:
    Cs.cy = Size.cy;
    Cs.x = Pos.x;
    Cs.y = Pos.y;
-   Cs.style = Wnd->Style;
+   Cs.style = Wnd->style;
+//   Cs.lpszName = (LPCWSTR) WindowName->Buffer;
+//   Cs.lpszClass = (LPCWSTR) ClassName->Buffer;
    Cs.lpszName = (LPCWSTR) WindowName;
    Cs.lpszClass = (LPCWSTR) ClassName;
    Cs.dwExStyle = dwExStyle;
    CbtCreate.lpcs = &Cs;
    CbtCreate.hwndInsertAfter = HWND_TOP;
-   if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
+   if (ISITHOOKED(WH_CBT))
    {
-      /* FIXME - Delete window object and remove it from the thread windows list */
-      /* FIXME - delete allocated DCE */
-      DPRINT1("CBT-hook returned !0\n");
-      RETURN( (HWND) NULL);
+      if (co_HOOK_CallHooks(WH_CBT, HCBT_CREATEWND, (WPARAM) hWnd, (LPARAM) &CbtCreate))
+      {
+         /* FIXME - Delete window object and remove it from the thread windows list */
+         /* FIXME - delete allocated DCE */
+         DPRINT1("CBT-hook returned !0\n");
+         RETURN( (PWND) NULL);
+      }
    }
-
    x = Cs.x;
    y = Cs.y;
    nWidth = Cs.cx;
    nHeight = Cs.cy;
+// FIXME: Need to set the Z order in the window link list if the hook callback changed it!
+//   hwndInsertAfter = CbtCreate.hwndInsertAfter;
 
    /* default positioning for overlapped windows */
-   if(!(Wnd->Style & (WS_POPUP | WS_CHILD)))
+   if(!(Wnd->style & (WS_POPUP | WS_CHILD)))
    {
       RECTL rc, WorkArea;
       PRTL_USER_PROCESS_PARAMETERS ProcessParams;
       BOOL CalculatedDefPosSize = FALSE;
 
-      IntGetDesktopWorkArea(((PTHREADINFO)Window->OwnerThread->Tcb.Win32Thread)->Desktop, &WorkArea);
+      IntGetDesktopWorkArea(Window->pti->rpdesk, &WorkArea);
 
       rc = WorkArea;
       ProcessParams = PsGetCurrentProcess()->Peb->ProcessParameters;
 
       if(x == CW_USEDEFAULT || x == CW_USEDEFAULT16)
       {
-         CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, Window, &rc, TRUE);
+         CalculatedDefPosSize = IntCalcDefPosSize(ParentWindow, &rc, TRUE);
 
          if(ProcessParams->WindowFlags & STARTF_USEPOSITION)
          {
@@ -1954,7 +2160,7 @@ AllocErr:
       {
          if(!CalculatedDefPosSize)
          {
-            IntCalcDefPosSize(ParentWindow, Window, &rc, FALSE);
+            IntCalcDefPosSize(ParentWindow, &rc, FALSE);
          }
          if(ProcessParams->WindowFlags & STARTF_USESIZE)
          {
@@ -1991,16 +2197,16 @@ AllocErr:
    }
 
    /* Initialize the window dimensions. */
-   Wnd->WindowRect.left = Pos.x;
-   Wnd->WindowRect.top = Pos.y;
-   Wnd->WindowRect.right = Pos.x + Size.cx;
-   Wnd->WindowRect.bottom = Pos.y + Size.cy;
-   if (0 != (Wnd->Style & WS_CHILD) && ParentWindow)
+   Wnd->rcWindow.left = Pos.x;
+   Wnd->rcWindow.top = Pos.y;
+   Wnd->rcWindow.right = Pos.x + Size.cx;
+   Wnd->rcWindow.bottom = Pos.y + Size.cy;
+   if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
    {
-      RECTL_vOffsetRect(&(Wnd->WindowRect), ParentWindow->Wnd->ClientRect.left,
-                       ParentWindow->Wnd->ClientRect.top);
+      RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left,
+                       ParentWindow->Wnd->rcClient.top);
    }
-   Wnd->ClientRect = Wnd->WindowRect;
+   Wnd->rcClient = Wnd->rcWindow;
 
    /*
     * Get the size and position of the window.
@@ -2026,16 +2232,16 @@ AllocErr:
          Size.cy = 0;
    }
 
-   Wnd->WindowRect.left = Pos.x;
-   Wnd->WindowRect.top = Pos.y;
-   Wnd->WindowRect.right = Pos.x + Size.cx;
-   Wnd->WindowRect.bottom = Pos.y + Size.cy;
-   if (0 != (Wnd->Style & WS_CHILD) && ParentWindow)
+   Wnd->rcWindow.left = Pos.x;
+   Wnd->rcWindow.top = Pos.y;
+   Wnd->rcWindow.right = Pos.x + Size.cx;
+   Wnd->rcWindow.bottom = Pos.y + Size.cy;
+   if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
    {
-      RECTL_vOffsetRect(&(Wnd->WindowRect), ParentWindow->Wnd->ClientRect.left,
-                       ParentWindow->Wnd->ClientRect.top);
+      RECTL_vOffsetRect(&(Wnd->rcWindow), ParentWindow->Wnd->rcClient.left,
+                       ParentWindow->Wnd->rcClient.top);
    }
-   Wnd->ClientRect = Wnd->WindowRect;
+   Wnd->rcClient = Wnd->rcWindow;
 
    /* FIXME: Initialize the window menu. */
 
@@ -2053,23 +2259,23 @@ AllocErr:
    {
       /* FIXME: Cleanup. */
       DPRINT1("IntCreateWindowEx(): NCCREATE message failed. No cleanup performed!\n");
-      RETURN((HWND)0);
+      RETURN((PWND)0);
    }
 
    /* Calculate the non-client size. */
-   MaxPos.x = Window->Wnd->WindowRect.left;
-   MaxPos.y = Window->Wnd->WindowRect.top;
+   MaxPos.x = Window->Wnd->rcWindow.left;
+   MaxPos.y = Window->Wnd->rcWindow.top;
 
 
    DPRINT("IntCreateWindowEx(): About to get non-client size.\n");
    /* WinPosGetNonClientSize SENDS THE WM_NCCALCSIZE message */
    Result = co_WinPosGetNonClientSize(Window,
-                                      &Window->Wnd->WindowRect,
-                                      &Window->Wnd->ClientRect);
+                                      &Window->Wnd->rcWindow,
+                                      &Window->Wnd->rcClient);
 
-   RECTL_vOffsetRect(&Window->Wnd->WindowRect,
-                    MaxPos.x - Window->Wnd->WindowRect.left,
-                    MaxPos.y - Window->Wnd->WindowRect.top);
+   RECTL_vOffsetRect(&Window->Wnd->rcWindow,
+                    MaxPos.x - Window->Wnd->rcWindow.left,
+                    MaxPos.y - Window->Wnd->rcWindow.top);
 
 
    if (NULL != ParentWindow)
@@ -2079,7 +2285,13 @@ AllocErr:
       {
          PWINDOW_OBJECT PrevSibling;
 
-         PrevSibling = ParentWindow->LastChild;
+         PrevSibling = ParentWindow->spwndChild;
+
+         if(PrevSibling)
+         {
+            while (PrevSibling->spwndNext)
+               PrevSibling = PrevSibling->spwndNext;
+         }
 
          /* link window as bottom sibling */
          IntLinkWindow(Window, ParentWindow, PrevSibling /*prev sibling*/);
@@ -2091,11 +2303,11 @@ AllocErr:
          if (!(dwExStyle & WS_EX_TOPMOST))
          {
             InsertAfter = NULL;
-            Sibling = ParentWindow->FirstChild;
+            Sibling = ParentWindow->spwndChild;
             while (Sibling && (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
             {
                InsertAfter = Sibling;
-               Sibling = Sibling->NextSibling;
+               Sibling = Sibling->spwndNext;
             }
          }
          else
@@ -2104,7 +2316,6 @@ AllocErr:
          }
 
          IntLinkWindow(Window, ParentWindow, InsertAfter /* prev sibling */);
-
       }
    }
 
@@ -2117,50 +2328,42 @@ AllocErr:
       /* FIXME: Cleanup. */
       DPRINT1("IntCreateWindowEx(): send CREATE message failed. No cleanup performed!\n");
       IntUnlinkWindow(Window);
-      RETURN((HWND)0);
+      RETURN((PWND)0);
    }
-#if 0
-   Result = IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window, OBJID_WINDOW, 0);
 
-   if (Result == (LRESULT)-1)
-   {
-      /* FIXME: Cleanup. */
-      DPRINT1("IntCreateWindowEx(): event CREATE hook failed. No cleanup performed!\n");
-      IntUnlinkWindow(Window);
-      RETURN((HWND)0);
-   }
-#endif
+   IntNotifyWinEvent(EVENT_OBJECT_CREATE, Window->Wnd, OBJID_WINDOW, 0);
+
    /* Send move and size messages. */
-   if (!(Window->Flags & WINDOWOBJECT_NEED_SIZE))
+   if (!(Window->state & WINDOWOBJECT_NEED_SIZE))
    {
       LONG lParam;
 
       DPRINT("IntCreateWindow(): About to send WM_SIZE\n");
 
-      if ((Window->Wnd->ClientRect.right - Window->Wnd->ClientRect.left) < 0 ||
-            (Window->Wnd->ClientRect.bottom - Window->Wnd->ClientRect.top) < 0)
+      if ((Window->Wnd->rcClient.right - Window->Wnd->rcClient.left) < 0 ||
+            (Window->Wnd->rcClient.bottom - Window->Wnd->rcClient.top) < 0)
       {
          DPRINT("Sending bogus WM_SIZE\n");
       }
 
-      lParam = MAKE_LONG(Window->Wnd->ClientRect.right -
-                         Window->Wnd->ClientRect.left,
-                         Window->Wnd->ClientRect.bottom -
-                         Window->Wnd->ClientRect.top);
+      lParam = MAKE_LONG(Window->Wnd->rcClient.right -
+                         Window->Wnd->rcClient.left,
+                         Window->Wnd->rcClient.bottom -
+                         Window->Wnd->rcClient.top);
       co_IntSendMessage(Window->hSelf, WM_SIZE, SIZE_RESTORED,
                         lParam);
 
       DPRINT("IntCreateWindow(): About to send WM_MOVE\n");
 
-      if (0 != (Wnd->Style & WS_CHILD) && ParentWindow)
+      if (0 != (Wnd->style & WS_CHILD) && ParentWindow)
       {
-         lParam = MAKE_LONG(Wnd->ClientRect.left - ParentWindow->Wnd->ClientRect.left,
-                            Wnd->ClientRect.top - ParentWindow->Wnd->ClientRect.top);
+         lParam = MAKE_LONG(Wnd->rcClient.left - ParentWindow->Wnd->rcClient.left,
+                            Wnd->rcClient.top - ParentWindow->Wnd->rcClient.top);
       }
       else
       {
-         lParam = MAKE_LONG(Wnd->ClientRect.left,
-                            Wnd->ClientRect.top);
+         lParam = MAKE_LONG(Wnd->rcClient.left,
+                            Wnd->rcClient.top);
       }
 
       co_IntSendMessage(Window->hSelf, WM_MOVE, 0, lParam);
@@ -2170,17 +2373,17 @@ AllocErr:
    }
 
    /* Show or maybe minimize or maximize the window. */
-   if (Wnd->Style & (WS_MINIMIZE | WS_MAXIMIZE))
+   if (Wnd->style & (WS_MINIMIZE | WS_MAXIMIZE))
    {
       RECTL NewPos;
       UINT16 SwFlag;
 
-      SwFlag = (Wnd->Style & WS_MINIMIZE) ? SW_MINIMIZE :
+      SwFlag = (Wnd->style & WS_MINIMIZE) ? SW_MINIMIZE :
                SW_MAXIMIZE;
 
       co_WinPosMinMaximize(Window, SwFlag, &NewPos);
 
-      SwFlag = ((Wnd->Style & WS_CHILD) || UserGetActiveWindow()) ?
+      SwFlag = ((Wnd->style & WS_CHILD) || UserGetActiveWindow()) ?
                 SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED :
                 SWP_NOZORDER | SWP_FRAMECHANGED;
 
@@ -2191,7 +2394,7 @@ AllocErr:
    }
 
    /* Notify the parent window of a new child. */
-   if ((Wnd->Style & WS_CHILD) &&
+   if ((Wnd->style & WS_CHILD) &&
        (!(Wnd->ExStyle & WS_EX_NOPARENTNOTIFY)) && ParentWindow)
    {
       DPRINT("IntCreateWindow(): About to notify parent\n");
@@ -2212,20 +2415,20 @@ AllocErr:
    }
 
    /* Initialize and show the window's scrollbars */
-   if (Wnd->Style & WS_VSCROLL)
+   if (Wnd->style & WS_VSCROLL)
    {
       co_UserShowScrollBar(Window, SB_VERT, TRUE);
    }
-   if (Wnd->Style & WS_HSCROLL)
+   if (Wnd->style & WS_HSCROLL)
    {
       co_UserShowScrollBar(Window, SB_HORZ, TRUE);
    }
 
    if (dwStyle & WS_VISIBLE)
    {
-      if (Wnd->Style & WS_MAXIMIZE)
+      if (Wnd->style & WS_MAXIMIZE)
          dwShowMode = SW_SHOW;
-      else if (Wnd->Style & WS_MINIMIZE)
+      else if (Wnd->style & WS_MINIMIZE)
          dwShowMode = SW_SHOWMINIMIZED;
 
       DPRINT("IntCreateWindow(): About to show window\n");
@@ -2239,14 +2442,14 @@ AllocErr:
       }
    }
 
-   /* BugBoy Comments: if the window being created is a edit control, ATOM 0xC007,
+   /* 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 
       Dont understand why it does this. */
-   if (ClassAtom == 0XC007)
+   if (ClassAtom == gpsi->atomSysClass[ICLS_EDIT])
    {
-      PCALLPROC CallProc;
-      //CallProc = CreateCallProc(NULL, Wnd->WndProc, bUnicodeWindow, Wnd->ti->ppi);
-      CallProc = CreateCallProc(NULL, Wnd->WndProc, Wnd->Unicode , Wnd->ti->ppi);
+      PCALLPROCDATA CallProc;
+      //CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, bUnicodeWindow, Wnd->ti->ppi);
+      CallProc = CreateCallProc(NULL, Wnd->lpfnWndProc, Wnd->Unicode , Wnd->head.pti->ppi);
 
       if (!CallProc)
       {
@@ -2255,19 +2458,18 @@ AllocErr:
       }
       else
       {
-         UserAddCallProcToClass(Wnd->Class, CallProc);
-         Wnd->CallProc = CallProc;
-         Wnd->IsSystem = FALSE;
+         UserAddCallProcToClass(Wnd->pcls, CallProc);
       }
    }
 
    DPRINT("IntCreateWindow(): = %X\n", hWnd);
    DPRINT("WindowObject->SystemMenu = 0x%x\n", Window->SystemMenu);
-   RETURN(hWnd);
+   RETURN( Wnd);
 
 CLEANUP:
    if (!_ret_ && Window && Window->Wnd && ti)
-       UserFreeWindowInfo(ti, Window);
+      co_UserDestroyWindow(Window);
+//      UserFreeWindowInfo(ti, Window);
    if (Window)
    {
       UserDerefObjectCo(Window);
@@ -2306,7 +2508,8 @@ NtUserCreateWindowEx(DWORD dwExStyle,
    NTSTATUS Status;
    UNICODE_STRING WindowName;
    UNICODE_STRING ClassName;
-   HWND NewWindow;
+   HWND NewWindow = NULL;
+   PWND pNewWindow;
    DECLARE_RETURN(HWND);
 
    DPRINT("Enter NtUserCreateWindowEx(): (%d,%d-%d,%d)\n", x, y, nWidth, nHeight);
@@ -2353,8 +2556,22 @@ NtUserCreateWindowEx(DWORD dwExStyle,
       RtlInitUnicodeString(&WindowName, NULL);
    }
 
-   NewWindow = co_IntCreateWindowEx(dwExStyle, &ClassName, &WindowName, dwStyle, x, y, nWidth, nHeight,
-                                    hWndParent, hMenu, hInstance, lpParam, dwShowMode, bUnicodeWindow);
+   pNewWindow = co_IntCreateWindowEx( dwExStyle,
+                                     &ClassName,
+                                     &WindowName,
+                                      dwStyle,
+                                      x,
+                                      y,
+                                      nWidth,
+                                      nHeight,
+                                      hWndParent,
+                                      hMenu,
+                                      hInstance,
+                                      lpParam,
+                                      dwShowMode,
+                                      bUnicodeWindow);
+
+   if (pNewWindow) NewWindow = UserHMGetHandle(pNewWindow);
 
    if (WindowName.Buffer)
    {
@@ -2395,21 +2612,33 @@ NtUserDeferWindowPos(HDWP WinPosInfo,
 BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
 {
    BOOLEAN isChild;
-   PWINDOW Wnd;
+   PWND Wnd;
+   HWND hWnd;
 
    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!
 
+   DPRINT("co_UserDestroyWindow \n");
+
    /* Check for owner thread */
-   if ((Window->OwnerThread != PsGetCurrentThread()))
+   if ( (Window->pti->pEThread != PsGetCurrentThread()) ||
+        Wnd->head.pti != PsGetCurrentThreadWin32Thread() )
    {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return FALSE;
    }
 
+   /* Call hooks */
+   if (ISITHOOKED(WH_CBT))
+   {
+      if (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hWnd, 0)) return FALSE;
+   }
+
    /* Look whether the focus is within the tree of windows we will
     * be destroying.
     */
@@ -2421,25 +2650,17 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
       }
    }
 
-   if (Window->MessageQueue->ActiveWindow == Window->hSelf)
-      Window->MessageQueue->ActiveWindow = NULL;
-   if (Window->MessageQueue->FocusWindow == Window->hSelf)
-      Window->MessageQueue->FocusWindow = NULL;
-   if (Window->MessageQueue->CaptureWindow == Window->hSelf)
-      Window->MessageQueue->CaptureWindow = NULL;
-
-   IntDereferenceMessageQueue(Window->MessageQueue);
-   /* Call hooks */
-#if 0 /* FIXME */
+   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 (co_HOOK_CallHooks(WH_CBT, HCBT_DESTROYWND, (WPARAM) hwnd, 0, TRUE))
-   {
-      return FALSE;
-   }
-#endif
+   IntDereferenceMessageQueue(Window->pti->MessageQueue);
 
    IntEngWindowChanged(Window, WOC_DELETE);
-   isChild = (0 != (Wnd->Style & WS_CHILD));
+   isChild = (0 != (Wnd->style & WS_CHILD));
 
 #if 0 /* FIXME */
 
@@ -2502,7 +2723,7 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
                if (Child->hOwner != NULL)
                {
                   Child->hOwner = NULL;
-                  Child->Wnd->Owner = NULL;
+                  Child->Wnd->spwndOwner = NULL;
                }
 
             }
@@ -2527,8 +2748,6 @@ BOOLEAN FASTCALL co_UserDestroyWindow(PWINDOW_OBJECT Window)
 }
 
 
-
-
 /*
  * @implemented
  */
@@ -2647,8 +2866,8 @@ 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((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->Wnd->WindowName), TRUE)) &&
-               (!ClassAtom || Child->Wnd->Class->Atom == ClassAtom))
+         if((!CheckWindowName || !RtlCompareUnicodeString(WindowName, &(Child->Wnd->strName), TRUE)) &&
+               (!ClassAtom || Child->Wnd->pcls->atomClassName == ClassAtom))
          {
             Ret = Child->hSelf;
             break;
@@ -2765,12 +2984,10 @@ NtUserFindWindowEx(HWND hwndParent,
 
    if(hwndParent == NULL)
       hwndParent = Desktop;
-   /* FIXME
    else if(hwndParent == HWND_MESSAGE)
    {
      hwndParent = IntGetMessageWindow();
    }
-   */
 
    if(!(Parent = UserGetWindowObject(hwndParent)))
    {
@@ -2821,9 +3038,9 @@ NtUserFindWindowEx(HWND hwndParent,
                    The user mode version however calls GetWindowText() which will
                    send WM_GETTEXT messages to windows belonging to its processes */
                 WindowMatches = !CheckWindowName || !RtlCompareUnicodeString(
-                                   &WindowName, &TopLevelWindow->Wnd->WindowName, TRUE);
+                                   &WindowName, &TopLevelWindow->Wnd->strName, TRUE);
                 ClassMatches = (ClassAtom == (RTL_ATOM)0) ||
-                               ClassAtom == TopLevelWindow->Wnd->Class->Atom;
+                               ClassAtom == TopLevelWindow->Wnd->pcls->atomClassName;
 
                 if (WindowMatches && ClassMatches)
                 {
@@ -2906,7 +3123,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
    {
       case GA_PARENT:
          {
-            WndAncestor = Wnd->Parent;
+            WndAncestor = Wnd->spwndParent;
             break;
          }
 
@@ -2917,7 +3134,7 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
 
             for(;;)
             {
-               if(!(Parent = WndAncestor->Parent))
+               if(!(Parent = WndAncestor->spwndParent))
                {
                   break;
                }
@@ -2964,8 +3181,6 @@ PWINDOW_OBJECT FASTCALL UserGetAncestor(PWINDOW_OBJECT Wnd, UINT Type)
    return WndAncestor;
 }
 
-
-
 /*
  * @implemented
  */
@@ -3046,7 +3261,7 @@ NtUserGetInternalWindowPos( HWND hWnd,
                             LPPOINT ptIcon)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
    DWORD Ret = 0;
    BOOL Hit = FALSE;
    WINDOWPLACEMENT wndpl;
@@ -3194,8 +3409,6 @@ co_UserSetParent(HWND hWndChild, HWND hWndNewParent)
    return( hWndOldParent);
 }
 
-
-
 /*
  * NtUserSetParent
  *
@@ -3221,6 +3434,18 @@ NtUserSetParent(HWND hWndChild, HWND hWndNewParent)
    DPRINT("Enter NtUserSetParent\n");
    UserEnterExclusive();
 
+   /*
+      Check Parent first from user space, set it here.
+    */
+   if (!hWndNewParent)
+   {
+      hWndNewParent = IntGetDesktopWindow();
+   }
+   else if (hWndNewParent == HWND_MESSAGE)
+   {
+      hWndNewParent = IntGetMessageWindow();
+   }
+
    RETURN( co_UserSetParent(hWndChild, hWndNewParent));
 
 CLEANUP:
@@ -3229,8 +3454,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-
-
 /*
  * UserGetShellWindow
  *
@@ -3239,7 +3462,7 @@ CLEANUP:
  * Status
  *    @implemented
  */
-HWND FASTCALL UserGetShellWindow()
+HWND FASTCALL UserGetShellWindow(VOID)
 {
    PWINSTATION_OBJECT WinStaObject;
    HWND Ret;
@@ -3278,7 +3501,7 @@ NtUserSetShellWindowEx(HWND hwndShell, HWND hwndListView)
    DECLARE_RETURN(BOOL);
    USER_REFERENCE_ENTRY Ref;
    NTSTATUS Status;
-   PW32THREADINFO ti;
+   PTHREADINFO ti;
 
    DPRINT("Enter NtUserSetShellWindowEx\n");
    UserEnterExclusive();
@@ -3453,9 +3676,6 @@ CLEANUP:
    END_CLEANUP;
 }
 
-
-
-
 HWND FASTCALL
 UserGetWindow(HWND hWnd, UINT Relationship)
 {
@@ -3468,29 +3688,37 @@ UserGetWindow(HWND hWnd, UINT Relationship)
    switch (Relationship)
    {
       case GW_HWNDFIRST:
-         if((Parent = Window->Parent))
+         if((Parent = Window->spwndParent))
          {
-            if (Parent->FirstChild)
-               hWndResult = Parent->FirstChild->hSelf;
+            if (Parent->spwndChild)
+               hWndResult = Parent->spwndChild->hSelf;
          }
          break;
 
       case GW_HWNDLAST:
-         if((Parent = Window->Parent))
+         if((Parent = Window->spwndParent))
          {
-            if (Parent->LastChild)
-               hWndResult = Parent->LastChild->hSelf;
+            if (Parent->spwndChild)
+            {
+               Window = Parent->spwndChild;
+               if(Window)
+               {
+                  while(Window->spwndNext)
+                     Window = Window->spwndNext;
+               }
+               hWndResult = Window->hSelf;
+            }
          }
          break;
 
       case GW_HWNDNEXT:
-         if (Window->NextSibling)
-            hWndResult = Window->NextSibling->hSelf;
+         if (Window->spwndNext)
+            hWndResult = Window->spwndNext->hSelf;
          break;
 
       case GW_HWNDPREV:
-         if (Window->PrevSibling)
-            hWndResult = Window->PrevSibling->hSelf;
+         if (Window->spwndPrev)
+            hWndResult = Window->spwndPrev->hSelf;
          break;
 
       case GW_OWNER:
@@ -3500,45 +3728,14 @@ UserGetWindow(HWND hWnd, UINT Relationship)
          }
          break;
       case GW_CHILD:
-         if (Window->FirstChild)
-            hWndResult = Window->FirstChild->hSelf;
+         if (Window->spwndChild)
+            hWndResult = Window->spwndChild->hSelf;
          break;
    }
 
    return hWndResult;
 }
 
-
-
-/*
- * NtUserGetWindow
- *
- * The NtUserGetWindow function retrieves a handle to a window that has the
- * specified relationship (Z order or owner) to the specified window.
- *
- * Status
- *    @implemented
- */
-
-HWND APIENTRY
-NtUserGetWindow(HWND hWnd, UINT Relationship)
-{
-   DECLARE_RETURN(HWND);
-
-   DPRINT("Enter NtUserGetWindow\n");
-   UserEnterShared();
-
-   RETURN(UserGetWindow(hWnd, Relationship));
-
-CLEANUP:
-   DPRINT("Leave NtUserGetWindow, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-
-
-
 /*
  * NtUserGetWindowLong
  *
@@ -3554,7 +3751,7 @@ LONG FASTCALL
 UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
 {
    PWINDOW_OBJECT Window, Parent;
-   PWINDOW Wnd;
+   PWND Wnd;
    LONG Result = 0;
 
    DPRINT("NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
@@ -3570,7 +3767,7 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
     * WndProc is only available to the owner process
     */
    if (GWL_WNDPROC == Index
-         && Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
+         && Window->pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
    {
       SetLastWin32Error(ERROR_ACCESS_DENIED);
       return 0;
@@ -3578,7 +3775,7 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
 
    if ((INT)Index >= 0)
    {
-      if ((Index + sizeof(LONG)) > Window->Wnd->ExtraDataSize)
+      if ((Index + sizeof(LONG)) > Window->Wnd->cbwndExtra)
       {
          SetLastWin32Error(ERROR_INVALID_PARAMETER);
          return 0;
@@ -3594,20 +3791,19 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
             break;
 
          case GWL_STYLE:
-            Result = Wnd->Style;
+            Result = Wnd->style;
             break;
 
          case GWL_WNDPROC:
-            Result = (LONG)IntGetWindowProc(Window,
-                                            Ansi);
+            Result = (LONG)IntGetWindowProc(Wnd, Ansi);
             break;
 
          case GWL_HINSTANCE:
-            Result = (LONG) Wnd->Instance;
+            Result = (LONG) Wnd->hModule;
             break;
 
          case GWL_HWNDPARENT:
-            Parent = Window->Parent;
+            Parent = Window->spwndParent;
             if(Parent)
             {
                if (Parent && Parent->hSelf == IntGetDesktopWindow())
@@ -3622,7 +3818,7 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
             break;
 
          case GWL_USERDATA:
-            Result = Wnd->UserData;
+            Result = Wnd->dwUserData;
             break;
 
          default:
@@ -3636,139 +3832,11 @@ UserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
    return Result;
 }
 
-
-
-
-/*
- * NtUserGetWindowLong
- *
- * The NtUserGetWindowLong function retrieves information about the specified
- * window. The function also retrieves the 32-bit (long) value at the
- * specified offset into the extra window memory.
- *
- * Status
- *    @implemented
- */
-
-LONG APIENTRY
-NtUserGetWindowLong(HWND hWnd, DWORD Index, BOOL Ansi)
-{
-   DECLARE_RETURN(LONG);
-
-   DPRINT("Enter NtUserGetWindowLong(%x,%d,%d)\n", hWnd, (INT)Index, Ansi);
-   UserEnterExclusive();
-
-   RETURN(UserGetWindowLong(hWnd, Index, Ansi));
-
-CLEANUP:
-   DPRINT("Leave NtUserGetWindowLong, ret=%i\n",_ret_);
-   UserLeave();
-   END_CLEANUP;
-}
-
-static WNDPROC
-IntSetWindowProc(PWINDOW_OBJECT Window,
-                 WNDPROC NewWndProc,
-                 BOOL Ansi)
-{
-    WNDPROC Ret;
-    PCALLPROC CallProc;
-    PWINDOW Wnd = Window->Wnd;
-
-    /* resolve any callproc handle if possible */
-    if (IsCallProcHandle(NewWndProc))
-    {
-        WNDPROC_INFO wpInfo;
-
-        if (UserGetCallProcInfo((HANDLE)NewWndProc,
-                                &wpInfo))
-        {
-            NewWndProc = wpInfo.WindowProc;
-            /* FIXME - what if wpInfo.IsUnicode doesn't match Ansi? */
-        }
-    }
-
-    /* attempt to get the previous window proc */
-    if (Wnd->IsSystem)
-    {
-        Ret = (Ansi ? Wnd->WndProcExtra : Wnd->WndProc);
-    }
-    else
-    {
-        if (!Ansi == Wnd->Unicode)
-        {
-            Ret = Wnd->WndProc;
-        }
-        else
-        {
-            CallProc = UserFindCallProc(Wnd->Class,
-                                        Wnd->WndProc,
-                                        Wnd->Unicode);
-            if (CallProc == NULL)
-            {
-                CallProc = CreateCallProc(NULL,
-                                          Wnd->WndProc,
-                                          Wnd->Unicode,
-                                          Wnd->ti->ppi);
-                if (CallProc == NULL)
-                {
-                    SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
-                    return NULL;
-                }
-
-                UserAddCallProcToClass(Wnd->Class,
-                                       CallProc);
-            }
-            /* BugBoy Comments: Added this if else, see below comments */
-            if (!Wnd->CallProc)
-            {
-               Ret = Wnd->WndProc;
-            }
-            else
-            {
-                Ret = GetCallProcHandle(Wnd->CallProc);
-            }
-
-            Wnd->CallProc = CallProc;
-
-            /* BugBoy Comments: Above sets the current CallProc for the
-               window and below we set the Ret value to it.
-               SetWindowLong for WNDPROC should return the previous proc
-            Ret = GetCallProcHandle(Wnd->CallProc); */
-        }
-    }
-
-    if (Wnd->Class->System)
-    {
-        /* check if the new procedure matches with the one in the
-           window class. If so, we need to restore both procedures! */
-        Wnd->IsSystem = (NewWndProc == Wnd->Class->WndProc ||
-                         NewWndProc == Wnd->Class->WndProcExtra);
-
-        if (Wnd->IsSystem)
-        {
-            Wnd->WndProc = Wnd->Class->WndProc;
-            Wnd->WndProcExtra = Wnd->Class->WndProcExtra;
-            Wnd->Unicode = !Ansi;
-            return Ret;
-        }
-    }
-
-    ASSERT(!Wnd->IsSystem);
-
-    /* update the window procedure */
-    Wnd->WndProc = NewWndProc;
-    Wnd->Unicode = !Ansi;
-
-    return Ret;
-}
-
-
 LONG FASTCALL
 co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 {
    PWINDOW_OBJECT Window, Parent;
-   PWINDOW Wnd;
+   PWND Wnd;
    PWINSTATION_OBJECT WindowStation;
    LONG OldValue;
    STYLESTRUCT Style;
@@ -3790,12 +3858,22 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
 
    if ((INT)Index >= 0)
    {
-      if ((Index + sizeof(LONG)) > Wnd->ExtraDataSize)
+      if ((Index + sizeof(LONG)) > Wnd->cbwndExtra)
       {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         SetLastWin32Error(ERROR_INVALID_INDEX);
          return( 0);
       }
+
       OldValue = *((LONG *)((PCHAR)(Wnd + 1) + Index));
+/*
+      if ( Index == DWLP_DLGPROC && Wnd->state & WNDS_DIALOGWINDOW)
+      {
+         OldValue = (LONG)IntSetWindowProc( Wnd,
+                                           (WNDPROC)NewValue,
+                                            Ansi);
+         if (!OldValue) return 0;
+      }
+*/
       *((LONG *)((PCHAR)(Wnd + 1) + Index)) = NewValue;
    }
    else
@@ -3810,7 +3888,7 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             /*
              * Remove extended window style bit WS_EX_TOPMOST for shell windows.
              */
-            WindowStation = ((PTHREADINFO)Window->OwnerThread->Tcb.Win32Thread)->Desktop->WindowStation;
+            WindowStation = Window->pti->rpdesk->rpwinstaParent;
             if(WindowStation)
             {
                if (hWnd == WindowStation->ShellWindow || hWnd == WindowStation->ShellListView)
@@ -3823,30 +3901,35 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             break;
 
          case GWL_STYLE:
-            OldValue = (LONG) Wnd->Style;
+            OldValue = (LONG) Wnd->style;
             Style.styleOld = OldValue;
             Style.styleNew = NewValue;
             co_IntSendMessage(hWnd, WM_STYLECHANGING, GWL_STYLE, (LPARAM) &Style);
-            Wnd->Style = (DWORD)Style.styleNew;
+            Wnd->style = (DWORD)Style.styleNew;
             co_IntSendMessage(hWnd, WM_STYLECHANGED, GWL_STYLE, (LPARAM) &Style);
             break;
 
          case GWL_WNDPROC:
          {
-            /* FIXME: should check if window belongs to current process */
-            OldValue = (LONG)IntSetWindowProc(Window,
+            if ( Wnd->head.pti->ppi != PsGetCurrentProcessWin32Process() ||
+                 Wnd->fnid & FNID_FREED)
+            {
+               SetLastWin32Error(ERROR_ACCESS_DENIED);
+               return( 0);
+            }
+            OldValue = (LONG)IntSetWindowProc(Wnd,
                                               (WNDPROC)NewValue,
                                               Ansi);
             break;
          }
 
          case GWL_HINSTANCE:
-            OldValue = (LONG) Wnd->Instance;
-            Wnd->Instance = (HINSTANCE) NewValue;
+            OldValue = (LONG) Wnd->hModule;
+            Wnd->hModule = (HINSTANCE) NewValue;
             break;
 
          case GWL_HWNDPARENT:
-            Parent = Window->Parent;
+            Parent = Window->spwndParent;
             if (Parent && (Parent->hSelf == IntGetDesktopWindow()))
                OldValue = (LONG) IntSetOwner(Window->hSelf, (HWND) NewValue);
             else
@@ -3859,13 +3942,13 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
             break;
 
          case GWL_USERDATA:
-            OldValue = Wnd->UserData;
-            Wnd->UserData = NewValue;
+            OldValue = Wnd->dwUserData;
+            Wnd->dwUserData = NewValue;
             break;
 
          default:
             DPRINT1("NtUserSetWindowLong(): Unsupported index %d\n", Index);
-            SetLastWin32Error(ERROR_INVALID_PARAMETER);
+            SetLastWin32Error(ERROR_INVALID_INDEX);
             OldValue = 0;
             break;
       }
@@ -3874,8 +3957,6 @@ co_UserSetWindowLong(HWND hWnd, DWORD Index, LONG NewValue, BOOL Ansi)
    return( OldValue);
 }
 
-
-
 /*
  * NtUserSetWindowLong
  *
@@ -3941,7 +4022,7 @@ NtUserSetWindowWord(HWND hWnd, INT Index, WORD NewValue)
          }
    }
 
-   if (Index > Window->Wnd->ExtraDataSize - sizeof(WORD))
+   if (Index > Window->Wnd->cbwndExtra - sizeof(WORD))
    {
       SetLastWin32Error(ERROR_INVALID_PARAMETER);
       RETURN( 0);
@@ -3966,7 +4047,7 @@ NtUserGetWindowPlacement(HWND hWnd,
                          WINDOWPLACEMENT *lpwndpl)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
    POINT Size;
    WINDOWPLACEMENT Safepl;
    NTSTATUS Status;
@@ -3993,29 +4074,29 @@ NtUserGetWindowPlacement(HWND hWnd,
    }
 
    Safepl.flags = 0;
-   if (0 == (Wnd->Style & WS_VISIBLE))
+   if (0 == (Wnd->style & WS_VISIBLE))
    {
       Safepl.showCmd = SW_HIDE;
    }
-   else if ((0 != (Window->Flags & WINDOWOBJECT_RESTOREMAX) ||
-            0 != (Wnd->Style & WS_MAXIMIZE)) &&
-            0 == (Wnd->Style & WS_MINIMIZE))
+   else if ((0 != (Window->state & WINDOWOBJECT_RESTOREMAX) ||
+            0 != (Wnd->style & WS_MAXIMIZE)) &&
+            0 == (Wnd->style & WS_MINIMIZE))
    {
       Safepl.showCmd = SW_SHOWMAXIMIZED;
    }
-   else if (0 != (Wnd->Style & WS_MINIMIZE))
+   else if (0 != (Wnd->style & WS_MINIMIZE))
    {
       Safepl.showCmd = SW_SHOWMINIMIZED;
    }
-   else if (0 != (Wnd->Style & WS_VISIBLE))
+   else if (0 != (Wnd->style & WS_VISIBLE))
    {
       Safepl.showCmd = SW_SHOWNORMAL;
    }
 
-   Size.x = Wnd->WindowRect.left;
-   Size.y = Wnd->WindowRect.top;
+   Size.x = Wnd->rcWindow.left;
+   Size.y = Wnd->rcWindow.top;
    WinPosInitInternalPos(Window, &Size,
-                         &Wnd->WindowRect);
+                         &Wnd->rcWindow);
 
    Safepl.rcNormalPosition = Wnd->InternalPos.NormalRect;
    Safepl.ptMinPosition = Wnd->InternalPos.IconPos;
@@ -4087,17 +4168,20 @@ DWORD APIENTRY
 NtUserQueryWindow(HWND hWnd, DWORD Index)
 {
    PWINDOW_OBJECT Window;
+   PWND pWnd;
    DWORD Result;
    DECLARE_RETURN(UINT);
 
    DPRINT("Enter NtUserQueryWindow\n");
    UserEnterShared();
 
-   if (!(Window = UserGetWindowObject(hWnd)))
+   if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
    {
       RETURN( 0);
    }
 
+   pWnd = Window->Wnd;
+
    switch(Index)
    {
       case QUERY_WINDOW_UNIQUE_PROCESS_ID:
@@ -4117,9 +4201,12 @@ NtUserQueryWindow(HWND hWnd, DWORD Index)
          break;
 
       case QUERY_WINDOW_ISHUNG:
-         Result = (DWORD)MsqIsHung(Window->MessageQueue);
+         Result = (DWORD)MsqIsHung(Window->pti->MessageQueue);
          break;
 
+      case QUERY_WINDOW_REAL_ID:
+         Result = (DWORD)pWnd->head.pti->pEThread->Cid.UniqueProcess;
+
       default:
          Result = (DWORD)NULL;
          break;
@@ -4297,7 +4384,7 @@ NtUserSetWindowFNID(HWND hWnd,
                     WORD fnID)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
    DECLARE_RETURN(BOOL);
 
    DPRINT("Enter NtUserSetWindowFNID\n");
@@ -4309,14 +4396,14 @@ NtUserSetWindowFNID(HWND hWnd,
    }
    Wnd = Window->Wnd;
 
-   if (Wnd->Class)
+   if (Wnd->pcls)
    {  // From user land we only set these.
       if ((fnID != FNID_DESTROY) || ((fnID < FNID_BUTTON) && (fnID > FNID_IME)) )
       {
          RETURN( FALSE);
       }
       else
-         Wnd->Class->fnID |= fnID;
+         Wnd->pcls->fnid |= fnID;
    }
    RETURN( TRUE);
 
@@ -4335,7 +4422,7 @@ NtUserSetWindowPlacement(HWND hWnd,
                          WINDOWPLACEMENT *lpwndpl)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
    WINDOWPLACEMENT Safepl;
    NTSTATUS Status;
    DECLARE_RETURN(BOOL);
@@ -4363,7 +4450,7 @@ NtUserSetWindowPlacement(HWND hWnd,
 
    UserRefObjectCo(Window, &Ref);
 
-   if ((Wnd->Style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
+   if ((Wnd->style & (WS_MAXIMIZE | WS_MINIMIZE)) == 0)
    {
       co_WinPosSetWindowPos(Window, NULL,
                             Safepl.rcNormalPosition.left, Safepl.rcNormalPosition.top,
@@ -4451,7 +4538,7 @@ IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
    INT Ret;
    HRGN VisRgn;
    ROSRGNDATA *pRgn;
-   PWINDOW Wnd;
+   PWND Wnd;
 
    if(!Window)
    {
@@ -4465,23 +4552,23 @@ IntGetWindowRgn(PWINDOW_OBJECT Window, HRGN hRgn)
    Wnd = Window->Wnd;
 
    /* Create a new window region using the window rectangle */
-   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->WindowRect);
-   NtGdiOffsetRgn(VisRgn, -Window->Wnd->WindowRect.left, -Window->Wnd->WindowRect.top);
+   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->WindowRegion && !(Wnd->Style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+   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 = REGION_LockRgn(hRgn)))
+   if((pRgn = RGNOBJAPI_Lock(hRgn, NULL)))
    {
       Ret = pRgn->rdh.iType;
-      REGION_UnlockRgn(pRgn);
+      RGNOBJAPI_Unlock(pRgn);
    }
    else
       Ret = ERROR;
 
-   GreDeleteObject(VisRgn);
+   REGION_FreeRgnByHandle(VisRgn);
 
    return Ret;
 }
@@ -4492,7 +4579,7 @@ IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
    INT Ret;
    HRGN VisRgn;
    ROSRGNDATA *pRgn;
-   PWINDOW Wnd;
+   PWND Wnd;
 
    if(!Window)
    {
@@ -4506,22 +4593,22 @@ IntGetWindowRgnBox(PWINDOW_OBJECT Window, RECTL *Rect)
    Wnd = Window->Wnd;
 
    /* Create a new window region using the window rectangle */
-   VisRgn = UnsafeIntCreateRectRgnIndirect(&Window->Wnd->WindowRect);
-   NtGdiOffsetRgn(VisRgn, -Window->Wnd->WindowRect.left, -Window->Wnd->WindowRect.top);
+   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->WindowRegion && !(Wnd->Style & WS_MINIMIZE))
-      NtGdiCombineRgn(VisRgn, VisRgn, Window->WindowRegion, RGN_AND);
+   if(Window->hrgnClip && !(Wnd->style & WS_MINIMIZE))
+      NtGdiCombineRgn(VisRgn, VisRgn, Window->hrgnClip, RGN_AND);
 
-   if((pRgn = REGION_LockRgn(VisRgn)))
+   if((pRgn = RGNOBJAPI_Lock(VisRgn, NULL)))
    {
       Ret = pRgn->rdh.iType;
       *Rect = pRgn->rdh.rcBound;
-      REGION_UnlockRgn(pRgn);
+      RGNOBJAPI_Unlock(pRgn);
    }
    else
       Ret = ERROR;
 
-   GreDeleteObject(VisRgn);
+   REGION_FreeRgnByHandle(VisRgn);
 
    return Ret;
 }
@@ -4536,6 +4623,7 @@ NtUserSetWindowRgn(
    HRGN hRgn,
    BOOL bRedraw)
 {
+   HRGN hrgnCopy;
    PWINDOW_OBJECT Window;
    DECLARE_RETURN(INT);
 
@@ -4547,15 +4635,25 @@ NtUserSetWindowRgn(
       RETURN( 0);
    }
 
-   /* FIXME - Verify if hRgn is a valid handle!!!!
-              Propably make this operation thread-safe, but maybe it's not necessary */
+   if (hRgn) // The region will be deleted in user32.
+   {
+      if (GDIOBJ_ValidateHandle(hRgn, GDI_OBJECT_TYPE_REGION))
+      {
+         hrgnCopy = IntSysCreateRectRgn(0, 0, 0, 0);
+         NtGdiCombineRgn(hrgnCopy, hRgn, 0, RGN_COPY);
+      }
+      else
+         RETURN( 0);
+   }
+   else
+      hrgnCopy = (HRGN) 1;
 
-   if(Window->WindowRegion)
+   if (Window->hrgnClip)
    {
       /* Delete no longer needed region handle */
-      GreDeleteObject(Window->WindowRegion);
+      GreDeleteObject(Window->hrgnClip);
    }
-   Window->WindowRegion = hRgn;
+   Window->hrgnClip = hrgnCopy;
 
    /* FIXME - send WM_WINDOWPOSCHANGING and WM_WINDOWPOSCHANGED messages to the window */
 
@@ -4637,13 +4735,24 @@ NtUserUpdateLayeredWindow(
    POINT *pptSrc,
    COLORREF crKey,
    BLENDFUNCTION *pblend,
-   DWORD dwFlags)
+   DWORD dwFlags,
+   RECT *prcDirty)
 {
    UNIMPLEMENTED
 
    return 0;
 }
 
+/*
+ *    @unimplemented
+ */
+HWND APIENTRY
+NtUserWindowFromPhysicalPoint(POINT Point)
+{
+   UNIMPLEMENTED
+
+   return NULL;
+}
 
 /*
  *    @implemented
@@ -4709,7 +4818,7 @@ BOOL APIENTRY
 NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
    LARGE_STRING SafeText;
    UNICODE_STRING UnicodeString;
    BOOL Ret = TRUE;
@@ -4769,38 +4878,38 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
 
    if (UnicodeString.Length != 0)
    {
-      if (Wnd->WindowName.MaximumLength > 0 &&
-          UnicodeString.Length <= Wnd->WindowName.MaximumLength - sizeof(UNICODE_NULL))
+      if (Wnd->strName.MaximumLength > 0 &&
+          UnicodeString.Length <= Wnd->strName.MaximumLength - sizeof(UNICODE_NULL))
       {
-         ASSERT(Wnd->WindowName.Buffer != NULL);
+         ASSERT(Wnd->strName.Buffer != NULL);
 
-         Wnd->WindowName.Length = UnicodeString.Length;
-         Wnd->WindowName.Buffer[UnicodeString.Length / sizeof(WCHAR)] = L'\0';
-         RtlCopyMemory(Wnd->WindowName.Buffer,
+         Wnd->strName.Length = UnicodeString.Length;
+         Wnd->strName.Buffer[UnicodeString.Length / sizeof(WCHAR)] = L'\0';
+         RtlCopyMemory(Wnd->strName.Buffer,
                               UnicodeString.Buffer,
                               UnicodeString.Length);
       }
       else
       {
          PWCHAR buf;
-         Wnd->WindowName.MaximumLength = Wnd->WindowName.Length = 0;
-         buf = Wnd->WindowName.Buffer;
-         Wnd->WindowName.Buffer = NULL;
+         Wnd->strName.MaximumLength = Wnd->strName.Length = 0;
+         buf = Wnd->strName.Buffer;
+         Wnd->strName.Buffer = NULL;
          if (buf != NULL)
          {
-            DesktopHeapFree(Wnd->pdesktop, buf);
+            DesktopHeapFree(Wnd->head.rpdesk, buf);
          }
 
-         Wnd->WindowName.Buffer = DesktopHeapAlloc(Wnd->pdesktop,
+         Wnd->strName.Buffer = DesktopHeapAlloc(Wnd->head.rpdesk,
                                                    UnicodeString.Length + sizeof(UNICODE_NULL));
-         if (Wnd->WindowName.Buffer != NULL)
+         if (Wnd->strName.Buffer != NULL)
          {
-            Wnd->WindowName.Buffer[UnicodeString.Length / sizeof(WCHAR)] = L'\0';
-            RtlCopyMemory(Wnd->WindowName.Buffer,
+            Wnd->strName.Buffer[UnicodeString.Length / sizeof(WCHAR)] = L'\0';
+            RtlCopyMemory(Wnd->strName.Buffer,
                                  UnicodeString.Buffer,
                                  UnicodeString.Length);
-            Wnd->WindowName.MaximumLength = UnicodeString.Length + sizeof(UNICODE_NULL);
-            Wnd->WindowName.Length = UnicodeString.Length;
+            Wnd->strName.MaximumLength = UnicodeString.Length + sizeof(UNICODE_NULL);
+            Wnd->strName.Length = UnicodeString.Length;
          }
          else
          {
@@ -4812,9 +4921,9 @@ NtUserDefSetText(HWND hWnd, PLARGE_STRING WindowText)
    }
    else
    {
-      Wnd->WindowName.Length = 0;
-      if (Wnd->WindowName.Buffer != NULL)
-          Wnd->WindowName.Buffer[0] = L'\0';
+      Wnd->strName.Length = 0;
+      if (Wnd->strName.Buffer != NULL)
+          Wnd->strName.Buffer[0] = L'\0';
    }
 
    // HAX! FIXME! Windows does not do this in here!
@@ -4845,7 +4954,7 @@ INT APIENTRY
 NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
 {
    PWINDOW_OBJECT Window;
-   PWINDOW Wnd;
+   PWND Wnd;
    NTSTATUS Status;
    INT Result;
    DECLARE_RETURN(INT);
@@ -4865,7 +4974,7 @@ NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
    }
    Wnd = Window->Wnd;
 
-   Result = Wnd->WindowName.Length / sizeof(WCHAR);
+   Result = Wnd->strName.Length / sizeof(WCHAR);
    if(lpString)
    {
       const WCHAR Terminator = L'\0';
@@ -4875,7 +4984,7 @@ NtUserInternalGetWindowText(HWND hWnd, LPWSTR lpString, INT nMaxCount)
       Copy = min(nMaxCount - 1, Result);
       if(Copy > 0)
       {
-         Status = MmCopyToCaller(Buffer, Wnd->WindowName.Buffer, Copy * sizeof(WCHAR));
+         Status = MmCopyToCaller(Buffer, Wnd->strName.Buffer, Copy * sizeof(WCHAR));
          if(!NT_SUCCESS(Status))
          {
             SetLastNtError(Status);
@@ -4930,7 +5039,7 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
 
       if (fShow)
       {
-         if (pWnd->Flags & WIN_NEEDS_SHOW_OWNEDPOPUP)
+         if (pWnd->Wnd->state & WNDS_HIDDENPOPUP)
          {
             /* In Windows, ShowOwnedPopups(TRUE) generates
              * WM_SHOWWINDOW messages with SW_PARENTOPENING,
@@ -4942,7 +5051,7 @@ IntShowOwnedPopups(PWINDOW_OBJECT OwnerWnd, BOOL fShow )
       }
       else
       {
-         if (pWnd->Wnd->Style & WS_VISIBLE)
+         if (pWnd->Wnd->style & WS_VISIBLE)
          {
             /* In Windows, ShowOwnedPopups(FALSE) generates
              * WM_SHOWWINDOW messages with SW_PARENTCLOSING,
@@ -5017,7 +5126,7 @@ NtUserValidateHandleSecure(
        }
        case otMonitor:
        {
-         PMONITOR_OBJECT Monitor;
+         PMONITOR Monitor;
          if ((Monitor = UserGetMonitorObject((HMONITOR) handle))) return TRUE;
          return FALSE;
        }