[Win32k]
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / winpos.c
index 67d468e..0d6b268 100644 (file)
@@ -16,8 +16,7 @@
  *  with this program; if not, write to the Free Software Foundation, Inc.,
  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
-/* $Id$
- *
+/*
  * COPYRIGHT:        See COPYING in the top level directory
  * PROJECT:          ReactOS kernel
  * PURPOSE:          Windows
  */
 /* INCLUDES ******************************************************************/
 
-#include <w32k.h>
+#include <win32k.h>
 
 #define NDEBUG
 #include <debug.h>
 
 VOID FASTCALL
-co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse);
+co_IntPaintWindows(PWND Window, ULONG Flags, BOOL Recurse);
 
 BOOL FASTCALL
-IntValidateParent(PWINDOW_OBJECT Child, HRGN hValidateRgn, BOOL Recurse);
+IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse);
 
 /* GLOBALS *******************************************************************/
 
@@ -56,7 +55,7 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN hValidateRgn, BOOL Recurse);
 /* FUNCTIONS *****************************************************************/
 
 BOOL FASTCALL
-IntGetClientOrigin(PWINDOW_OBJECT Window OPTIONAL, LPPOINT Point)
+IntGetClientOrigin(PWND Window OPTIONAL, LPPOINT Point)
 {
    Window = Window ? Window : UserGetWindowObject(IntGetDesktopWindow());
    if (Window == NULL)
@@ -64,17 +63,14 @@ IntGetClientOrigin(PWINDOW_OBJECT Window OPTIONAL, LPPOINT Point)
       Point->x = Point->y = 0;
       return FALSE;
    }
-   Point->x = Window->Wnd->rcClient.left;
-   Point->y = Window->Wnd->rcClient.top;
+   Point->x = Window->rcClient.left;
+   Point->y = Window->rcClient.top;
 
    return TRUE;
 }
 
-
-
-
 BOOL FASTCALL
-UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point)
+UserGetClientOrigin(PWND Window, LPPOINT Point)
 {
    BOOL Ret;
    POINT pt;
@@ -82,7 +78,7 @@ UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point)
 
    if(!Point)
    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      EngSetLastError(ERROR_INVALID_PARAMETER);
       return FALSE;
    }
 
@@ -90,7 +86,7 @@ UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point)
 
    if(!Ret)
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
    }
 
@@ -112,17 +108,22 @@ UserGetClientOrigin(PWINDOW_OBJECT Window, LPPOINT Point)
  * Check if we can activate the specified window.
  */
 static
-BOOL FASTCALL can_activate_window( PWINDOW_OBJECT Wnd OPTIONAL)
+BOOL FASTCALL can_activate_window( PWND Wnd OPTIONAL)
 {
     LONG style;
 
     if (!Wnd) return FALSE;
-       if (!Wnd->Wnd) return FALSE;
-    style = Wnd->Wnd->style;
+
+    style = Wnd->style;
     if (!(style & WS_VISIBLE) &&
-        Wnd->OwnerThread->ThreadsProcess != CsrProcess) return FALSE;
+        Wnd->head.pti->pEThread->ThreadsProcess != CsrProcess) return FALSE;
+    if ((style & WS_MINIMIZE) &&
+        Wnd->head.pti->pEThread->ThreadsProcess != CsrProcess) return FALSE;
     if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
-    return !(style & WS_DISABLED);
+    return TRUE;
+    /* FIXME: This window could be disable  because the child that closed
+              was a popup. */
+    //return !(style & WS_DISABLED);
 }
 
 
@@ -132,25 +133,22 @@ BOOL FASTCALL can_activate_window( PWINDOW_OBJECT Wnd OPTIONAL)
  *  Activates window other than pWnd.
  */
 VOID FASTCALL
-co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
+co_WinPosActivateOtherWindow(PWND Wnd)
 {
-   PWINDOW_OBJECT WndTo = NULL;
+   PWND WndTo = NULL;
    HWND Fg;
    USER_REFERENCE_ENTRY Ref;
-   PWND Wnd;
-
-   ASSERT_REFS_CO(Window);
 
-   Wnd = Window->Wnd;
+   ASSERT_REFS_CO(Wnd);
 
-   if (IntIsDesktopWindow(Window))
+   if (IntIsDesktopWindow(Wnd))
    {
       IntSetFocusMessageQueue(NULL);
       return;
    }
 
    /* If this is popup window, try to activate the owner first. */
-   if ((Wnd->style & WS_POPUP) && (WndTo = IntGetOwner(Window)))
+   if ((Wnd->style & WS_POPUP) && (WndTo = Wnd->spwndOwner))
    {
       WndTo = UserGetAncestor( WndTo, GA_ROOT );
       if (can_activate_window(WndTo)) goto done;
@@ -158,7 +156,7 @@ co_WinPosActivateOtherWindow(PWINDOW_OBJECT Window)
 
    /* Pick a next top-level window. */
    /* FIXME: Search for non-tooltip windows first. */
-   WndTo = Window;
+   WndTo = Wnd;
    for (;;)
    {
       if (!(WndTo = WndTo->spwndNext)) break;
@@ -170,7 +168,7 @@ done:
    if (WndTo) UserRefObjectCo(WndTo, &Ref);
 
    Fg = UserGetForegroundWindow();
-   if ((!Fg || Window->hSelf == Fg) && WndTo)//fixme: ok if WndTo is NULL??
+   if ((!Fg || Wnd->head.h == Fg) && WndTo)//fixme: ok if WndTo is NULL??
    {
       /* fixme: wine can pass WndTo=NULL to co_IntSetForegroundWindow. hmm */
       if (co_IntSetForegroundWindow(WndTo))
@@ -189,7 +187,7 @@ done:
 
 UINT
 FASTCALL
-co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent)
+co_WinPosArrangeIconicWindows(PWND parent)
 {
    RECTL rectParent;
    INT i, x, y, xspacing, yspacing;
@@ -208,24 +206,21 @@ co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent)
 
    for( i = 0; List[i]; i++)
    {
-      PWINDOW_OBJECT WndChild;
-      PWND ChildWnd;
+      PWND Child;
 
-      if (!(WndChild = UserGetWindowObject(List[i])))
+      if (!(Child = UserGetWindowObject(List[i])))
          continue;
 
-      ChildWnd = WndChild->Wnd;
-
-      if((ChildWnd->style & WS_MINIMIZE) != 0 )
+      if((Child->style & WS_MINIMIZE) != 0 )
       {
          USER_REFERENCE_ENTRY Ref;
-         UserRefObjectCo(WndChild, &Ref);
+         UserRefObjectCo(Child, &Ref);
 
-         co_WinPosSetWindowPos(WndChild, 0, x + UserGetSystemMetrics(SM_CXBORDER),
+         co_WinPosSetWindowPos(Child, 0, x + UserGetSystemMetrics(SM_CXBORDER),
                                y - yspacing - UserGetSystemMetrics(SM_CYBORDER)
                                , 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
 
-         UserDerefObjectCo(WndChild);
+         UserDerefObjectCo(Child);
 
          if (x <= rectParent.right - xspacing)
             x += xspacing;
@@ -242,37 +237,34 @@ co_WinPosArrangeIconicWindows(PWINDOW_OBJECT parent)
 
 
 static VOID FASTCALL
-WinPosFindIconPos(PWINDOW_OBJECT Window, POINT *Pos)
+WinPosFindIconPos(PWND Window, POINT *Pos)
 {
    /* FIXME */
 }
 
 VOID FASTCALL
-WinPosInitInternalPos(PWINDOW_OBJECT Window, POINT *pt, RECTL *RestoreRect)
+WinPosInitInternalPos(PWND Wnd, POINT *pt, RECTL *RestoreRect)
 {
-    PWINDOW_OBJECT Parent;
+    PWND Parent;
     UINT XInc, YInc;
-    PWND Wnd = Window->Wnd;
 
    if (!Wnd->InternalPosInitialized)
    {
       RECTL WorkArea;
-      PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-      PDESKTOP Desktop = pti->Desktop; /* Or rather get it from the window? */
 
-      Parent = Window->spwndParent;
+      Parent = Wnd->spwndParent;
       if(Parent)
       {
          if(IntIsDesktopWindow(Parent))
-            IntGetDesktopWorkArea(Desktop, &WorkArea);
+             UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
          else
-            WorkArea = Parent->Wnd->rcClient;
+            WorkArea = Parent->rcClient;
       }
       else
-         IntGetDesktopWorkArea(Desktop, &WorkArea);
+         UserSystemParametersInfo(SPI_GETWORKAREA, 0, &WorkArea, 0);
 
-      Wnd->InternalPos.NormalRect = Window->Wnd->rcWindow;
-      IntGetWindowBorderMeasures(Window, &XInc, &YInc);
+      Wnd->InternalPos.NormalRect = Wnd->rcWindow;
+      IntGetWindowBorderMeasures(Wnd, &XInc, &YInc);
       Wnd->InternalPos.MaxPos.x = WorkArea.left - XInc;
       Wnd->InternalPos.MaxPos.y = WorkArea.top - YInc;
       Wnd->InternalPos.IconPos.x = WorkArea.left;
@@ -295,25 +287,25 @@ WinPosInitInternalPos(PWINDOW_OBJECT Window, POINT *pt, RECTL *RestoreRect)
 }
 
 UINT FASTCALL
-co_WinPosMinMaximize(PWINDOW_OBJECT Window, UINT ShowFlag, RECT* NewPos)
+co_WinPosMinMaximize(PWND Wnd, UINT ShowFlag, RECT* NewPos)
 {
    POINT Size;
    UINT SwpFlags = 0;
-   PWND Wnd;
 
-   ASSERT_REFS_CO(Window);
-   Wnd = Window->Wnd;
+   ASSERT_REFS_CO(Wnd);
 
    Size.x = Wnd->rcWindow.left;
    Size.y = Wnd->rcWindow.top;
-   WinPosInitInternalPos(Window, &Size, &Wnd->rcWindow);
+   WinPosInitInternalPos(Wnd, &Size, &Wnd->rcWindow);
 
-   if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Window->hSelf, ShowFlag))
+   if (co_HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)Wnd->head.h, ShowFlag))
+   {
+      DPRINT1("WinPosMinMaximize WH_CBT Call Hook return!\n");
       return SWP_NOSIZE | SWP_NOMOVE;
-
+   }
       if (Wnd->style & WS_MINIMIZE)
       {
-         if (!co_IntSendMessage(Window->hSelf, WM_QUERYOPEN, 0, 0))
+         if (!co_IntSendMessageNoWait(Wnd->head.h, WM_QUERYOPEN, 0, 0))
          {
             return(SWP_NOSIZE | SWP_NOMOVE);
          }
@@ -325,17 +317,17 @@ co_WinPosMinMaximize(PWINDOW_OBJECT Window, UINT ShowFlag, RECT* NewPos)
             {
                if (Wnd->style & WS_MAXIMIZE)
                {
-                  Window->state |= WINDOWOBJECT_RESTOREMAX;
+                  Wnd->state2 |= WNDS2_MAXIMIZEBUTTONDOWN;
                   Wnd->style &= ~WS_MAXIMIZE;
                }
                else
                {
-                  Window->state &= ~WINDOWOBJECT_RESTOREMAX;
+                  Wnd->state2 &= ~WNDS2_MAXIMIZEBUTTONDOWN;
                }
-               co_UserRedrawWindow(Window, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
+               co_UserRedrawWindow(Wnd, NULL, 0, RDW_VALIDATE | RDW_NOERASE |
                                    RDW_NOINTERNALPAINT);
                Wnd->style |= WS_MINIMIZE;
-               WinPosFindIconPos(Window, &Wnd->InternalPos.IconPos);
+               WinPosFindIconPos(Wnd, &Wnd->InternalPos.IconPos);
                RECTL_vSetRect(NewPos, Wnd->InternalPos.IconPos.x, Wnd->InternalPos.IconPos.y,
                              UserGetSystemMetrics(SM_CXMINIMIZED),
                              UserGetSystemMetrics(SM_CYMINIMIZED));
@@ -345,7 +337,7 @@ co_WinPosMinMaximize(PWINDOW_OBJECT Window, UINT ShowFlag, RECT* NewPos)
 
          case SW_MAXIMIZE:
             {
-               co_WinPosGetMinMaxInfo(Window, &Size, &Wnd->InternalPos.MaxPos,
+               co_WinPosGetMinMaxInfo(Wnd, &Size, &Wnd->InternalPos.MaxPos,
                                       NULL, NULL);
                DPRINT("Maximize: %d,%d %dx%d\n",
                       Wnd->InternalPos.MaxPos.x, Wnd->InternalPos.MaxPos.y, Size.x, Size.y);
@@ -364,9 +356,9 @@ co_WinPosMinMaximize(PWINDOW_OBJECT Window, UINT ShowFlag, RECT* NewPos)
                if (Wnd->style & WS_MINIMIZE)
                {
                   Wnd->style &= ~WS_MINIMIZE;
-                  if (Window->state & WINDOWOBJECT_RESTOREMAX)
+                  if (Wnd->state2 & WNDS2_MAXIMIZEBUTTONDOWN)
                   {
-                     co_WinPosGetMinMaxInfo(Window, &Size,
+                     co_WinPosGetMinMaxInfo(Wnd, &Size,
                                             &Wnd->InternalPos.MaxPos, NULL, NULL);
                      Wnd->style |= WS_MAXIMIZE;
                      RECTL_vSetRect(NewPos, Wnd->InternalPos.MaxPos.x,
@@ -395,53 +387,156 @@ co_WinPosMinMaximize(PWINDOW_OBJECT Window, UINT ShowFlag, RECT* NewPos)
                }
             }
       }
-
    return(SwpFlags);
 }
 
-static
-VOID FASTCALL
-WinPosFillMinMaxInfoStruct(PWINDOW_OBJECT Window, MINMAXINFO *Info)
+BOOL
+UserHasWindowEdge(DWORD Style, DWORD ExStyle)
 {
-   UINT XInc, YInc;
-   RECTL WorkArea;
-   PTHREADINFO pti = PsGetCurrentThreadWin32Thread();
-   PDESKTOP Desktop = pti->Desktop; /* Or rather get it from the window? */
-
-   IntGetDesktopWorkArea(Desktop, &WorkArea);
+   if (Style & WS_MINIMIZE)
+      return TRUE;
+   if (ExStyle & WS_EX_DLGMODALFRAME)
+      return TRUE;
+   if (ExStyle & WS_EX_STATICEDGE)
+      return FALSE;
+   if (Style & WS_THICKFRAME)
+      return TRUE;
+   Style &= WS_CAPTION;
+   if (Style == WS_DLGFRAME || Style == WS_CAPTION)
+      return TRUE;
+   return FALSE;
+}
 
-   /* Get default values. */
-   Info->ptMinTrackSize.x = UserGetSystemMetrics(SM_CXMINTRACK);
-   Info->ptMinTrackSize.y = UserGetSystemMetrics(SM_CYMINTRACK);
+VOID
+UserGetWindowBorders(DWORD Style, DWORD ExStyle, SIZE *Size, BOOL WithClient)
+{
+   DWORD Border = 0;
+
+   if (UserHasWindowEdge(Style, ExStyle))
+      Border += 2;
+   else if (ExStyle & WS_EX_STATICEDGE)
+      Border += 1;
+   if ((ExStyle & WS_EX_CLIENTEDGE) && WithClient)
+      Border += 2;
+   if (Style & WS_CAPTION || ExStyle & WS_EX_DLGMODALFRAME)
+      Border ++;
+   Size->cx = Size->cy = Border;
+   if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE))
+   {
+      Size->cx += UserGetSystemMetrics(SM_CXFRAME) - UserGetSystemMetrics(SM_CXDLGFRAME);
+      Size->cy += UserGetSystemMetrics(SM_CYFRAME) - UserGetSystemMetrics(SM_CYDLGFRAME);
+   }
+   Size->cx *= UserGetSystemMetrics(SM_CXBORDER);
+   Size->cy *= UserGetSystemMetrics(SM_CYBORDER);
+}
 
-   IntGetWindowBorderMeasures(Window, &XInc, &YInc);
-   Info->ptMaxSize.x = WorkArea.right - WorkArea.left + 2 * XInc;
-   Info->ptMaxSize.y = WorkArea.bottom - WorkArea.top + 2 * YInc;
-   Info->ptMaxTrackSize.x = Info->ptMaxSize.x;
-   Info->ptMaxTrackSize.y = Info->ptMaxSize.y;
+BOOL WINAPI
+UserAdjustWindowRectEx(LPRECT lpRect,
+                       DWORD dwStyle,
+                       BOOL bMenu,
+                       DWORD dwExStyle)
+{
+   SIZE BorderSize;
 
-   if (Window->Wnd->InternalPosInitialized)
+   if (bMenu)
    {
-      Info->ptMaxPosition = Window->Wnd->InternalPos.MaxPos;
+      lpRect->top -= UserGetSystemMetrics(SM_CYMENU);
    }
-   else
+   if ((dwStyle & WS_CAPTION) == WS_CAPTION)
    {
-      Info->ptMaxPosition.x = WorkArea.left - XInc;
-      Info->ptMaxPosition.y = WorkArea.top - YInc;
+      if (dwExStyle & WS_EX_TOOLWINDOW)
+         lpRect->top -= UserGetSystemMetrics(SM_CYSMCAPTION);
+      else
+         lpRect->top -= UserGetSystemMetrics(SM_CYCAPTION);
    }
+   UserGetWindowBorders(dwStyle, dwExStyle, &BorderSize, TRUE);
+   RECTL_vInflateRect(
+      lpRect,
+      BorderSize.cx,
+      BorderSize.cy);
+
+   return TRUE;
 }
 
 UINT FASTCALL
-co_WinPosGetMinMaxInfo(PWINDOW_OBJECT Window, POINT* MaxSize, POINT* MaxPos,
+co_WinPosGetMinMaxInfo(PWND Window, POINT* MaxSize, POINT* MaxPos,
                        POINT* MinTrack, POINT* MaxTrack)
 {
    MINMAXINFO MinMax;
+   PMONITOR monitor;
+    INT xinc, yinc;
+    LONG style = Window->style;
+    LONG adjustedStyle;
+    LONG exstyle = Window->ExStyle;
+    RECT rc;
 
-   ASSERT_REFS_CO(Window);
+    ASSERT_REFS_CO(Window);
+
+    /* Compute default values */
+
+    rc = Window->rcWindow;
+    MinMax.ptReserved.x = rc.left;
+    MinMax.ptReserved.y = rc.top;
+
+    if ((style & WS_CAPTION) == WS_CAPTION)
+        adjustedStyle = style & ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
+    else
+        adjustedStyle = style;
+
+    if(Window->spwndParent)
+        IntGetClientRect(Window->spwndParent, &rc);
+    UserAdjustWindowRectEx(&rc, adjustedStyle, ((style & WS_POPUP) && Window->IDMenu), exstyle);
+
+    xinc = -rc.left;
+    yinc = -rc.top;
+
+    MinMax.ptMaxSize.x = rc.right - rc.left;
+    MinMax.ptMaxSize.y = rc.bottom - rc.top;
+    if (style & (WS_DLGFRAME | WS_BORDER))
+    {
+        MinMax.ptMinTrackSize.x = UserGetSystemMetrics(SM_CXMINTRACK);
+        MinMax.ptMinTrackSize.y = UserGetSystemMetrics(SM_CYMINTRACK);
+    }
+    else
+    {
+        MinMax.ptMinTrackSize.x = 2 * xinc;
+        MinMax.ptMinTrackSize.y = 2 * yinc;
+    }
+    MinMax.ptMaxTrackSize.x = UserGetSystemMetrics(SM_CXMAXTRACK);
+    MinMax.ptMaxTrackSize.y = UserGetSystemMetrics(SM_CYMAXTRACK);
+    MinMax.ptMaxPosition.x = -xinc;
+    MinMax.ptMaxPosition.y = -yinc;
 
-   WinPosFillMinMaxInfoStruct(Window, &MinMax);
+    //if (!EMPTYPOINT(win->max_pos)) MinMax.ptMaxPosition = win->max_pos;
+
+   co_IntSendMessage(Window->head.h, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
+
+    /* if the app didn't change the values, adapt them for the current monitor */
+    if ((monitor = IntGetPrimaryMonitor()))
+    {
+        RECT rc_work;
+
+        rc_work = monitor->rcMonitor;
+
+        if (style & WS_MAXIMIZEBOX)
+        {
+            if ((style & WS_CAPTION) == WS_CAPTION || !(style & (WS_CHILD | WS_POPUP)))
+                rc_work = monitor->rcWork;
+        }
+
+        if (MinMax.ptMaxSize.x == UserGetSystemMetrics(SM_CXSCREEN) + 2 * xinc &&
+            MinMax.ptMaxSize.y == UserGetSystemMetrics(SM_CYSCREEN) + 2 * yinc)
+        {
+            MinMax.ptMaxSize.x = (rc_work.right - rc_work.left) + 2 * xinc;
+            MinMax.ptMaxSize.y = (rc_work.bottom - rc_work.top) + 2 * yinc;
+        }
+        if (MinMax.ptMaxPosition.x == -xinc && MinMax.ptMaxPosition.y == -yinc)
+        {
+            MinMax.ptMaxPosition.x = rc_work.left - xinc;
+            MinMax.ptMaxPosition.y = rc_work.top - yinc;
+        }
+    }
 
-   co_IntSendMessage(Window->hSelf, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax);
 
    MinMax.ptMaxTrackSize.x = max(MinMax.ptMaxTrackSize.x,
                                  MinMax.ptMinTrackSize.x);
@@ -500,15 +595,13 @@ FixClientRect(PRECTL ClientRect, PRECTL WindowRect)
 
 static
 LONG FASTCALL
-co_WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
+co_WinPosDoNCCALCSize(PWND Window, PWINDOWPOS WinPos,
                       RECT* WindowRect, RECT* ClientRect)
 {
-   PWINDOW_OBJECT Parent;
+   PWND Parent;
    UINT wvrFlags = 0;
-   PWND Wnd;
 
    ASSERT_REFS_CO(Window);
-   Wnd = Window->Wnd;
 
    /* Send WM_NCCALCSIZE message to get new client area */
    if ((WinPos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE)
@@ -517,48 +610,48 @@ co_WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
       WINDOWPOS winposCopy;
 
       params.rgrc[0] = *WindowRect;
-      params.rgrc[1] = Window->Wnd->rcWindow;
-      params.rgrc[2] = Window->Wnd->rcClient;
+      params.rgrc[1] = Window->rcWindow;
+      params.rgrc[2] = Window->rcClient;
       Parent = Window->spwndParent;
-      if (0 != (Wnd->style & WS_CHILD) && Parent)
+      if (0 != (Window->style & WS_CHILD) && Parent)
       {
-         RECTL_vOffsetRect(&(params.rgrc[0]), - Parent->Wnd->rcClient.left,
-                          - Parent->Wnd->rcClient.top);
-         RECTL_vOffsetRect(&(params.rgrc[1]), - Parent->Wnd->rcClient.left,
-                          - Parent->Wnd->rcClient.top);
-         RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->Wnd->rcClient.left,
-                          - Parent->Wnd->rcClient.top);
+         RECTL_vOffsetRect(&(params.rgrc[0]), - Parent->rcClient.left,
+                          - Parent->rcClient.top);
+         RECTL_vOffsetRect(&(params.rgrc[1]), - Parent->rcClient.left,
+                          - Parent->rcClient.top);
+         RECTL_vOffsetRect(&(params.rgrc[2]), - Parent->rcClient.left,
+                          - Parent->rcClient.top);
       }
       params.lppos = &winposCopy;
       winposCopy = *WinPos;
 
-      wvrFlags = co_IntSendMessage(Window->hSelf, WM_NCCALCSIZE, TRUE, (LPARAM) &params);
+      wvrFlags = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, TRUE, (LPARAM) &params);
 
       /* If the application send back garbage, ignore it */
       if (params.rgrc[0].left <= params.rgrc[0].right &&
           params.rgrc[0].top <= params.rgrc[0].bottom)
       {
          *ClientRect = params.rgrc[0];
-         if ((Wnd->style & WS_CHILD) && Parent)
+         if ((Window->style & WS_CHILD) && Parent)
          {
-            RECTL_vOffsetRect(ClientRect, Parent->Wnd->rcClient.left,
-                             Parent->Wnd->rcClient.top);
+            RECTL_vOffsetRect(ClientRect, Parent->rcClient.left,
+                             Parent->rcClient.top);
          }
          FixClientRect(ClientRect, WindowRect);
       }
 
       /* FIXME: WVR_ALIGNxxx */
 
-      if (ClientRect->left != Wnd->rcClient.left ||
-          ClientRect->top != Wnd->rcClient.top)
+      if (ClientRect->left != Window->rcClient.left ||
+          ClientRect->top != Window->rcClient.top)
       {
          WinPos->flags &= ~SWP_NOCLIENTMOVE;
       }
 
       if ((ClientRect->right - ClientRect->left !=
-            Wnd->rcClient.right - Wnd->rcClient.left) ||
+            Window->rcClient.right - Window->rcClient.left) ||
             (ClientRect->bottom - ClientRect->top !=
-             Wnd->rcClient.bottom - Wnd->rcClient.top))
+             Window->rcClient.bottom - Window->rcClient.top))
       {
          WinPos->flags &= ~SWP_NOCLIENTSIZE;
       }
@@ -566,8 +659,8 @@ co_WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
    else
    {
       if (! (WinPos->flags & SWP_NOMOVE)
-            && (ClientRect->left != Wnd->rcClient.left ||
-                ClientRect->top != Wnd->rcClient.top))
+            && (ClientRect->left != Window->rcClient.left ||
+                ClientRect->top != Window->rcClient.top))
       {
          WinPos->flags &= ~SWP_NOCLIENTMOVE;
       }
@@ -578,24 +671,22 @@ co_WinPosDoNCCALCSize(PWINDOW_OBJECT Window, PWINDOWPOS WinPos,
 
 static
 BOOL FASTCALL
-co_WinPosDoWinPosChanging(PWINDOW_OBJECT Window,
+co_WinPosDoWinPosChanging(PWND Window,
                           PWINDOWPOS WinPos,
                           PRECTL WindowRect,
                           PRECTL ClientRect)
 {
    INT X, Y;
-   PWND Wnd;
 
    ASSERT_REFS_CO(Window);
-   Wnd = Window->Wnd;
 
    if (!(WinPos->flags & SWP_NOSENDCHANGING))
    {
-      co_IntPostOrSendMessage(Window->hSelf, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
+      co_IntSendMessageNoWait(Window->head.h, WM_WINDOWPOSCHANGING, 0, (LPARAM) WinPos);
    }
 
-   *WindowRect = Wnd->rcWindow;
-   *ClientRect = Wnd->rcClient;
+   *WindowRect = Window->rcWindow;
+   *ClientRect = Window->rcClient;
 
    if (!(WinPos->flags & SWP_NOSIZE))
    {
@@ -605,23 +696,23 @@ co_WinPosDoWinPosChanging(PWINDOW_OBJECT Window,
 
    if (!(WinPos->flags & SWP_NOMOVE))
    {
-      PWINDOW_OBJECT Parent;
+      PWND Parent;
       X = WinPos->x;
       Y = WinPos->y;
       Parent = Window->spwndParent;
-      if ((0 != (Wnd->style & WS_CHILD)) && Parent)
+      if ((0 != (Window->style & WS_CHILD)) && Parent)
       {
-         X += Parent->Wnd->rcClient.left;
-         Y += Parent->Wnd->rcClient.top;
+         X += Parent->rcClient.left;
+         Y += Parent->rcClient.top;
       }
 
       WindowRect->left = X;
       WindowRect->top = Y;
-      WindowRect->right += X - Wnd->rcWindow.left;
-      WindowRect->bottom += Y - Wnd->rcWindow.top;
+      WindowRect->right += X - Window->rcWindow.left;
+      WindowRect->bottom += Y - Window->rcWindow.top;
       RECTL_vOffsetRect(ClientRect,
-                       X - Wnd->rcWindow.left,
-                       Y - Wnd->rcWindow.top);
+                       X - Window->rcWindow.left,
+                       Y - Window->rcWindow.top);
    }
 
    WinPos->flags |= SWP_NOCLIENTMOVE | SWP_NOCLIENTSIZE;
@@ -638,11 +729,15 @@ HWND FASTCALL
 WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
 {
    HWND *List = NULL;
-   HWND Owner = UserGetWindow(hWnd, GW_OWNER);
-   LONG Style = UserGetWindowLong(hWnd, GWL_STYLE, FALSE);
-   PWINDOW_OBJECT DesktopWindow, ChildObject;
+   HWND Owner;
+   LONG Style;
+   PWND Window ,DesktopWindow, ChildObject;
    int i;
 
+   Window = UserGetWindowObject(hWnd);
+   Owner = Window->spwndOwner ? Window->spwndOwner->head.h : NULL;
+   Style = Window->style;
+
    if ((Style & WS_POPUP) && Owner)
    {
       /* Make sure this popup stays above the owner */
@@ -664,7 +759,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
                   ChildObject = UserGetWindowObject(List[i]);
                   if (NULL != ChildObject)
                   {
-                     if (0 == (ChildObject->Wnd->ExStyle & WS_EX_TOPMOST))
+                     if (0 == (ChildObject->ExStyle & WS_EX_TOPMOST))
                      {
                         break;
                      }
@@ -693,7 +788,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
    {
       for (i = 0; List[i]; i++)
       {
-         PWINDOW_OBJECT Wnd;
+         PWND Wnd;
 
          if (List[i] == hWnd)
             break;
@@ -701,8 +796,7 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
          if (!(Wnd = UserGetWindowObject(List[i])))
             continue;
 
-         if ((Wnd->Wnd->style & WS_POPUP) &&
-               UserGetWindow(List[i], GW_OWNER) == hWnd)
+         if (Wnd->style & WS_POPUP && Wnd->spwndOwner == Window)
          {
             USER_REFERENCE_ENTRY Ref;
             UserRefObjectCo(Wnd, &Ref);
@@ -729,21 +823,21 @@ WinPosDoOwnedPopups(HWND hWnd, HWND hWndInsertAfter)
  */
 static
 VOID FASTCALL
-WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
+WinPosInternalMoveWindow(PWND Window, INT MoveX, INT MoveY)
 {
-   PWINDOW_OBJECT Child;
+   PWND Child;
 
    ASSERT(Window != Window->spwndChild);
 
-   Window->Wnd->rcWindow.left += MoveX;
-   Window->Wnd->rcWindow.right += MoveX;
-   Window->Wnd->rcWindow.top += MoveY;
-   Window->Wnd->rcWindow.bottom += MoveY;
+   Window->rcWindow.left += MoveX;
+   Window->rcWindow.right += MoveX;
+   Window->rcWindow.top += MoveY;
+   Window->rcWindow.bottom += MoveY;
 
-   Window->Wnd->rcClient.left += MoveX;
-   Window->Wnd->rcClient.right += MoveX;
-   Window->Wnd->rcClient.top += MoveY;
-   Window->Wnd->rcClient.bottom += MoveY;
+   Window->rcClient.left += MoveX;
+   Window->rcClient.right += MoveX;
+   Window->rcClient.top += MoveY;
+   Window->rcClient.bottom += MoveY;
 
    for(Child = Window->spwndChild; Child; Child = Child->spwndNext)
    {
@@ -758,12 +852,8 @@ WinPosInternalMoveWindow(PWINDOW_OBJECT Window, INT MoveX, INT MoveY)
  */
 static
 BOOL FASTCALL
-WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
+WinPosFixupFlags(WINDOWPOS *WinPos, PWND Wnd)
 {
-   PWND Wnd = Window->Wnd;
-
-   if (!Wnd) return FALSE;
-
    if (Wnd->style & WS_VISIBLE)
    {
       WinPos->flags &= ~SWP_SHOWWINDOW;
@@ -839,7 +929,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
             && HWND_NOTOPMOST != WinPos->hwndInsertAfter
             && HWND_BOTTOM != WinPos->hwndInsertAfter)
       {
-         PWINDOW_OBJECT InsAfterWnd, Parent = Window->spwndParent;
+         PWND InsAfterWnd, Parent = Wnd->spwndParent;
 
          InsAfterWnd = UserGetWindowObject(WinPos->hwndInsertAfter);
 
@@ -855,7 +945,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
              * itself.
              */
             if ((WinPos->hwnd == WinPos->hwndInsertAfter) ||
-                  (WinPos->hwnd == UserGetWindow(WinPos->hwndInsertAfter, GW_HWNDNEXT)))
+                ((InsAfterWnd->spwndNext) && (WinPos->hwnd == InsAfterWnd->spwndNext->head.h)))
             {
                WinPos->flags |= SWP_NOZORDER;
             }
@@ -869,7 +959,7 @@ WinPosFixupFlags(WINDOWPOS *WinPos, PWINDOW_OBJECT Window)
 /* x and y are always screen relative */
 BOOLEAN FASTCALL
 co_WinPosSetWindowPos(
-   PWINDOW_OBJECT Window,
+   PWND Window,
    HWND WndInsertAfter,
    INT x,
    INT y,
@@ -893,24 +983,22 @@ co_WinPosSetWindowPos(
    HDC Dc;
    RECTL CopyRect;
    RECTL TempRect;
-   PWINDOW_OBJECT Ancestor;
+   PWND Ancestor;
 
    ASSERT_REFS_CO(Window);
 
-   if (!Window->Wnd) return FALSE;
-
    /* FIXME: Get current active window from active queue. */
-
    /*
     * Only allow CSRSS to mess with the desktop window
     */
-   if (Window->hSelf == IntGetDesktopWindow() &&
-         Window->OwnerThread->ThreadsProcess != PsGetCurrentProcess())
+
+   if ( Window->head.h == IntGetDesktopWindow() &&
+        Window->head.pti->pEThread->ThreadsProcess != PsGetCurrentProcess())
    {
       return FALSE;
    }
 
-   WinPos.hwnd = Window->hSelf;
+   WinPos.hwnd = Window->head.h;
    WinPos.hwndInsertAfter = WndInsertAfter;
    WinPos.x = x;
    WinPos.y = y;
@@ -923,21 +1011,21 @@ co_WinPosSetWindowPos(
    /* Fix up the flags. */
    if (!WinPosFixupFlags(&WinPos, Window))
    {
-      SetLastWin32Error(ERROR_INVALID_PARAMETER);
+      EngSetLastError(ERROR_INVALID_PARAMETER);
       return FALSE;
    }
 
    /* Does the window still exist? */
    if (!IntIsWindow(WinPos.hwnd))
    {
-      SetLastWin32Error(ERROR_INVALID_WINDOW_HANDLE);
+      EngSetLastError(ERROR_INVALID_WINDOW_HANDLE);
       return FALSE;
    }
 
    Ancestor = UserGetAncestor(Window, GA_PARENT);
-   if ((WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
+   if ( (WinPos.flags & (SWP_NOZORDER | SWP_HIDEWINDOW | SWP_SHOWWINDOW)) !=
          SWP_NOZORDER &&
-         Ancestor && Ancestor->hSelf == IntGetDesktopWindow())
+         Ancestor && Ancestor->head.h == IntGetDesktopWindow() )
    {
       WinPos.hwndInsertAfter = WinPosDoOwnedPopups(WinPos.hwnd, WinPos.hwndInsertAfter);
    }
@@ -946,15 +1034,16 @@ co_WinPosSetWindowPos(
    {
       /* Compute the visible region before the window position is changed */
       if (!(WinPos.flags & (SWP_NOREDRAW | SWP_SHOWWINDOW)) &&
-            (WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
+           (WinPos.flags & (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER |
                              SWP_HIDEWINDOW | SWP_FRAMECHANGED)) !=
             (SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER))
       {
          VisBefore = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
          VisRgn = NULL;
 
-         if (VisBefore != NULL && (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisBefore, NULL)) &&
-               REGION_GetRgnBox(VisRgn, &TempRect) == NULLREGION)
+         if ( VisBefore != NULL &&
+             (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisBefore, NULL)) &&
+              REGION_GetRgnBox(VisRgn, &TempRect) == NULLREGION )
          {
             RGNOBJAPI_Unlock(VisRgn);
             GreDeleteObject(VisBefore);
@@ -963,7 +1052,7 @@ co_WinPosSetWindowPos(
          else if(VisRgn)
          {
             RGNOBJAPI_Unlock(VisRgn);
-            NtGdiOffsetRgn(VisBefore, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
+            NtGdiOffsetRgn(VisBefore, -Window->rcWindow.left, -Window->rcWindow.top);
          }
       }
    }
@@ -975,80 +1064,11 @@ co_WinPosSetWindowPos(
    /* Relink windows. (also take into account shell window in hwndShellWindow) */
    if (!(WinPos.flags & SWP_NOZORDER) && WinPos.hwnd != UserGetShellWindow())
    {
-      PWINDOW_OBJECT ParentWindow;
-      PWINDOW_OBJECT Sibling;
-      PWINDOW_OBJECT InsertAfterWindow;
-
-      if ((ParentWindow = Window->spwndParent))
-      {
-         if (HWND_TOPMOST == WinPos.hwndInsertAfter)
-         {
-            InsertAfterWindow = NULL;
-         }
-         else if (HWND_TOP == WinPos.hwndInsertAfter
-                  || HWND_NOTOPMOST == WinPos.hwndInsertAfter)
-         {
-            InsertAfterWindow = NULL;
-            Sibling = ParentWindow->spwndChild;
-            while (NULL != Sibling && 0 != (Sibling->Wnd->ExStyle & WS_EX_TOPMOST))
-            {
-               InsertAfterWindow = Sibling;
-               Sibling = Sibling->spwndNext;
-            }
-            if (NULL != InsertAfterWindow)
-            {
-               UserReferenceObject(InsertAfterWindow);
-            }
-         }
-         else if (WinPos.hwndInsertAfter == HWND_BOTTOM)
-         {
-            if(ParentWindow->spwndChild)
-            {
-               InsertAfterWindow = ParentWindow->spwndChild;
-
-               if(InsertAfterWindow)
-               {
-                  while (InsertAfterWindow->spwndNext)
-                     InsertAfterWindow = InsertAfterWindow->spwndNext;
-               }
-
-               UserReferenceObject(InsertAfterWindow);
-            }
-            else
-               InsertAfterWindow = NULL;
-         }
-         else
-            InsertAfterWindow = IntGetWindowObject(WinPos.hwndInsertAfter);
-         /* Do nothing if hwndInsertAfter is HWND_BOTTOM and Window is already
-            the last window */
-         if (InsertAfterWindow != Window)
-         {
-            IntUnlinkWindow(Window);
-            IntLinkWindow(Window, ParentWindow, InsertAfterWindow);
-         }
-         if (InsertAfterWindow != NULL)
-            UserDereferenceObject(InsertAfterWindow);
-         if ((HWND_TOPMOST == WinPos.hwndInsertAfter)
-               || (0 != (Window->Wnd->ExStyle & WS_EX_TOPMOST)
-                   && NULL != Window->spwndPrev
-                   && 0 != (Window->spwndPrev->Wnd->ExStyle & WS_EX_TOPMOST))
-               || (NULL != Window->spwndNext
-                   && 0 != (Window->spwndNext->Wnd->ExStyle & WS_EX_TOPMOST)))
-         {
-            Window->Wnd->ExStyle |= WS_EX_TOPMOST;
-         }
-         else
-         {
-            Window->Wnd->ExStyle &= ~ WS_EX_TOPMOST;
-         }
-
-      }
+      IntLinkHwnd(Window, WndInsertAfter);
    }
 
-   if (!Window->Wnd) return FALSE;
-
-   OldWindowRect = Window->Wnd->rcWindow;
-   OldClientRect = Window->Wnd->rcClient;
+   OldWindowRect = Window->rcWindow;
+   OldClientRect = Window->rcClient;
 
    if (OldClientRect.bottom - OldClientRect.top ==
          NewClientRect.bottom - NewClientRect.top)
@@ -1064,42 +1084,45 @@ co_WinPosSetWindowPos(
 
    /* FIXME: Actually do something with WVR_VALIDRECTS */
 
-   if (NewClientRect.left != OldClientRect.left ||
-         NewClientRect.top != OldClientRect.top)
+   if ( NewClientRect.left != OldClientRect.left ||
+        NewClientRect.top  != OldClientRect.top)
    {
       WinPosInternalMoveWindow(Window,
                                NewClientRect.left - OldClientRect.left,
                                NewClientRect.top - OldClientRect.top);
    }
 
-   Window->Wnd->rcWindow = NewWindowRect;
-   Window->Wnd->rcClient = NewClientRect;
+   Window->rcWindow = NewWindowRect;
+   Window->rcClient = NewClientRect;
 
    if (!(WinPos.flags & SWP_SHOWWINDOW) && (WinPos.flags & SWP_HIDEWINDOW))
    {
       /* Clear the update region */
-      co_UserRedrawWindow(Window, NULL, 0, RDW_VALIDATE | RDW_NOFRAME |
-                          RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
-      if ((Window->Wnd->style & WS_VISIBLE) &&
+      co_UserRedrawWindow( Window,
+                           NULL,
+                           0,
+                           RDW_VALIDATE | RDW_NOFRAME | RDW_NOERASE | RDW_NOINTERNALPAINT | RDW_ALLCHILDREN);
+
+      if ((Window->style & WS_VISIBLE) &&
           Window->spwndParent == UserGetDesktopWindow())
       {
-         co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM)Window->hSelf);
+         co_IntShellHookNotify(HSHELL_WINDOWDESTROYED, (LPARAM)Window->head.h);
       }
-      Window->Wnd->style &= ~WS_VISIBLE;
+      Window->style &= ~WS_VISIBLE;
    }
    else if (WinPos.flags & SWP_SHOWWINDOW)
    {
-      if (!(Window->Wnd->style & WS_VISIBLE) &&
-          Window->spwndParent == UserGetDesktopWindow())
+      if (!(Window->style & WS_VISIBLE) &&
+           Window->spwndParent == UserGetDesktopWindow() )
       {
-         co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Window->hSelf);
+         co_IntShellHookNotify(HSHELL_WINDOWCREATED, (LPARAM)Window->head.h);
       }
-      Window->Wnd->style |= WS_VISIBLE;
+      Window->style |= WS_VISIBLE;
    }
 
-   if (Window->UpdateRegion != NULL && Window->UpdateRegion != (HRGN)1)
+   if (Window->hrgnUpdate != NULL && Window->hrgnUpdate != HRGN_WINDOW)
    {
-      NtGdiOffsetRgn(Window->UpdateRegion,
+      NtGdiOffsetRgn(Window->hrgnUpdate,
                      NewWindowRect.left - OldWindowRect.left,
                      NewWindowRect.top - OldWindowRect.top);
    }
@@ -1112,8 +1135,9 @@ co_WinPosSetWindowPos(
       VisAfter = VIS_ComputeVisibleRegion(Window, FALSE, FALSE, TRUE);
       VisRgn = NULL;
 
-      if (VisAfter != NULL && (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisAfter, NULL)) &&
-            REGION_GetRgnBox(VisRgn, &TempRect) == NULLREGION)
+      if ( VisAfter != NULL &&
+          (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(VisAfter, NULL)) &&
+           REGION_GetRgnBox(VisRgn, &TempRect) == NULLREGION )
       {
          RGNOBJAPI_Unlock(VisRgn);
          GreDeleteObject(VisAfter);
@@ -1122,7 +1146,7 @@ co_WinPosSetWindowPos(
       else if(VisRgn)
       {
          RGNOBJAPI_Unlock(VisRgn);
-         NtGdiOffsetRgn(VisAfter, -Window->Wnd->rcWindow.left, -Window->Wnd->rcWindow.top);
+         NtGdiOffsetRgn(VisAfter, -Window->rcWindow.left, -Window->rcWindow.top);
       }
 
       /*
@@ -1132,11 +1156,13 @@ co_WinPosSetWindowPos(
        * class need to be completely repainted on (horizontal/vertical) size
        * change.
        */
-      if (VisBefore != NULL && VisAfter != NULL && !(WinPos.flags & SWP_NOCOPYBITS) &&
+      if ( VisBefore != NULL &&
+           VisAfter != NULL &&
+          !(WinPos.flags & SWP_NOCOPYBITS) &&
           ((WinPos.flags & SWP_NOSIZE) || !(WvrFlags & WVR_REDRAW)) &&
-          !(Window->Wnd->ExStyle & WS_EX_TRANSPARENT))
+          !(Window->ExStyle & WS_EX_TRANSPARENT) )
       {
-         CopyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+         CopyRgn = IntSysCreateRectRgn(0, 0, 0, 0);
          RgnType = NtGdiCombineRgn(CopyRgn, VisAfter, VisBefore, RGN_AND);
 
          /*
@@ -1147,8 +1173,9 @@ co_WinPosSetWindowPos(
           * we don't have to crop (can't take anything away from an empty
           * region...)
           */
-         if (!(WinPos.flags & SWP_NOSIZE) && RgnType != ERROR &&
-               RgnType != NULLREGION)
+         if (!(WinPos.flags & SWP_NOSIZE) &&
+               RgnType != ERROR &&
+               RgnType != NULLREGION )
          {
             PROSRGNDATA pCopyRgn;
             RECTL ORect = OldClientRect;
@@ -1162,10 +1189,10 @@ co_WinPosSetWindowPos(
          }
 
          /* No use in copying bits which are in the update region. */
-         if (Window->UpdateRegion != NULL)
+         if (Window->hrgnUpdate != NULL)
          {
             NtGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
-            NtGdiCombineRgn(CopyRgn, CopyRgn, Window->UpdateRegion, RGN_DIFF);
+            NtGdiCombineRgn(CopyRgn, CopyRgn, Window->hrgnUpdate, RGN_DIFF);
             NtGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
          }
 
@@ -1174,12 +1201,12 @@ co_WinPosSetWindowPos(
           * there's nothing to copy. Also, it's no use copying bits onto
           * themselves.
           */
-         if ((VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(CopyRgn, NULL)) &&
+         if ( (VisRgn = (PROSRGNDATA)RGNOBJAPI_Lock(CopyRgn, NULL)) &&
                REGION_GetRgnBox(VisRgn, &CopyRect) == NULLREGION)
          {
             /* Nothing to copy, clean up */
             RGNOBJAPI_Unlock(VisRgn);
-            GreDeleteObject(CopyRgn);
+            REGION_FreeRgnByHandle(CopyRgn);
             CopyRgn = NULL;
          }
          else if (OldWindowRect.left != NewWindowRect.left ||
@@ -1190,24 +1217,30 @@ co_WinPosSetWindowPos(
                RGNOBJAPI_Unlock(VisRgn);
             }
 
-            /*
-             * Small trick here: there is no function to bitblt a region. So
-             * we set the region as the clipping region, take the bounding box
-             * of the region and bitblt that. Since nothing outside the clipping
-             * region is copied, this has the effect of bitblt'ing the region.
-             *
-             * Since NtUserGetDCEx takes ownership of the clip region, we need
-             * to create a copy of CopyRgn and pass that. We need CopyRgn later
-             */
+          /*
+           * Small trick here: there is no function to bitblt a region. So
+           * we set the region as the clipping region, take the bounding box
+           * of the region and bitblt that. Since nothing outside the clipping
+           * region is copied, this has the effect of bitblt'ing the region.
+           *
+           * Since NtUserGetDCEx takes ownership of the clip region, we need
+           * to create a copy of CopyRgn and pass that. We need CopyRgn later
+           */
             NtGdiOffsetRgn(CopyRgn, NewWindowRect.left, NewWindowRect.top);
-            Dc = UserGetDCEx(Window, CopyRgn, DCX_WINDOW | DCX_CACHE |
-                             DCX_INTERSECTRGN | DCX_CLIPSIBLINGS |
-                             DCX_KEEPCLIPRGN);
-            NtGdiBitBlt(Dc,
-                        CopyRect.left, CopyRect.top, CopyRect.right - CopyRect.left,
-                        CopyRect.bottom - CopyRect.top, Dc,
-                        CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
-                        CopyRect.top + (OldWindowRect.top - NewWindowRect.top), SRCCOPY, 0, 0);
+            Dc = UserGetDCEx( Window,
+                              CopyRgn,
+                              DCX_WINDOW|DCX_CACHE|DCX_INTERSECTRGN|DCX_CLIPSIBLINGS|DCX_KEEPCLIPRGN);
+            NtGdiBitBlt( Dc,
+                         CopyRect.left, CopyRect.top,
+                         CopyRect.right - CopyRect.left,
+                         CopyRect.bottom - CopyRect.top,
+                         Dc,
+                         CopyRect.left + (OldWindowRect.left - NewWindowRect.left),
+                         CopyRect.top + (OldWindowRect.top - NewWindowRect.top),
+                         SRCCOPY,
+                         0,
+                         0);
+
             UserReleaseDC(Window, Dc, FALSE);
             IntValidateParent(Window, CopyRgn, FALSE);
             NtGdiOffsetRgn(CopyRgn, -NewWindowRect.left, -NewWindowRect.top);
@@ -1225,7 +1258,7 @@ co_WinPosSetWindowPos(
       /* We need to redraw what wasn't visible before */
       if (VisAfter != NULL)
       {
-         DirtyRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+         DirtyRgn = IntSysCreateRectRgn(0, 0, 0, 0);
          if (CopyRgn != NULL)
          {
             RgnType = NtGdiCombineRgn(DirtyRgn, VisAfter, CopyRgn, RGN_DIFF);
@@ -1236,48 +1269,53 @@ co_WinPosSetWindowPos(
          }
          if (RgnType != ERROR && RgnType != NULLREGION)
          {
-                      /* old code
+        /* old code
             NtGdiOffsetRgn(DirtyRgn, Window->rcWindow.left, Window->rcWindow.top);
-            IntInvalidateWindows(Window, DirtyRgn,
+            IntInvalidateWindows( Window,
+                                  DirtyRgn,
                RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
          }
          GreDeleteObject(DirtyRgn);
          */
 
-            PWINDOW_OBJECT Parent = Window->spwndParent;
+            PWND Parent = Window->spwndParent;
 
-            NtGdiOffsetRgn(DirtyRgn,
-                           Window->Wnd->rcWindow.left,
-                           Window->Wnd->rcWindow.top);
-            if ((Window->Wnd->style & WS_CHILD) &&
-                (Parent) &&
-                !(Parent->Wnd->style & WS_CLIPCHILDREN))
+            NtGdiOffsetRgn( DirtyRgn,
+                            Window->rcWindow.left,
+                            Window->rcWindow.top);
+            if ( (Window->style & WS_CHILD) &&
+                 (Parent) &&
+                !(Parent->style & WS_CLIPCHILDREN))
             {
-               IntInvalidateWindows(Parent, DirtyRgn,
-                  RDW_ERASE | RDW_INVALIDATE);
+               IntInvalidateWindows( Parent,
+                                     DirtyRgn,
+                                     RDW_ERASE | RDW_INVALIDATE);
                co_IntPaintWindows(Parent, RDW_ERASENOW, FALSE);
             }
             else
             {
-                IntInvalidateWindows(Window, DirtyRgn,
-                RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
+                IntInvalidateWindows( Window,
+                                      DirtyRgn,
+                    RDW_ERASE | RDW_FRAME | RDW_INVALIDATE | RDW_ALLCHILDREN);
             }
          }
-         GreDeleteObject(DirtyRgn);
+         REGION_FreeRgnByHandle(DirtyRgn);
       }
 
       if (CopyRgn != NULL)
       {
-         GreDeleteObject(CopyRgn);
+         REGION_FreeRgnByHandle(CopyRgn);
       }
 
       /* Expose what was covered before but not covered anymore */
       if (VisBefore != NULL)
       {
-         ExposedRgn = NtGdiCreateRectRgn(0, 0, 0, 0);
+         ExposedRgn = IntSysCreateRectRgn(0, 0, 0, 0);
          NtGdiCombineRgn(ExposedRgn, VisBefore, NULL, RGN_COPY);
-         NtGdiOffsetRgn(ExposedRgn, OldWindowRect.left - NewWindowRect.left,
-                        OldWindowRect.top - NewWindowRect.top);
+         NtGdiOffsetRgn( ExposedRgn,
+                         OldWindowRect.left - NewWindowRect.left,
+                         OldWindowRect.top  - NewWindowRect.top);
+
          if (VisAfter != NULL)
             RgnType = NtGdiCombineRgn(ExposedRgn, ExposedRgn, VisAfter, RGN_DIFF);
          else
@@ -1287,20 +1325,20 @@ co_WinPosSetWindowPos(
          {
             co_VIS_WindowLayoutChanged(Window, ExposedRgn);
          }
-         GreDeleteObject(ExposedRgn);
-         GreDeleteObject(VisBefore);
+         REGION_FreeRgnByHandle(ExposedRgn);
+         REGION_FreeRgnByHandle(VisBefore);
       }
 
       if (VisAfter != NULL)
       {
-         GreDeleteObject(VisAfter);
+         REGION_FreeRgnByHandle(VisAfter);
       }
 
       if (!(WinPos.flags & SWP_NOACTIVATE))
       {
-         if ((Window->Wnd->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
+         if ((Window->style & (WS_CHILD | WS_POPUP)) == WS_CHILD)
          {
-            co_IntSendMessage(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
+            co_IntSendMessageNoWait(WinPos.hwnd, WM_CHILDACTIVATE, 0, 0);
          }
          else
          {
@@ -1310,40 +1348,79 @@ co_WinPosSetWindowPos(
    }
 
    if ((WinPos.flags & SWP_AGG_STATUSFLAGS) != SWP_AGG_NOPOSCHANGE)
-      co_IntPostOrSendMessage(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
+   {
+      /* WM_WINDOWPOSCHANGED is sent even if SWP_NOSENDCHANGING is set
+         and always contains final window position.
+       */
+      WinPos.x = NewWindowRect.left;
+      WinPos.y = NewWindowRect.top;
+      WinPos.cx = NewWindowRect.right - NewWindowRect.left;
+      WinPos.cy = NewWindowRect.bottom - NewWindowRect.top;
+      co_IntSendMessageNoWait(WinPos.hwnd, WM_WINDOWPOSCHANGED, 0, (LPARAM) &WinPos);
+   }
+
+   if ( WinPos.flags & SWP_FRAMECHANGED  || WinPos.flags & SWP_STATECHANGED ||
+      !(WinPos.flags & SWP_NOCLIENTSIZE) || !(WinPos.flags & SWP_NOCLIENTMOVE) )
+   {
+      PWND pWnd = UserGetWindowObject(WinPos.hwnd);
+      if (pWnd)
+         IntNotifyWinEvent(EVENT_OBJECT_LOCATIONCHANGE, pWnd, OBJID_WINDOW, CHILDID_SELF, WEF_SETBYWNDPTI);
+   }
 
    return TRUE;
 }
 
 LRESULT FASTCALL
-co_WinPosGetNonClientSize(PWINDOW_OBJECT Window, RECT* WindowRect, RECT* ClientRect)
+co_WinPosGetNonClientSize(PWND Window, RECT* WindowRect, RECT* ClientRect)
 {
    LRESULT Result;
 
    ASSERT_REFS_CO(Window);
 
    *ClientRect = *WindowRect;
-   Result = co_IntSendMessage(Window->hSelf, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);
+   Result = co_IntSendMessageNoWait(Window->head.h, WM_NCCALCSIZE, FALSE, (LPARAM) ClientRect);
 
    FixClientRect(ClientRect, WindowRect);
 
    return Result;
 }
 
+void FASTCALL
+co_WinPosSendSizeMove(PWND Wnd)
+{
+    WPARAM wParam = SIZE_RESTORED;
+
+    Wnd->state &= ~WNDS_SENDSIZEMOVEMSGS;
+    if (Wnd->style & WS_MAXIMIZE)
+    {
+        wParam = SIZE_MAXIMIZED;
+    }
+    else if (Wnd->style & WS_MINIMIZE)
+    {
+        wParam = SIZE_MINIMIZED;
+    }
+
+    co_IntSendMessageNoWait(Wnd->head.h, WM_SIZE, wParam,
+                        MAKELONG(Wnd->rcClient.right -
+                                 Wnd->rcClient.left,
+                                 Wnd->rcClient.bottom -
+                                 Wnd->rcClient.top));
+    co_IntSendMessageNoWait(Wnd->head.h, WM_MOVE, 0,
+                        MAKELONG(Wnd->rcClient.left,
+                                 Wnd->rcClient.top));
+    IntEngWindowChanged(Wnd, WOC_RGN_CLIENT);
+}
+
 BOOLEAN FASTCALL
-co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
+co_WinPosShowWindow(PWND Wnd, INT Cmd)
 {
    BOOLEAN WasVisible;
    UINT Swp = 0;
    RECTL NewPos;
    BOOLEAN ShowFlag;
    //  HRGN VisibleRgn;
-   PWND Wnd;
 
-   ASSERT_REFS_CO(Window);
-   Wnd = Window->Wnd;
-
-   if (!Wnd) return FALSE;
+   ASSERT_REFS_CO(Wnd);
    
    WasVisible = (Wnd->style & WS_VISIBLE) != 0;
 
@@ -1356,7 +1433,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
                return(FALSE);
             }
             Swp |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE;
-            if (Window->hSelf != UserGetActiveWindow())
+            if (Wnd->head.h != UserGetActiveWindow())
                Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
             break;
          }
@@ -1372,7 +1449,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
             Swp |= SWP_NOACTIVATE;
             if (!(Wnd->style & WS_MINIMIZE))
             {
-               Swp |= co_WinPosMinMaximize(Window, SW_MINIMIZE, &NewPos) |
+               Swp |= co_WinPosMinMaximize(Wnd, SW_MINIMIZE, &NewPos) |
                       SWP_FRAMECHANGED;
             }
             else
@@ -1391,7 +1468,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
             Swp |= SWP_SHOWWINDOW;
             if (!(Wnd->style & WS_MAXIMIZE))
             {
-               Swp |= co_WinPosMinMaximize(Window, SW_MAXIMIZE, &NewPos) |
+               Swp |= co_WinPosMinMaximize(Wnd, SW_MAXIMIZE, &NewPos) |
                       SWP_FRAMECHANGED;
             }
             else
@@ -1424,7 +1501,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
          Swp |= SWP_SHOWWINDOW;
          if (Wnd->style & (WS_MINIMIZE | WS_MAXIMIZE))
          {
-            Swp |= co_WinPosMinMaximize(Window, SW_RESTORE, &NewPos) |
+            Swp |= co_WinPosMinMaximize(Wnd, SW_RESTORE, &NewPos) |
                    SWP_FRAMECHANGED;
          }
          else
@@ -1442,7 +1519,7 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
 
    if (ShowFlag != WasVisible)
    {
-      co_IntSendMessage(Window->hSelf, WM_SHOWWINDOW, ShowFlag, 0);
+      co_IntSendMessageNoWait(Wnd->head.h, WM_SHOWWINDOW, ShowFlag, 0);
    }
 
    /* We can't activate a child window */
@@ -1452,22 +1529,22 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
       Swp |= SWP_NOACTIVATE | SWP_NOZORDER;
    }
 
-   co_WinPosSetWindowPos(Window, 0 != (Wnd->ExStyle & WS_EX_TOPMOST)
+   co_WinPosSetWindowPos(Wnd, 0 != (Wnd->ExStyle & WS_EX_TOPMOST)
                          ? HWND_TOPMOST : HWND_TOP,
                          NewPos.left, NewPos.top, NewPos.right, NewPos.bottom, LOWORD(Swp));
 
-   if (Cmd == SW_HIDE)
+   if ((Cmd == SW_HIDE) || (Cmd == SW_MINIMIZE))
    {
-      PWINDOW_OBJECT ThreadFocusWindow;
+      PWND ThreadFocusWindow;
 
       /* FIXME: This will cause the window to be activated irrespective
        * of whether it is owned by the same thread. Has to be done
        * asynchronously.
        */
 
-      if (Window->hSelf == UserGetActiveWindow())
+      if (Wnd->head.h == UserGetActiveWindow())
       {
-         co_WinPosActivateOtherWindow(Window);
+         co_WinPosActivateOtherWindow(Wnd);
       }
 
 
@@ -1475,41 +1552,20 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
       ThreadFocusWindow = UserGetWindowObject(IntGetThreadFocusWindow());
 
       /* Revert focus to parent */
-      if (ThreadFocusWindow && (Window == ThreadFocusWindow ||
-            IntIsChildWindow(Window, ThreadFocusWindow)))
+      if (ThreadFocusWindow && (Wnd == ThreadFocusWindow ||
+            IntIsChildWindow(Wnd, ThreadFocusWindow)))
       {
          //faxme: as long as we have ref on Window, we also, indirectly, have ref on parent...
-         co_UserSetFocus(Window->spwndParent);
+         co_UserSetFocus(Wnd->spwndParent);
       }
    }
 
    /* FIXME: Check for window destruction. */
 
-   if ((Window->state & WINDOWOBJECT_NEED_SIZE) &&
-       !(Window->state & WINDOWSTATUS_DESTROYING))
+   if ((Wnd->state & WNDS_SENDSIZEMOVEMSGS) &&
+       !(Wnd->state2 & WNDS2_INDESTROY))
    {
-      WPARAM wParam = SIZE_RESTORED;
-
-      Window->state &= ~WINDOWOBJECT_NEED_SIZE;
-      if (Wnd->style & WS_MAXIMIZE)
-      {
-         wParam = SIZE_MAXIMIZED;
-      }
-      else if (Wnd->style & WS_MINIMIZE)
-      {
-         wParam = SIZE_MINIMIZED;
-      }
-
-      co_IntSendMessage(Window->hSelf, WM_SIZE, wParam,
-                        MAKELONG(Wnd->rcClient.right -
-                                 Wnd->rcClient.left,
-                                 Wnd->rcClient.bottom -
-                                 Wnd->rcClient.top));
-      co_IntSendMessage(Window->hSelf, WM_MOVE, 0,
-                        MAKELONG(Wnd->rcClient.left,
-                                 Wnd->rcClient.top));
-      IntEngWindowChanged(Window, WOC_RGN_CLIENT);
-
+        co_WinPosSendSizeMove(Wnd);
    }
 
    /* Activate the window if activation is not requested and the window is not minimized */
@@ -1522,164 +1578,297 @@ co_WinPosShowWindow(PWINDOW_OBJECT Window, INT Cmd)
    return(WasVisible);
 }
 
+static
+PWND FASTCALL
+co_WinPosSearchChildren(
+   PWND ScopeWin,
+   POINT *Point,
+   USHORT *HitTest
+   )
+{
+    PWND pwndChild;
+    HWND *List, *phWnd;
 
-#if 0
+    if (!(ScopeWin->style & WS_VISIBLE))
+    {
+        return NULL;
+    }
 
-/* find child of 'parent' that contains the given point (in parent-relative coords) */
-PWINDOW_OBJECT child_window_from_point(PWINDOW_OBJECT parent, int x, int y )
-{
-    PWINDOW_OBJECT Wnd;// = parent->spwndChild;
+    if ((ScopeWin->style & WS_DISABLED))
+    {
+        return NULL;
+    }
 
-//    LIST_FOR_EACH_ENTRY( Wnd, &parent->children, struct window, entry )
-    for (Wnd = parent->spwndChild; Wnd; Wnd = Wnd->spwndNext)
+    if (!IntPtInWindow(ScopeWin, Point->x, Point->y))
     {
-        if (!IntPtInWindow( Wnd, x, y )) continue;  /* skip it */
+        return NULL;
+    }
 
-        /* if window is minimized or disabled, return at once */
-        if (Wnd->style & (WS_MINIMIZE|WS_DISABLED)) return Wnd;
+    UserReferenceObject(ScopeWin);
 
-        /* if point is not in client area, return at once */
-        if (x < Wnd->rcClient.left || x >= Wnd->rcClient.right ||
-            y < Wnd->rcClient.top || y >= Wnd->rcClient.bottom)
-            return Wnd;
+    if (Point->x - ScopeWin->rcClient.left < ScopeWin->rcClient.right &&
+        Point->y - ScopeWin->rcClient.top < ScopeWin->rcClient.bottom )
+    {
+        List = IntWinListChildren(ScopeWin);
+        if(List)
+        {
+            for (phWnd = List; *phWnd; ++phWnd)
+            {
+                if (!(pwndChild = UserGetWindowObject(*phWnd)))
+                {
+                    continue;
+                }
+
+                pwndChild = co_WinPosSearchChildren(pwndChild, Point, HitTest);
+
+                if(pwndChild != NULL)
+                {
+                    /* We found a window. Don't send any more WM_NCHITTEST messages */
+                    UserDereferenceObject(ScopeWin);
+                    return pwndChild;
+                }
+            }
+        }
 
-        return child_window_from_point( Wnd, x - Wnd->rcClient.left, y - Wnd->rcClient.top );
+        ExFreePool(List);
     }
-    return parent;  /* not found any child */
-}
-#endif
 
-/* wine server: child_window_from_point
+    *HitTest = co_IntSendMessage(ScopeWin->head.h, WM_NCHITTEST, 0,
+                                 MAKELONG(Point->x, Point->y));
+    if ((*HitTest) == (USHORT)HTTRANSPARENT)
+    {
+         UserDereferenceObject(ScopeWin);
+         return NULL;
+    }
+    
+    return ScopeWin;
+}
 
-Caller must dereference the "returned" Window
-*/
-static
-VOID FASTCALL
-co_WinPosSearchChildren(
-   PWINDOW_OBJECT ScopeWin,
-   PUSER_MESSAGE_QUEUE OnlyHitTests,
-   POINT *Point,
-   PWINDOW_OBJECT* Window,
-   USHORT *HitTest
-   )
+PWND FASTCALL
+co_WinPosWindowFromPoint(PWND ScopeWin, POINT *WinPoint, USHORT* HitTest)
 {
-   PWINDOW_OBJECT Current;
-   PWND CurrentWnd;
-   HWND *List, *phWnd;
+   PWND Window;
+   POINT Point = *WinPoint;
    USER_REFERENCE_ENTRY Ref;
 
-   ASSERT_REFS_CO(ScopeWin);
-
-   if ((List = IntWinListChildren(ScopeWin)))
+   if( ScopeWin == NULL )
    {
-      for (phWnd = List; *phWnd; ++phWnd)
-      {
-         if (!(Current = UserGetWindowObject(*phWnd)))
-            continue;
-         CurrentWnd = Current->Wnd;
+       ScopeWin = UserGetDesktopWindow();
+       if(ScopeWin == NULL)
+           return NULL;
+   }
 
-         if (!(CurrentWnd->style & WS_VISIBLE))
-         {
-            continue;
-         }
+   *HitTest = HTNOWHERE;
 
-         if ((CurrentWnd->style & (WS_POPUP | WS_CHILD | WS_DISABLED)) ==
-               (WS_CHILD | WS_DISABLED))
-         {
-            continue;
-         }
+   ASSERT_REFS_CO(ScopeWin);
+   UserRefObjectCo(ScopeWin, &Ref);
 
-         if (!IntPtInWindow(Current, Point->x, Point->y))
-         {
-             continue;
-         }
+   Window = co_WinPosSearchChildren(ScopeWin, &Point, HitTest);
 
-         if (*Window) UserDereferenceObject(*Window);
-         *Window = Current;
-         UserReferenceObject(*Window);
+   UserDerefObjectCo(ScopeWin);
+   if(Window)
+       ASSERT_REFS_CO(Window);
+   ASSERT_REFS_CO(ScopeWin);
 
-         if (CurrentWnd->style & WS_MINIMIZE)
-         {
-            *HitTest = HTCAPTION;
-            break;
-         }
+   return Window;
+}
 
-         if (CurrentWnd->style & WS_DISABLED)
-         {
-            *HitTest = HTERROR;
-            break;
-         }
+HDWP
+FASTCALL
+IntDeferWindowPos( HDWP hdwp,
+                   HWND hwnd,
+                   HWND hwndAfter,
+                   INT x,
+                   INT y,
+                   INT cx,
+                   INT cy,
+                   UINT flags )
+{
+    PSMWP pDWP;
+    int i;
+    HDWP retvalue = hdwp;
+
+    DPRINT("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
+          hdwp, hwnd, hwndAfter, x, y, cx, cy, flags);
+
+    if (flags & ~(SWP_NOSIZE | SWP_NOMOVE |
+                  SWP_NOZORDER | SWP_NOREDRAW |
+                  SWP_NOACTIVATE | SWP_NOCOPYBITS |
+                  SWP_NOOWNERZORDER|SWP_SHOWWINDOW |
+                  SWP_HIDEWINDOW | SWP_FRAMECHANGED))
+    {
+       EngSetLastError(ERROR_INVALID_PARAMETER);
+       return NULL;    
+    }
 
-         UserRefObjectCo(Current, &Ref);
+    if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
+    {
+       EngSetLastError(ERROR_INVALID_DWP_HANDLE);
+       return NULL;
+    }
 
-         if (OnlyHitTests && (Current->MessageQueue == OnlyHitTests))
-         {
-            *HitTest = co_IntSendMessage(Current->hSelf, WM_NCHITTEST, 0,
-                                         MAKELONG(Point->x, Point->y));
-            if ((*HitTest) == (USHORT)HTTRANSPARENT)
+    for (i = 0; i < pDWP->ccvr; i++)
+    {
+        if (pDWP->acvr[i].pos.hwnd == hwnd)
+        {
+              /* Merge with the other changes */
+            if (!(flags & SWP_NOZORDER))
             {
-               UserDerefObjectCo(Current);
-               continue;
+                pDWP->acvr[i].pos.hwndInsertAfter = hwndAfter;
             }
-         }
-         else
-            *HitTest = HTCLIENT;
+            if (!(flags & SWP_NOMOVE))
+            {
+                pDWP->acvr[i].pos.x = x;
+                pDWP->acvr[i].pos.y = y;
+            }
+            if (!(flags & SWP_NOSIZE))
+            {
+                pDWP->acvr[i].pos.cx = cx;
+                pDWP->acvr[i].pos.cy = cy;
+            }
+            pDWP->acvr[i].pos.flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
+                                               SWP_NOZORDER | SWP_NOREDRAW |
+                                               SWP_NOACTIVATE | SWP_NOCOPYBITS|
+                                               SWP_NOOWNERZORDER);
+            pDWP->acvr[i].pos.flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
+                                              SWP_FRAMECHANGED);
+            goto END;
+        }
+    }
+    if (pDWP->ccvr >= pDWP->ccvrAlloc)
+    {
+        PCVR newpos = ExAllocatePoolWithTag(PagedPool, pDWP->ccvrAlloc * 2 * sizeof(CVR), USERTAG_SWP);
+        if (!newpos)
+        {
+            retvalue = NULL;
+            goto END;
+        }
+        RtlZeroMemory(newpos, pDWP->ccvrAlloc * 2 * sizeof(CVR));
+        RtlCopyMemory(newpos, pDWP->acvr, pDWP->ccvrAlloc * sizeof(CVR));
+        ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
+        pDWP->ccvrAlloc *= 2;
+        pDWP->acvr = newpos;
+    }
+    pDWP->acvr[pDWP->ccvr].pos.hwnd = hwnd;
+    pDWP->acvr[pDWP->ccvr].pos.hwndInsertAfter = hwndAfter;
+    pDWP->acvr[pDWP->ccvr].pos.x = x;
+    pDWP->acvr[pDWP->ccvr].pos.y = y;
+    pDWP->acvr[pDWP->ccvr].pos.cx = cx;
+    pDWP->acvr[pDWP->ccvr].pos.cy = cy;
+    pDWP->acvr[pDWP->ccvr].pos.flags = flags;
+    pDWP->acvr[pDWP->ccvr].hrgnClip = NULL; 
+    pDWP->acvr[pDWP->ccvr].hrgnInterMonitor = NULL;
+    pDWP->ccvr++;
+END:
+    return retvalue;
+}
 
-         if (Point->x >= CurrentWnd->rcClient.left &&
-               Point->x < CurrentWnd->rcClient.right &&
-               Point->y >= CurrentWnd->rcClient.top &&
-               Point->y < CurrentWnd->rcClient.bottom)
-         {
-            co_WinPosSearchChildren(Current, OnlyHitTests, Point, Window, HitTest);
-         }
+BOOL FASTCALL IntEndDeferWindowPosEx( HDWP hdwp )
+{
+    PSMWP pDWP;
+    PCVR winpos;
+    BOOL res = TRUE;
+    int i;
 
-         UserDerefObjectCo(Current);
+    DPRINT("%p\n", hdwp);
 
-         break;
-      }
-      ExFreePool(List);
-   }
+    if (!(pDWP = (PSMWP)UserGetObject(gHandleTable, hdwp, otSMWP)))
+    {
+       EngSetLastError(ERROR_INVALID_DWP_HANDLE);
+       return FALSE;
+    }
+
+    for (i = 0, winpos = pDWP->acvr; res && i < pDWP->ccvr; i++, winpos++)
+    {
+        DPRINT("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
+               winpos->pos.hwnd, winpos->pos.hwndInsertAfter, winpos->pos.x, winpos->pos.y,
+               winpos->pos.cx, winpos->pos.cy, winpos->pos.flags);
+
+        res = co_WinPosSetWindowPos( UserGetWindowObject(winpos->pos.hwnd),
+                                     winpos->pos.hwndInsertAfter,
+                                     winpos->pos.x,
+                                     winpos->pos.y,
+                                     winpos->pos.cx,
+                                     winpos->pos.cy,
+                                     winpos->pos.flags);
+    }
+    ExFreePoolWithTag(pDWP->acvr, USERTAG_SWP);
+    UserDeleteObject(hdwp, otSMWP);
+    return res;
 }
 
-/* wine: WINPOS_WindowFromPoint */
-USHORT FASTCALL
-co_WinPosWindowFromPoint(PWINDOW_OBJECT ScopeWin, PUSER_MESSAGE_QUEUE OnlyHitTests, POINT *WinPoint,
-                         PWINDOW_OBJECT* Window)
+/*
+ * @implemented
+ */
+BOOL APIENTRY
+NtUserEndDeferWindowPosEx(HDWP WinPosInfo,
+                          DWORD Unknown1)
 {
-   HWND DesktopWindowHandle;
-   PWINDOW_OBJECT DesktopWindow;
-   POINT Point = *WinPoint;
-   USHORT HitTest;
+   BOOL Ret;
+   DPRINT("Enter NtUserEndDeferWindowPosEx\n");
+   UserEnterExclusive();
+   Ret = IntEndDeferWindowPosEx(WinPosInfo);
+   DPRINT("Leave NtUserEndDeferWindowPosEx, ret=%i\n", Ret);
+   UserLeave();
+   return Ret;
+}
 
-   ASSERT_REFS_CO(ScopeWin);
+/*
+ * @implemented
+ */
+HDWP APIENTRY
+NtUserDeferWindowPos(HDWP WinPosInfo,
+                     HWND Wnd,
+                     HWND WndInsertAfter,
+                     int x,
+                     int y,
+                     int cx,
+                     int cy,
+                     UINT Flags)
+{
+   PWND pWnd, pWndIA;
+   HDWP Ret = NULL;
+   UINT Tmp = ~(SWP_ASYNCWINDOWPOS|SWP_DEFERERASE|SWP_NOSENDCHANGING|SWP_NOREPOSITION|
+                SWP_NOCOPYBITS|SWP_HIDEWINDOW|SWP_SHOWWINDOW|SWP_FRAMECHANGED|
+                SWP_NOACTIVATE|SWP_NOREDRAW|SWP_NOZORDER|SWP_NOMOVE|SWP_NOSIZE);
 
-   *Window = NULL;
+   DPRINT("Enter NtUsereferWindowPos\n");
+   UserEnterExclusive();
 
-   if(!ScopeWin)
+   if ( Flags & Tmp )
    {
-      DPRINT1("WinPosWindowFromPoint(): ScopeWin == NULL!\n");
-      return(HTERROR);
+      EngSetLastError(ERROR_INVALID_FLAGS);
+      goto Exit;
    }
 
-   if (ScopeWin->Wnd->style & WS_DISABLED)
+   pWnd = UserGetWindowObject(Wnd);
+   if ( !pWnd ||
+         pWnd == IntGetDesktopWindow() ||
+         pWnd == IntGetMessageWindow() )
    {
-      return(HTERROR);
+      goto Exit;
    }
 
-   /* Translate the point to the space of the scope window. */
-   DesktopWindowHandle = IntGetDesktopWindow();
-   if((DesktopWindowHandle != ScopeWin->hSelf) &&
-         (DesktopWindow = UserGetWindowObject(DesktopWindowHandle)))
+   if ( WndInsertAfter &&
+        WndInsertAfter != HWND_BOTTOM &&
+        WndInsertAfter != HWND_TOPMOST && 
+        WndInsertAfter != HWND_NOTOPMOST )
    {
-      Point.x += ScopeWin->Wnd->rcClient.left - DesktopWindow->Wnd->rcClient.left;
-      Point.y += ScopeWin->Wnd->rcClient.top - DesktopWindow->Wnd->rcClient.top;
+      pWndIA = UserGetWindowObject(WndInsertAfter);
+      if ( !pWndIA ||
+            pWndIA == IntGetDesktopWindow() ||
+            pWndIA == IntGetMessageWindow() )
+      {
+         goto Exit;
+      }
    }
 
-   HitTest = HTNOWHERE;
-
-   co_WinPosSearchChildren(ScopeWin, OnlyHitTests, &Point, Window, &HitTest);
+   Ret = IntDeferWindowPos(WinPosInfo, Wnd, WndInsertAfter, x, y, cx, cy, Flags);
 
-   return ((*Window) ? HitTest : HTNOWHERE);
+Exit:
+   DPRINT("Leave NtUserDeferWindowPos, ret=%i\n", Ret);
+   UserLeave();
+   return Ret;   
 }
 
 BOOL
@@ -1690,8 +1879,7 @@ NtUserGetMinMaxInfo(
    BOOL SendMessage)
 {
    POINT Size;
-   PWINDOW_OBJECT Window = NULL;
-   PWND Wnd;
+   PWND Window = NULL;
    MINMAXINFO SafeMinMax;
    NTSTATUS Status;
    BOOL ret;
@@ -1707,22 +1895,15 @@ NtUserGetMinMaxInfo(
    }
 
    UserRefObjectCo(Window, &Ref);
-   Wnd = Window->Wnd;
 
-   Size.x = Window->Wnd->rcWindow.left;
-   Size.y = Window->Wnd->rcWindow.top;
+   Size.x = Window->rcWindow.left;
+   Size.y = Window->rcWindow.top;
    WinPosInitInternalPos(Window, &Size,
-                         &Wnd->rcWindow);
+                         &Window->rcWindow);
+
+   co_WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition,
+                          &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
 
-   if(SendMessage)
-   {
-      co_WinPosGetMinMaxInfo(Window, &SafeMinMax.ptMaxSize, &SafeMinMax.ptMaxPosition,
-                             &SafeMinMax.ptMinTrackSize, &SafeMinMax.ptMaxTrackSize);
-   }
-   else
-   {
-      WinPosFillMinMaxInfoStruct(Window, &SafeMinMax);
-   }
    Status = MmCopyToCaller(MinMaxInfo, &SafeMinMax, sizeof(MINMAXINFO));
    if(!NT_SUCCESS(Status))
    {