[CMAKE]
[reactos.git] / subsystems / win32 / win32k / ntuser / painting.c
index 7aba254..fcea7dc 100644 (file)
@@ -2,7 +2,7 @@
  *  COPYRIGHT:        See COPYING in the top level directory
  *  PROJECT:          ReactOS kernel
  *  PURPOSE:          Window painting function
- *  FILE:             subsys/win32k/ntuser/painting.c
+ *  FILE:             subsystems/win32/win32k/ntuser/painting.c
  *  PROGRAMER:        Filip Navara (xnavara@volny.cz)
  *  REVISION HISTORY:
  *       06/06/2001   Created (?)
  */
 
 BOOL FASTCALL
-IntIntersectWithParents(PWINDOW_OBJECT Child, RECTL *WindowRect)
+IntIntersectWithParents(PWND Child, RECTL *WindowRect)
 {
-   PWINDOW_OBJECT ParentWindow;
    PWND ParentWnd;
 
-   ParentWindow = Child->spwndParent;
-   while (ParentWindow != NULL)
+   ParentWnd = Child->spwndParent;
+   while (ParentWnd != NULL)
    {
-      ParentWnd = ParentWindow->Wnd;
       if (!(ParentWnd->style & WS_VISIBLE) ||
           (ParentWnd->style & WS_MINIMIZE))
       {
@@ -58,35 +56,33 @@ IntIntersectWithParents(PWINDOW_OBJECT Child, RECTL *WindowRect)
 
       /* FIXME: Layered windows. */
 
-      ParentWindow = ParentWindow->spwndParent;
+      ParentWnd = ParentWnd->spwndParent;
    }
 
    return TRUE;
 }
 
 BOOL FASTCALL
-IntValidateParent(PWINDOW_OBJECT Child, HRGN hValidateRgn, BOOL Recurse)
+IntValidateParent(PWND Child, HRGN hValidateRgn, BOOL Recurse)
 {
-   PWINDOW_OBJECT ParentWindow = Child->spwndParent;
-   PWND ParentWnd;
+   PWND ParentWnd = Child->spwndParent;
 
-   while (ParentWindow)
+   while (ParentWnd)
    {
-      ParentWnd = ParentWindow->Wnd;
       if (ParentWnd->style & WS_CLIPCHILDREN)
          break;
 
-      if (ParentWindow->hrgnUpdate != 0)
+      if (ParentWnd->hrgnUpdate != 0)
       {
          if (Recurse)
             return FALSE;
 
-         IntInvalidateWindows( ParentWindow,
+         IntInvalidateWindows( ParentWnd,
                                hValidateRgn,
                                RDW_VALIDATE | RDW_NOCHILDREN);
       }
 
-      ParentWindow = ParentWindow->spwndParent;
+      ParentWnd = ParentWnd->spwndParent;
    }
 
    return TRUE;
@@ -99,24 +95,21 @@ IntValidateParent(PWINDOW_OBJECT Child, HRGN hValidateRgn, BOOL Recurse)
  */
 
 HRGN FASTCALL
-IntCalcWindowRgn(PWINDOW_OBJECT Window, BOOL Client)
+IntCalcWindowRgn(PWND Wnd, BOOL Client)
 {
-   PWND Wnd;
    HRGN hRgnWindow;
-   UINT RgnType;
 
-   Wnd = Window->Wnd;
    if (Client)
       hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcClient);
    else
       hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow);
 
-   if (Window->hrgnClip != NULL && !(Wnd->style & WS_MINIMIZE))
+   if (Wnd->hrgnClip != NULL && !(Wnd->style & WS_MINIMIZE))
    {
       NtGdiOffsetRgn(hRgnWindow,
          -Wnd->rcWindow.left,
          -Wnd->rcWindow.top);
-      RgnType = NtGdiCombineRgn(hRgnWindow, hRgnWindow, Window->hrgnClip, RGN_AND);
+      NtGdiCombineRgn(hRgnWindow, hRgnWindow, Wnd->hrgnClip, RGN_AND);
       NtGdiOffsetRgn(hRgnWindow,
          Wnd->rcWindow.left,
          Wnd->rcWindow.top);
@@ -141,14 +134,14 @@ IntCalcWindowRgn(PWINDOW_OBJECT Window, BOOL Client)
  */
 
 HRGN FASTCALL
-IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
+IntGetNCUpdateRgn(PWND Window, BOOL Validate)
 {
    HRGN hRgnNonClient;
    HRGN hRgnWindow;
    UINT RgnType;
 
    if (Window->hrgnUpdate != NULL &&
-       Window->hrgnUpdate != (HRGN)1)
+       Window->hrgnUpdate != HRGN_WINDOW)
    {
       hRgnNonClient = IntCalcWindowRgn(Window, FALSE);
 
@@ -158,28 +151,28 @@ IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
        */
       if (hRgnNonClient == NULL)
       {
-         return (HRGN)1;
+         return HRGN_WINDOW;
       }
 
       hRgnWindow = IntCalcWindowRgn(Window, TRUE);
       if (hRgnWindow == NULL)
       {
-         REGION_FreeRgnByHandle(hRgnNonClient);
-         return (HRGN)1;
+         GreDeleteObject(hRgnNonClient);
+         return HRGN_WINDOW;
       }
 
       RgnType = NtGdiCombineRgn(hRgnNonClient, hRgnNonClient,
                                 hRgnWindow, RGN_DIFF);
       if (RgnType == ERROR)
       {
-         REGION_FreeRgnByHandle(hRgnWindow);
-         REGION_FreeRgnByHandle(hRgnNonClient);
-         return (HRGN)1;
+         GreDeleteObject(hRgnWindow);
+         GreDeleteObject(hRgnNonClient);
+         return HRGN_WINDOW;
       }
       else if (RgnType == NULLREGION)
       {
-         REGION_FreeRgnByHandle(hRgnWindow);
-         REGION_FreeRgnByHandle(hRgnNonClient);
+         GreDeleteObject(hRgnWindow);
+         GreDeleteObject(hRgnNonClient);
          return NULL;
       }
 
@@ -194,14 +187,14 @@ IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
                              hRgnWindow, RGN_AND) == NULLREGION)
          {
             IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
-            REGION_FreeRgnByHandle(Window->hrgnUpdate);
+            GreDeleteObject(Window->hrgnUpdate);
             Window->hrgnUpdate = NULL;
-            if (!(Window->Wnd->state & WNDS_INTERNALPAINT))
-               MsqDecPaintCountQueue(Window->pti->MessageQueue);
+            if (!(Window->state & WNDS_INTERNALPAINT))
+               MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
          }
       }
 
-      REGION_FreeRgnByHandle(hRgnWindow);
+      GreDeleteObject(hRgnWindow);
 
       return hRgnNonClient;
    }
@@ -218,26 +211,23 @@ IntGetNCUpdateRgn(PWINDOW_OBJECT Window, BOOL Validate)
  */
 
 VOID FASTCALL
-co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
+co_IntPaintWindows(PWND Wnd, ULONG Flags, BOOL Recurse)
 {
    HDC hDC;
-   HWND hWnd = Window->hSelf;
+   HWND hWnd = Wnd->head.h;
    HRGN TempRegion;
-   PWND Wnd;
-
-   Wnd = Window->Wnd;
 
    if (Flags & (RDW_ERASENOW | RDW_UPDATENOW))
    {
-      if (Window->hrgnUpdate)
+      if (Wnd->hrgnUpdate)
       {
-         if (!IntValidateParent(Window, Window->hrgnUpdate, Recurse))
+         if (!IntValidateParent(Wnd, Wnd->hrgnUpdate, Recurse))
             return;
       }
 
       if (Flags & RDW_UPDATENOW)
       {
-         if (Window->hrgnUpdate != NULL ||
+         if (Wnd->hrgnUpdate != NULL ||
              Wnd->state & WNDS_INTERNALPAINT)
          {
             co_IntSendMessage(hWnd, WM_PAINT, 0, 0);
@@ -245,34 +235,30 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
       }
       else
       {
-         if (Window->state & WINDOWOBJECT_NEED_NCPAINT)
+         if (Wnd->state & WNDS_SENDNCPAINT)
          {
-            TempRegion = IntGetNCUpdateRgn(Window, TRUE);
-            Window->state &= ~WINDOWOBJECT_NEED_NCPAINT;
-            MsqDecPaintCountQueue(Window->pti->MessageQueue);
+            TempRegion = IntGetNCUpdateRgn(Wnd, TRUE);
+            Wnd->state &= ~WNDS_SENDNCPAINT;
+            MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
             co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)TempRegion, 0);
 
-            if ( (HANDLE) 1 != TempRegion &&
-                 NULL != TempRegion)
-            {
-               /* NOTE: The region can already be deleted! */
-               GDIOBJ_FreeObjByHandle(TempRegion, GDI_OBJECT_TYPE_REGION | GDI_OBJECT_TYPE_SILENT);
-            }
          }
 
-         if (Window->state & WINDOWOBJECT_NEED_ERASEBKGND)
+         if (Wnd->state & WNDS_SENDERASEBACKGROUND)
          {
-            if (Window->hrgnUpdate)
+            if (Wnd->hrgnUpdate)
             {
-               hDC = UserGetDCEx( Window,
-                                  Window->hrgnUpdate,
+               hDC = UserGetDCEx( Wnd,
+                                  Wnd->hrgnUpdate,
                                   DCX_CACHE|DCX_USESTYLE|DCX_INTERSECTRGN|DCX_KEEPCLIPRGN);
 
-               if (co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hDC, 0))
+               Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
+               // Kill the loop, so Clear before we send.
+               if (!co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)hDC, 0))
                {
-                  Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+                  Wnd->state |= (WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
                }
-               UserReleaseDC(Window, hDC, FALSE);
+               UserReleaseDC(Wnd, hDC, FALSE);
             }
          }
       }
@@ -295,19 +281,18 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
    {
       HWND *List, *phWnd;
 
-      if ((List = IntWinListChildren(Window)))
+      if ((List = IntWinListChildren(Wnd)))
       {
          /* FIXME: Handle WS_EX_TRANSPARENT */
          for (phWnd = List; *phWnd; ++phWnd)
          {
-            Window = UserGetWindowObject(*phWnd);
-            Wnd = Window->Wnd;
-            if (Window && (Wnd->style & WS_VISIBLE))
+            Wnd = UserGetWindowObject(*phWnd);
+            if (Wnd && (Wnd->style & WS_VISIBLE))
             {
                USER_REFERENCE_ENTRY Ref;
-               UserRefObjectCo(Window, &Ref);
-               co_IntPaintWindows(Window, Flags, TRUE);
-               UserDerefObjectCo(Window);
+               UserRefObjectCo(Wnd, &Ref);
+               co_IntPaintWindows(Wnd, Flags, TRUE);
+               UserDerefObjectCo(Wnd);
             }
          }
          ExFreePool(List);
@@ -318,18 +303,16 @@ co_IntPaintWindows(PWINDOW_OBJECT Window, ULONG Flags, BOOL Recurse)
 /*
  * IntInvalidateWindows
  *
- * Internal function used by IntRedrawWindow.
+ * Internal function used by IntRedrawWindow, UserRedrawDesktop,
+ * co_WinPosSetWindowPos, IntValidateParent, co_UserRedrawWindow.
  */
-
 VOID FASTCALL
-IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
+IntInvalidateWindows(PWND Wnd, HRGN hRgn, ULONG Flags)
 {
    INT RgnType;
-   PWND Wnd;
    BOOL HadPaintMessage, HadNCPaintMessage;
    BOOL HasPaintMessage, HasNCPaintMessage;
 
-   Wnd = Window->Wnd;
    DPRINT("IntInvalidateWindows start\n");
    /*
     * If the nonclient is not to be redrawn, clip the region to the client
@@ -339,29 +322,29 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    {
       HRGN hRgnClient;
 
-      hRgnClient = IntSysCreateRectRgnIndirect(&Window->Wnd->rcClient);
+      hRgnClient = IntSysCreateRectRgnIndirect(&Wnd->rcClient);
       RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnClient, RGN_AND);
-      REGION_FreeRgnByHandle(hRgnClient);
+      GreDeleteObject(hRgnClient);
    }
 
    /*
     * Clip the given region with window rectangle (or region)
     */
 
-   if (!Window->hrgnClip || (Wnd->style & WS_MINIMIZE))
+   if (!Wnd->hrgnClip || (Wnd->style & WS_MINIMIZE))
    {
       HRGN hRgnWindow;
 
-      hRgnWindow = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
+      hRgnWindow = IntSysCreateRectRgnIndirect(&Wnd->rcWindow);
       RgnType = NtGdiCombineRgn(hRgn, hRgn, hRgnWindow, RGN_AND);
-      REGION_FreeRgnByHandle(hRgnWindow);
+      GreDeleteObject(hRgnWindow);
    }
    else
    {
       NtGdiOffsetRgn( hRgn,
                      -Wnd->rcWindow.left,
                      -Wnd->rcWindow.top);
-      RgnType = NtGdiCombineRgn(hRgn, hRgn, Window->hrgnClip, RGN_AND);
+      RgnType = NtGdiCombineRgn(hRgn, hRgn, Wnd->hrgnClip, RGN_AND);
       NtGdiOffsetRgn( hRgn,
                       Wnd->rcWindow.left,
                       Wnd->rcWindow.top);
@@ -371,9 +354,9 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
     * Save current state of pending updates
     */
 
-   HadPaintMessage = Window->hrgnUpdate != NULL ||
+   HadPaintMessage = Wnd->hrgnUpdate != NULL ||
                      Wnd->state & WNDS_INTERNALPAINT;
-   HadNCPaintMessage = Window->state & WINDOWOBJECT_NEED_NCPAINT;
+   HadNCPaintMessage = Wnd->state & WNDS_SENDNCPAINT;
 
    /*
     * Update the region and flags
@@ -381,47 +364,47 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
 
    if (Flags & RDW_INVALIDATE && RgnType != NULLREGION)
    {
-      if (Window->hrgnUpdate == NULL)
+      if (Wnd->hrgnUpdate == NULL)
       {
-         Window->hrgnUpdate = IntSysCreateRectRgn(0, 0, 0, 0);
-         IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC);
+         Wnd->hrgnUpdate = IntSysCreateRectRgn(0, 0, 0, 0);
+         IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_PUBLIC);
       }
 
-      if (NtGdiCombineRgn(Window->hrgnUpdate, Window->hrgnUpdate,
+      if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate,
                           hRgn, RGN_OR) == NULLREGION)
       {
-         IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
-         REGION_FreeRgnByHandle(Window->hrgnUpdate);
-         Window->hrgnUpdate = NULL;
+         IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
+         GreDeleteObject(Wnd->hrgnUpdate);
+         Wnd->hrgnUpdate = NULL;
       }
 
       if (Flags & RDW_FRAME)
-         Window->state |= WINDOWOBJECT_NEED_NCPAINT;
+         Wnd->state |= WNDS_SENDNCPAINT;
       if (Flags & RDW_ERASE)
-         Window->state |= WINDOWOBJECT_NEED_ERASEBKGND;
+         Wnd->state |= WNDS_SENDERASEBACKGROUND;
 
       Flags |= RDW_FRAME;
    }
 
    if (Flags & RDW_VALIDATE && RgnType != NULLREGION)
    {
-      if (Window->hrgnUpdate != NULL)
+      if (Wnd->hrgnUpdate != NULL)
       {
-         if (NtGdiCombineRgn(Window->hrgnUpdate, Window->hrgnUpdate,
+         if (NtGdiCombineRgn(Wnd->hrgnUpdate, Wnd->hrgnUpdate,
                              hRgn, RGN_DIFF) == NULLREGION)
          {
-            IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
-            REGION_FreeRgnByHandle(Window->hrgnUpdate);
-            Window->hrgnUpdate = NULL;
+            IntGdiSetRegionOwner(Wnd->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
+            GreDeleteObject(Wnd->hrgnUpdate);
+            Wnd->hrgnUpdate = NULL;
          }
       }
 
-      if (Window->hrgnUpdate == NULL)
-         Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+      if (Wnd->hrgnUpdate == NULL)
+         Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
       if (Flags & RDW_NOFRAME)
-         Window->state &= ~WINDOWOBJECT_NEED_NCPAINT;
+         Wnd->state &= ~WNDS_SENDNCPAINT;
       if (Flags & RDW_NOERASE)
-         Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+         Wnd->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
    }
 
    if (Flags & RDW_INTERNALPAINT)
@@ -441,11 +424,11 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
    if (!(Flags & RDW_NOCHILDREN) && !(Wnd->style & WS_MINIMIZE) &&
          ((Flags & RDW_ALLCHILDREN) || !(Wnd->style & WS_CLIPCHILDREN)))
    {
-      PWINDOW_OBJECT Child;
+      PWND Child;
 
-      for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
+      for (Child = Wnd->spwndChild; Child; Child = Child->spwndNext)
       {
-         if (Child->Wnd->style & WS_VISIBLE)
+         if (Child->style & WS_VISIBLE)
          {
             /*
              * Recursive call to update children hrgnUpdate
@@ -453,7 +436,7 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
             HRGN hRgnTemp = IntSysCreateRectRgn(0, 0, 0, 0);
             NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY);
             IntInvalidateWindows(Child, hRgnTemp, Flags);
-            REGION_FreeRgnByHandle(hRgnTemp);
+            GreDeleteObject(hRgnTemp);
          }
 
       }
@@ -463,24 +446,24 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
     * Fake post paint messages to window message queue if needed
     */
 
-   HasPaintMessage = Window->hrgnUpdate != NULL ||
+   HasPaintMessage = Wnd->hrgnUpdate != NULL ||
                      Wnd->state & WNDS_INTERNALPAINT;
-   HasNCPaintMessage = Window->state & WINDOWOBJECT_NEED_NCPAINT;
+   HasNCPaintMessage = Wnd->state & WNDS_SENDNCPAINT;
 
    if (HasPaintMessage != HadPaintMessage)
    {
       if (HadPaintMessage)
-         MsqDecPaintCountQueue(Window->pti->MessageQueue);
+         MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
       else
-         MsqIncPaintCountQueue(Window->pti->MessageQueue);
+         MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue);
    }
 
    if (HasNCPaintMessage != HadNCPaintMessage)
    {
       if (HadNCPaintMessage)
-         MsqDecPaintCountQueue(Window->pti->MessageQueue);
+         MsqDecPaintCountQueue(Wnd->head.pti->MessageQueue);
       else
-         MsqIncPaintCountQueue(Window->pti->MessageQueue);
+         MsqIncPaintCountQueue(Wnd->head.pti->MessageQueue);
    }
    DPRINT("IntInvalidateWindows exit\n");
 }
@@ -494,19 +477,17 @@ IntInvalidateWindows(PWINDOW_OBJECT Window, HRGN hRgn, ULONG Flags)
  */
 
 BOOL FASTCALL
-IntIsWindowDrawable(PWINDOW_OBJECT Window)
+IntIsWindowDrawable(PWND Wnd)
 {
-   PWINDOW_OBJECT WndObject;
-   PWND Wnd;
+   PWND WndObject;
 
-   for (WndObject = Window; WndObject != NULL; WndObject = WndObject->spwndParent)
+   for (WndObject = Wnd; WndObject != NULL; WndObject = WndObject->spwndParent)
    {
-      Wnd = WndObject->Wnd;
-      if ( Window->state & WINDOWSTATUS_DESTROYING || // state2
-           Window->state & WINDOWSTATUS_DESTROYED ||
-           !Wnd ||
-           !(Wnd->style & WS_VISIBLE) ||
-            ((Wnd->style & WS_MINIMIZE) && (WndObject != Window)))
+      if ( WndObject->state2 & WNDS2_INDESTROY ||
+           WndObject->state & WNDS_DESTROYED ||
+           !WndObject ||
+           !(WndObject->style & WS_VISIBLE) ||
+            ((WndObject->style & WS_MINIMIZE) && (WndObject != Wnd)))
       {
          return FALSE;
       }
@@ -518,13 +499,13 @@ IntIsWindowDrawable(PWINDOW_OBJECT Window)
 /*
  * IntRedrawWindow
  *
- * Internal version of NtUserRedrawWindow that takes WINDOW_OBJECT as
+ * Internal version of NtUserRedrawWindow that takes WND as
  * first parameter.
  */
 
 BOOL FASTCALL
 co_UserRedrawWindow(
-   PWINDOW_OBJECT Window,
+   PWND Window,
    const RECTL* UpdateRect,
    HRGN UpdateRgn,
    ULONG Flags)
@@ -555,30 +536,30 @@ co_UserRedrawWindow(
          hRgn = IntSysCreateRectRgn(0, 0, 0, 0);
          if (NtGdiCombineRgn(hRgn, UpdateRgn, NULL, RGN_COPY) == NULLREGION)
          {
-            REGION_FreeRgnByHandle(hRgn);
+            GreDeleteObject(hRgn);
             hRgn = NULL;
          }
          else
-            NtGdiOffsetRgn(hRgn, Window->Wnd->rcClient.left, Window->Wnd->rcClient.top);
+            NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top);
       }
       else if (UpdateRect != NULL)
       {
          if (!RECTL_bIsEmptyRect(UpdateRect))
          {
             hRgn = IntSysCreateRectRgnIndirect((RECTL *)UpdateRect);
-            NtGdiOffsetRgn(hRgn, Window->Wnd->rcClient.left, Window->Wnd->rcClient.top);
+            NtGdiOffsetRgn(hRgn, Window->rcClient.left, Window->rcClient.top);
          }
       }
       else if ((Flags & (RDW_INVALIDATE | RDW_FRAME)) == (RDW_INVALIDATE | RDW_FRAME) ||
                (Flags & (RDW_VALIDATE | RDW_NOFRAME)) == (RDW_VALIDATE | RDW_NOFRAME))
       {
-         if (!RECTL_bIsEmptyRect(&Window->Wnd->rcWindow))
-            hRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcWindow);
+         if (!RECTL_bIsEmptyRect(&Window->rcWindow))
+            hRgn = IntSysCreateRectRgnIndirect(&Window->rcWindow);
       }
       else
       {
-         if (!RECTL_bIsEmptyRect(&Window->Wnd->rcClient))
-            hRgn = IntSysCreateRectRgnIndirect(&Window->Wnd->rcClient);
+         if (!RECTL_bIsEmptyRect(&Window->rcClient))
+            hRgn = IntSysCreateRectRgnIndirect(&Window->rcClient);
       }
    }
 
@@ -610,7 +591,7 @@ co_UserRedrawWindow(
 
    if (hRgn != NULL)
    {
-      REGION_FreeRgnByHandle(hRgn);
+      GreDeleteObject(hRgn);
    }
    DPRINT("co_UserRedrawWindow exit\n");
 
@@ -618,45 +599,41 @@ co_UserRedrawWindow(
 }
 
 BOOL FASTCALL
-IntIsWindowDirty(PWINDOW_OBJECT Window)
+IntIsWindowDirty(PWND Wnd)
 {
-   PWND Wnd = Window->Wnd;
    return (Wnd->style & WS_VISIBLE) &&
-          ((Window->hrgnUpdate != NULL) ||
+          ((Wnd->hrgnUpdate != NULL) ||
            (Wnd->state & WNDS_INTERNALPAINT) ||
-           (Window->state & WINDOWOBJECT_NEED_NCPAINT));
+           (Wnd->state & WNDS_SENDNCPAINT));
 }
 
 HWND FASTCALL
-IntFindWindowToRepaint(PWINDOW_OBJECT Window, PTHREADINFO Thread)
+IntFindWindowToRepaint(PWND Window, PTHREADINFO Thread)
 {
    HWND hChild;
-   PWINDOW_OBJECT TempWindow;
-   PWND Wnd, TempWnd;
+   PWND TempWindow;
 
    for (; Window != NULL; Window = Window->spwndNext)
    {
-      Wnd = Window->Wnd;
       if (IntWndBelongsToThread(Window, Thread) &&
           IntIsWindowDirty(Window))
       {
          /* Make sure all non-transparent siblings are already drawn. */
-         if (Wnd->ExStyle & WS_EX_TRANSPARENT)
+         if (Window->ExStyle & WS_EX_TRANSPARENT)
          {
             for (TempWindow = Window->spwndNext; TempWindow != NULL;
                  TempWindow = TempWindow->spwndNext)
             {
-               TempWnd = TempWindow->Wnd;
-               if (!(TempWnd->ExStyle & WS_EX_TRANSPARENT) &&
+               if (!(TempWindow->ExStyle & WS_EX_TRANSPARENT) &&
                    IntWndBelongsToThread(TempWindow, Thread) &&
                    IntIsWindowDirty(TempWindow))
                {
-                  return TempWindow->hSelf;
+                  return TempWindow->head.h;
                }
             }
          }
 
-         return Window->hSelf;
+         return Window->head.h;
       }
 
       if (Window->spwndChild)
@@ -672,16 +649,14 @@ IntFindWindowToRepaint(PWINDOW_OBJECT Window, PTHREADINFO Thread)
 
 BOOL FASTCALL
 IntGetPaintMessage(
-   PWINDOW_OBJECT Window,
+   PWND Window,
    UINT MsgFilterMin,
    UINT MsgFilterMax,
    PTHREADINFO Thread,
    MSG *Message,
    BOOL Remove)
 {
-   PUSER_MESSAGE_QUEUE MessageQueue = (PUSER_MESSAGE_QUEUE)Thread->MessageQueue;
-
-   if (!MessageQueue->PaintCount)
+   if (!Thread->cPaintsReady)
       return FALSE;
 
    if ((MsgFilterMin != 0 || MsgFilterMax != 0) &&
@@ -692,13 +667,13 @@ IntGetPaintMessage(
 
    if (Message->hwnd == NULL)
    {
-      DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found!\n");
+      DPRINT1("PAINTING BUG: Thread marked as containing dirty windows, but no dirty windows found! Counts %d\n",Thread->cPaintsReady);
       /* Hack to stop spamming the debuglog ! */
-      MessageQueue->PaintCount = 0;
+      Thread->cPaintsReady = 0;
       return FALSE;
    }
 
-   if (Window != NULL && Message->hwnd != Window->hSelf)
+   if (Window != NULL && Message->hwnd != Window->head.h)
       return FALSE;
 
    Message->message = WM_PAINT;
@@ -709,17 +684,22 @@ IntGetPaintMessage(
 
 static
 HWND FASTCALL
-co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
+co_IntFixCaret(PWND Window, RECTL *lprc, UINT flags)
 {
    PDESKTOP Desktop;
    PTHRDCARETINFO CaretInfo;
+   PTHREADINFO pti;
+   PUSER_MESSAGE_QUEUE ActiveMessageQueue;
    HWND hWndCaret;
-   PWINDOW_OBJECT WndCaret;
+   PWND WndCaret;
 
    ASSERT_REFS_CO(Window);
 
-   Desktop = ((PTHREADINFO)PsGetCurrentThread()->Tcb.Win32Thread)->rpdesk;
-   CaretInfo = ((PUSER_MESSAGE_QUEUE)Desktop->ActiveMessageQueue)->CaretInfo;
+   pti = PsGetCurrentThreadWin32Thread();
+   Desktop = pti->rpdesk;
+   ActiveMessageQueue = Desktop->ActiveMessageQueue;
+   if (!ActiveMessageQueue) return 0;
+   CaretInfo = ActiveMessageQueue->CaretInfo;
    hWndCaret = CaretInfo->hWnd;
 
    WndCaret = UserGetWindowObject(hWndCaret);
@@ -728,15 +708,13 @@ co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
    if (WndCaret == Window ||
          ((flags & SW_SCROLLCHILDREN) && IntIsChildWindow(Window, WndCaret)))
    {
-      POINT pt, FromOffset, ToOffset, Offset;
+      POINT pt, FromOffset, ToOffset;
       RECTL rcCaret;
 
       pt.x = CaretInfo->Pos.x;
       pt.y = CaretInfo->Pos.y;
       IntGetClientOrigin(WndCaret, &FromOffset);
       IntGetClientOrigin(Window, &ToOffset);
-      Offset.x = FromOffset.x - ToOffset.x;
-      Offset.y = FromOffset.y - ToOffset.y;
       rcCaret.left = pt.x;
       rcCaret.top = pt.y;
       rcCaret.right = pt.x + CaretInfo->Size.cx;
@@ -753,6 +731,58 @@ co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
    return 0;
 }
 
+BOOL
+FASTCALL
+IntPrintWindow(
+    PWND pwnd,
+    HDC hdcBlt,
+    UINT nFlags)
+{
+    HDC hdcSrc;
+    INT cx, cy, xSrc, ySrc;
+
+    if ( nFlags & PW_CLIENTONLY)
+    {
+       cx = pwnd->rcClient.right - pwnd->rcClient.left;
+       cy = pwnd->rcClient.bottom - pwnd->rcClient.top;
+       xSrc = pwnd->rcClient.left - pwnd->rcWindow.left;
+       ySrc = pwnd->rcClient.top - pwnd->rcWindow.top;
+    }
+    else
+    {
+       cx = pwnd->rcWindow.right - pwnd->rcWindow.left;
+       cy = pwnd->rcWindow.bottom - pwnd->rcWindow.top;
+       xSrc = 0;
+       ySrc = 0;
+    }
+
+    // TODO: Setup Redirection for Print.
+    return FALSE;
+
+    /* Update the window just incase. */
+    co_IntPaintWindows( pwnd, RDW_ERASENOW|RDW_UPDATENOW, FALSE);
+
+    hdcSrc = UserGetDCEx( pwnd, NULL, DCX_CACHE|DCX_WINDOW);
+    /* Print window to printer context. */
+    NtGdiBitBlt( hdcBlt,
+                 0,
+                 0,
+                 cx,
+                 cy,
+                 hdcSrc,
+                 xSrc,
+                 ySrc,
+                 SRCCOPY,
+                 0,
+                 0);
+
+    UserReleaseDC( pwnd, hdcSrc, FALSE);
+
+    // TODO: Release Redirection from Print.
+
+    return TRUE;
+}
+
 /* PUBLIC FUNCTIONS ***********************************************************/
 
 /*
@@ -765,12 +795,11 @@ co_IntFixCaret(PWINDOW_OBJECT Window, RECTL *lprc, UINT flags)
 HDC APIENTRY
 NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
 {
-   PWINDOW_OBJECT Window = NULL;
+   PWND Window = NULL;
    PAINTSTRUCT Ps;
    NTSTATUS Status;
    DECLARE_RETURN(HDC);
    USER_REFERENCE_ENTRY Ref;
-   PWND Wnd;
 
    DPRINT("Enter NtUserBeginPaint\n");
    UserEnterExclusive();
@@ -782,22 +811,20 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
 
    UserRefObjectCo(Window, &Ref);
 
-   Wnd = Window->Wnd;
-
    co_UserHideCaret(Window);
 
-   if (Window->state & WINDOWOBJECT_NEED_NCPAINT)
+   if (Window->state & WNDS_SENDNCPAINT)
    {
       HRGN hRgn;
 
       hRgn = IntGetNCUpdateRgn(Window, FALSE);
-      Window->state &= ~WINDOWOBJECT_NEED_NCPAINT;
-      MsqDecPaintCountQueue(Window->pti->MessageQueue);
+      Window->state &= ~WNDS_SENDNCPAINT;
+      MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
       co_IntSendMessage(hWnd, WM_NCPAINT, (WPARAM)hRgn, 0);
-      if (hRgn != (HANDLE)1 && hRgn != NULL)
+      if (hRgn != HRGN_WINDOW && hRgn != NULL && GreIsHandleValid(hRgn))
       {
          /* NOTE: The region can already by deleted! */
-         GDIOBJ_FreeObjByHandle(hRgn, GDI_OBJECT_TYPE_REGION | GDI_OBJECT_TYPE_SILENT);
+         GreDeleteObject(hRgn);
       }
    }
 
@@ -813,7 +840,7 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
 
    if (Window->hrgnUpdate != NULL)
    {
-      MsqDecPaintCountQueue(Window->pti->MessageQueue);
+      MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
       GdiGetClipBox(Ps.hdc, &Ps.rcPaint);
       IntGdiSetRegionOwner(Window->hrgnUpdate, GDI_OBJ_HMGR_POWNED);
       /* The region is part of the dc now and belongs to the process! */
@@ -821,18 +848,22 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
    }
    else
    {
-      if (Wnd->state & WNDS_INTERNALPAINT)
-         MsqDecPaintCountQueue(Window->pti->MessageQueue);
+      if (Window->state & WNDS_INTERNALPAINT)
+         MsqDecPaintCountQueue(Window->head.pti->MessageQueue);
 
       IntGetClientRect(Window, &Ps.rcPaint);
    }
 
-   Wnd->state &= ~WNDS_INTERNALPAINT;
+   Window->state &= ~WNDS_INTERNALPAINT;
 
-   if (Window->state & WINDOWOBJECT_NEED_ERASEBKGND)
+   if (Window->state & WNDS_SENDERASEBACKGROUND)
    {
-      Window->state &= ~WINDOWOBJECT_NEED_ERASEBKGND;
+      Window->state &= ~(WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
       Ps.fErase = !co_IntSendMessage(hWnd, WM_ERASEBKGND, (WPARAM)Ps.hdc, 0);
+      if ( Ps.fErase )
+      {
+         Window->state |= (WNDS_SENDERASEBACKGROUND|WNDS_ERASEBACKGROUND);
+      }
    }
    else
    {
@@ -840,9 +871,9 @@ NtUserBeginPaint(HWND hWnd, PAINTSTRUCT* UnsafePs)
    }
    if (Window->hrgnUpdate)
    {
-      if (!(Wnd->style & WS_CLIPCHILDREN))
+      if (!(Window->style & WS_CLIPCHILDREN))
       {
-         PWINDOW_OBJECT Child;
+         PWND Child;
          for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
          {
             IntInvalidateWindows(Child, Window->hrgnUpdate, RDW_FRAME | RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
@@ -879,7 +910,7 @@ BOOL APIENTRY
 NtUserEndPaint(HWND hWnd, CONST PAINTSTRUCT* pUnsafePs)
 {
    NTSTATUS Status = STATUS_SUCCESS;
-   PWINDOW_OBJECT Window;
+   PWND Window;
    DECLARE_RETURN(BOOL);
    USER_REFERENCE_ENTRY Ref;
    HDC hdc = NULL;
@@ -923,7 +954,7 @@ CLEANUP:
 
 
 INT FASTCALL
-co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
+co_UserGetUpdateRgn(PWND Window, HRGN hRgn, BOOL bErase)
 {
    int RegionType;
    RECTL Rect;
@@ -936,11 +967,11 @@ co_UserGetUpdateRgn(PWINDOW_OBJECT Window, HRGN hRgn, BOOL bErase)
    }
    else
    {
-      Rect = Window->Wnd->rcClient;
+      Rect = Window->rcClient;
       IntIntersectWithParents(Window, &Rect);
       NtGdiSetRectRgn(hRgn, Rect.left, Rect.top, Rect.right, Rect.bottom);
       RegionType = NtGdiCombineRgn(hRgn, hRgn, Window->hrgnUpdate, RGN_AND);
-      NtGdiOffsetRgn(hRgn, -Window->Wnd->rcClient.left, -Window->Wnd->rcClient.top);
+      NtGdiOffsetRgn(hRgn, -Window->rcClient.left, -Window->rcClient.top);
    }
 
    if (bErase && RegionType != NULLREGION && RegionType != ERROR)
@@ -962,7 +993,7 @@ INT APIENTRY
 NtUserGetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase)
 {
    DECLARE_RETURN(INT);
-   PWINDOW_OBJECT Window;
+   PWND Window;
    INT ret;
    USER_REFERENCE_ENTRY Ref;
 
@@ -996,7 +1027,7 @@ CLEANUP:
 BOOL APIENTRY
 NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
 {
-   PWINDOW_OBJECT Window;
+   PWND Window;
    RECTL Rect;
    INT RegionType;
    PROSRGNDATA RgnData;
@@ -1018,9 +1049,9 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
    else
    {
       /* Get the update region bounding box. */
-      if (Window->hrgnUpdate == (HRGN)1)
+      if (Window->hrgnUpdate == HRGN_WINDOW)
       {
-         Rect = Window->Wnd->rcClient;
+         Rect = Window->rcClient;
       }
       else
       {
@@ -1030,14 +1061,14 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
          RGNOBJAPI_Unlock(RgnData);
 
          if (RegionType != ERROR && RegionType != NULLREGION)
-            RECTL_bIntersectRect(&Rect, &Rect, &Window->Wnd->rcClient);
+            RECTL_bIntersectRect(&Rect, &Rect, &Window->rcClient);
       }
 
       if (IntIntersectWithParents(Window, &Rect))
       {
          RECTL_vOffsetRect(&Rect,
-                          -Window->Wnd->rcClient.left,
-                          -Window->Wnd->rcClient.top);
+                          -Window->rcClient.left,
+                          -Window->rcClient.top);
       } else
       {
          Rect.left = Rect.top = Rect.right = Rect.bottom = 0;
@@ -1057,7 +1088,7 @@ NtUserGetUpdateRect(HWND hWnd, LPRECT UnsafeRect, BOOL bErase)
       Status = MmCopyToCaller(UnsafeRect, &Rect, sizeof(RECTL));
       if (!NT_SUCCESS(Status))
       {
-         SetLastWin32Error(ERROR_INVALID_PARAMETER);
+         EngSetLastError(ERROR_INVALID_PARAMETER);
          RETURN(FALSE);
       }
    }
@@ -1085,7 +1116,7 @@ NtUserRedrawWindow(
    UINT flags)
 {
    RECTL SafeUpdateRect;
-   PWINDOW_OBJECT Wnd;
+   PWND Wnd;
    BOOL Ret;
    USER_REFERENCE_ENTRY Ref;
    NTSTATUS Status = STATUS_SUCCESS;
@@ -1113,7 +1144,7 @@ NtUserRedrawWindow(
       _SEH2_END
       if (!NT_SUCCESS(Status))
       {
-         SetLastWin32Error(RtlNtStatusToDosError(Status));
+         EngSetLastError(RtlNtStatusToDosError(Status));
          RETURN( FALSE);
       }
    }
@@ -1123,7 +1154,7 @@ NtUserRedrawWindow(
                   RDW_ERASENOW|RDW_UPDATENOW|RDW_ALLCHILDREN|RDW_NOCHILDREN) )
    {
       /* RedrawWindow fails only in case that flags are invalid */
-      SetLastWin32Error(ERROR_INVALID_FLAGS);
+      EngSetLastError(ERROR_INVALID_FLAGS);
       RETURN( FALSE);
    }
 
@@ -1199,14 +1230,14 @@ UserScrollDC(
       could not be copied, because it was not visible */
    if (hrgnUpdate || prcUpdate)
    {
-      HRGN hrgnOwn, hrgnVisible, hrgnTmp;
+      HRGN hrgnOwn, hrgnTmp;
+      PREGION prgnTmp;
 
       pDC = DC_LockDc(hDC);
       if (!pDC)
       {
          return FALSE;
       }
-      hrgnVisible = ((PROSRGNDATA)pDC->prgnVis)->BaseObject.hHmgr;  // pDC->prgnRao?
 
       /* Begin with the shifted and then clipped scroll rect */
       rcDst = rcScroll;
@@ -1217,6 +1248,7 @@ UserScrollDC(
          hrgnOwn = hrgnUpdate;
          if (!NtGdiSetRectRgn(hrgnOwn, rcDst.left, rcDst.top, rcDst.right, rcDst.bottom))
          {
+            DC_UnlockDc(pDC);
             return ERROR;
          }
       }
@@ -1230,14 +1262,16 @@ UserScrollDC(
       NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_OR);
 
       /* Substract the part of the dest that was visible in source */
-      NtGdiCombineRgn(hrgnTmp, hrgnTmp, hrgnVisible, RGN_AND);
+      prgnTmp = RGNOBJAPI_Lock(hrgnTmp, NULL);
+      IntGdiCombineRgn(prgnTmp, prgnTmp, pDC->prgnVis, RGN_AND);
+      RGNOBJAPI_Unlock(prgnTmp);
       NtGdiOffsetRgn(hrgnTmp, dx, dy);
       Result = NtGdiCombineRgn(hrgnOwn, hrgnOwn, hrgnTmp, RGN_DIFF);
 
-         /* DO NOT Unlock DC while messing with prgnVis! */
-         DC_UnlockDc(pDC);
+      /* DO NOT Unlock DC while messing with prgnVis! */
+      DC_UnlockDc(pDC);
 
-      REGION_FreeRgnByHandle(hrgnTmp);
+      GreDeleteObject(hrgnTmp);
 
       if (prcUpdate)
       {
@@ -1246,7 +1280,7 @@ UserScrollDC(
 
       if (!hrgnUpdate)
       {
-         REGION_FreeRgnByHandle(hrgnOwn);
+         GreDeleteObject(hrgnOwn);
       }
    }
    else
@@ -1367,7 +1401,7 @@ NtUserScrollWindowEx(
 {
    RECTL rcScroll, rcClip, rcCaret, rcUpdate;
    INT Result;
-   PWINDOW_OBJECT Window = NULL, CaretWnd;
+   PWND Window = NULL, CaretWnd;
    HDC hDC;
    HRGN hrgnOwn = NULL, hrgnTemp;
    HWND hwndCaret;
@@ -1459,13 +1493,13 @@ NtUserScrollWindowEx(
       NtGdiOffsetRgn(hrgnTemp, dx, dy);
       NtGdiCombineRgn(hrgnTemp, hrgnTemp, hrgnClip, RGN_AND);
       co_UserRedrawWindow(Window, NULL, hrgnTemp, RDW_INVALIDATE | RDW_ERASE);
-      REGION_FreeRgnByHandle(hrgnClip);
+      GreDeleteObject(hrgnClip);
    }
-   REGION_FreeRgnByHandle(hrgnTemp);
+   GreDeleteObject(hrgnTemp);
 
    if (flags & SW_SCROLLCHILDREN)
    {
-      PWINDOW_OBJECT Child;
+      PWND Child;
       RECTL rcChild;
       POINT ClientOrigin;
       USER_REFERENCE_ENTRY WndRef;
@@ -1474,7 +1508,7 @@ NtUserScrollWindowEx(
       IntGetClientOrigin(Window, &ClientOrigin);
       for (Child = Window->spwndChild; Child; Child = Child->spwndNext)
       {
-         rcChild = Child->Wnd->rcWindow;
+         rcChild = Child->rcWindow;
          rcChild.left -= ClientOrigin.x;
          rcChild.top -= ClientOrigin.y;
          rcChild.right -= ClientOrigin.x;
@@ -1534,7 +1568,7 @@ NtUserScrollWindowEx(
 CLEANUP:
    if (hrgnOwn && !hrgnUpdate)
    {
-      REGION_FreeRgnByHandle(hrgnOwn);
+      GreDeleteObject(hrgnOwn);
    }
 
    if (Window)
@@ -1548,7 +1582,7 @@ CLEANUP:
 
 BOOL
 UserDrawSysMenuButton(
-   PWINDOW_OBJECT pWnd,
+   PWND pWnd,
    HDC hDc,
    RECTL *lpRc,
    BOOL Down)
@@ -1560,12 +1594,12 @@ UserDrawSysMenuButton(
 
    /* Get the icon to draw. We don't care about WM_GETICON here. */
 
-   hIcon = pWnd->Wnd->pcls->hIconSm;
+   hIcon = pWnd->pcls->hIconSm;
 
    if(!hIcon)
    {
       DPRINT("Wnd class has no small icon.\n");
-      hIcon = pWnd->Wnd->pcls->hIcon;
+      hIcon = pWnd->pcls->hIcon;
    }
 
    if(!hIcon)
@@ -1654,7 +1688,7 @@ UserDrawCaptionText(
 }
 
 BOOL UserDrawCaption(
-   PWINDOW_OBJECT pWnd,
+   PWND pWnd,
    HDC hDc,
    RECTL *lpRc,
    HFONT hFont,
@@ -1671,13 +1705,9 @@ BOOL UserDrawCaption(
    RECTL r = *lpRc;
    LONG ButtonWidth, IconWidth;
    BOOL HasIcon;
-   PWND Wnd = NULL;
 
    //ASSERT(pWnd != NULL);
 
-   if (pWnd)
-       Wnd = pWnd->Wnd;
-
    RECTL_vMakeWellOrdered(lpRc);
    hMemBmp = NtGdiCreateCompatibleBitmap(hDc,
       lpRc->right - lpRc->left,
@@ -1707,11 +1737,11 @@ BOOL UserDrawCaption(
    VCenter = (lpRc->bottom - lpRc->top) / 2;
    Padding = VCenter - (Height / 2);
 
-   if ((!hIcon) && (Wnd != NULL))
+   if ((!hIcon) && (pWnd != NULL))
    {
-     HasIcon = (uFlags & DC_ICON) && (Wnd->style & WS_SYSMENU)
-        && !(uFlags & DC_SMALLCAP) && !(Wnd->ExStyle & WS_EX_DLGMODALFRAME)
-        && !(Wnd->ExStyle & WS_EX_TOOLWINDOW);
+     HasIcon = (uFlags & DC_ICON) && (pWnd->style & WS_SYSMENU)
+        && !(uFlags & DC_SMALLCAP) && !(pWnd->ExStyle & WS_EX_DLGMODALFRAME)
+        && !(pWnd->ExStyle & WS_EX_TOOLWINDOW);
    }
    else
      HasIcon = (hIcon != 0);
@@ -1785,14 +1815,14 @@ BOOL UserDrawCaption(
          TRIVERTEX vert[2];
          COLORREF Colors[2];
 
-                if (Wnd != NULL)
+                if (pWnd != NULL)
                 {
-                        if(Wnd->style & WS_SYSMENU)
+                        if(pWnd->style & WS_SYSMENU)
                         {
                                r.right -= 3 + ButtonWidth;
                                if(!(uFlags & DC_SMALLCAP))
                                {
-                                  if(Wnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+                                  if(pWnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
                                          r.right -= 2 + 2 * ButtonWidth;
                                   else r.right -= 2;
                                   r.right -= 2;
@@ -1872,12 +1902,12 @@ BOOL UserDrawCaption(
             ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
          else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;
 
-         if ((Wnd != NULL) && (Wnd->style & WS_SYSMENU))
+         if ((pWnd != NULL) && (pWnd->style & WS_SYSMENU))
          {
             r.right -= 3 + ButtonWidth;
             if(! (uFlags & DC_SMALLCAP))
             {
-               if(Wnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+               if(pWnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
                   r.right -= 2 + 2 * ButtonWidth;
                else r.right -= 2;
                r.right -= 2;
@@ -1891,9 +1921,9 @@ BOOL UserDrawCaption(
       else if (pWnd != NULL)
       {
          UNICODE_STRING ustr;
-         ustr.Buffer = pWnd->Wnd->strName.Buffer;
-         ustr.Length = pWnd->Wnd->strName.Length;
-         ustr.MaximumLength = pWnd->Wnd->strName.MaximumLength;
+         ustr.Buffer = pWnd->strName.Buffer;
+         ustr.Length = pWnd->strName.Length;
+         ustr.MaximumLength = pWnd->strName.MaximumLength;
          UserDrawCaptionText(hMemDc, &ustr, &r, uFlags);
       }
    }
@@ -1930,7 +1960,7 @@ UserRealizePalette(HDC hdc)
       hWnd = IntWindowFromDC(hdc);
       if (hWnd) // Send broadcast if dc is associated with a window.
       {  // FYI: Thread locked in CallOneParam.
-         co_IntSendMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
+         UserSendNotifyMessage((HWND)HWND_BROADCAST, WM_PALETTECHANGED, (WPARAM)hWnd, 0);
       }
   }
   return Ret;
@@ -1947,7 +1977,7 @@ NtUserDrawCaptionTemp(
    const PUNICODE_STRING str,
    UINT uFlags)
 {
-   PWINDOW_OBJECT pWnd = NULL;
+   PWND pWnd = NULL;
    UNICODE_STRING SafeStr = {0};
    NTSTATUS Status = STATUS_SUCCESS;
    RECTL SafeRect;
@@ -2031,6 +2061,36 @@ NtUserInvalidateRgn(
     return NtUserRedrawWindow(hWnd, NULL, hRgn, RDW_INVALIDATE | (bErase? RDW_ERASE : 0));
 }
 
+BOOL
+APIENTRY
+NtUserPrintWindow(
+    HWND hwnd,
+    HDC  hdcBlt,
+    UINT nFlags)
+{
+    PWND Window;
+    BOOL Ret = FALSE;
+
+    UserEnterExclusive();
+
+    if (hwnd)
+    {
+       Window = UserGetWindowObject(hwnd);
+       // TODO: Add Desktop and MessageBox check via FNID's.
+       if ( Window )
+       {
+          /* Validate flags and check it as a mask for 0 or 1. */
+          if ( (nFlags & PW_CLIENTONLY) == nFlags)
+             Ret = IntPrintWindow( Window, hdcBlt, nFlags);
+          else
+             EngSetLastError(ERROR_INVALID_PARAMETER);
+       }
+    }
+
+    UserLeave();
+    return Ret;
+}
+
 /* ValidateRect gets redirected to NtUserValidateRect:
    http://blog.csdn.net/ntdll/archive/2005/10/19/509299.aspx */
 BOOL