Index: include/reactos/undocuser.h
===================================================================
--- include/reactos/undocuser.h	(revision 68595)
+++ include/reactos/undocuser.h	(working copy)
@@ -132,7 +132,9 @@
 //
 // Undocumented flags for DrawCaptionTemp
 //
+#define DC_NOVISIBLE 0x0800
 #define DC_NOSENDMSG 0x2000
+#define DC_FRAME     0x8000  // Missing from WinUser.H!
 
 #define STARTF_SCRNSAVER 0x80000000
 
Index: win32ss/user/ntuser/defwnd.c
===================================================================
--- win32ss/user/ntuser/defwnd.c	(revision 68595)
+++ win32ss/user/ntuser/defwnd.c	(working copy)
@@ -362,7 +362,40 @@
     co_IntSendMessage(UserHMGetHandle(pwnd), WM_PRINTCLIENT, (WPARAM)hdc, uFlags);
 }
 
+BOOL
+UserPaintCaption(PWND pWnd, INT Flags)
+{
+  BOOL Ret = FALSE;
 
+  if ( pWnd->style & WS_VISIBLE && (pWnd->style & WS_CAPTION) == WS_CAPTION )
+  {
+    /* 
+     * When themes are not enabled we can go on and paint the non client area.
+     * However if we do that with themes enabled we will draw a classic frame.
+     * This is sovled by sending a themes specific message to notify the themes
+     * engine that the caption needs to be redrawn 
+     */
+      if (gpsi->dwSRVIFlags & SRVINFO_APIHOOK)
+      {
+        /* 
+         * This will cause uxtheme to either paint the themed caption or call
+         * RealUserDrawCaption in order to draw the classic caption when themes
+         * are disabled but the themes service is enabled
+         */
+         co_IntSendMessage(UserHMGetHandle(pWnd), WM_NCUAHDRAWCAPTION, Flags, 0);
+      }
+      else
+      {
+         HDC hDC = UserGetDCEx(pWnd, NULL, DCX_WINDOW|DCX_USESTYLE);
+         UserDrawCaptionBar(pWnd, hDC, Flags);
+         UserReleaseDC(pWnd, hDC, FALSE);
+      }
+      Ret = TRUE;
+   }
+   // Support window tray
+   return Ret;
+}
+
 /*
    Win32k counterpart of User DefWindowProc
  */
@@ -607,6 +640,53 @@
           return (DefWndHandleWindowPosChanged(Wnd, (WINDOWPOS*)lParam));
       }
 
+      case WM_NCCALCSIZE:
+      {
+         return NC_HandleNCCalcSize( Wnd, wParam, (RECTL *)lParam );
+      }
+
+      case WM_NCACTIVATE:
+      {
+          return NC_HandleNCActivate( Wnd, wParam, lParam );
+      }
+
+      //
+      // NC Paint mode.
+      //
+      case WM_NCPAINT:
+      {
+          HDC hDC = UserGetDCEx(Wnd, (HRGN)wParam, DCX_WINDOW | DCX_INTERSECTRGN | DCX_USESTYLE | DCX_KEEPCLIPRGN);
+          Wnd->state |= WNDS_FORCEMENUDRAW;
+          NC_DoNCPaint(Wnd, hDC, -1);
+          Wnd->state &= ~WNDS_FORCEMENUDRAW;
+          UserReleaseDC(Wnd, hDC, FALSE);
+          return 0;
+      }
+      //
+      //  Draw Caption mode.
+      //
+      //  wParam is DC_* flags.
+      //
+      case WM_NCUAHDRAWCAPTION:
+      {
+          HDC hDC = UserGetDCEx(Wnd, NULL, DCX_WINDOW|DCX_USESTYLE);
+          TRACE("WM_NCUAHDRAWCAPTION: wParam DC_ flags %d\n");
+          UserDrawCaptionBar(Wnd, hDC, wParam);
+          UserReleaseDC(Wnd, hDC, FALSE);
+          return 0;
+      }
+      //
+      //  Draw Frame mode.
+      //
+      //  wParam is HDC, lParam is DC_ACTIVE and or DCF_REDRAWHUNGWND.
+      //
+      case WM_NCUAHDRAWFRAME:
+      {
+          TRACE("WM_NCUAHDRAWFRAME: wParam hDC %p lParam DC_ flags %d\n",wParam,lParam);
+          NC_DoNCPaint(Wnd, (HDC)wParam, lParam|DC_NC);
+          return 0;
+      }
+
       /* ReactOS only. */
       case WM_CBT:
       {
Index: win32ss/user/ntuser/menu.c
===================================================================
--- win32ss/user/ntuser/menu.c	(revision 68595)
+++ win32ss/user/ntuser/menu.c	(working copy)
@@ -11,6 +11,9 @@
 
 /* INTERNAL ******************************************************************/
 
+HFONT ghMenuFont = NULL;
+HFONT ghMenuFontBold = NULL;
+
 BOOL FASTCALL IntSetMenuItemInfo(PMENU, PITEM, PROSMENUITEMINFO, PUNICODE_STRING);
 
 /* maximum allowed depth of any branch in the menu tree.
@@ -269,6 +272,45 @@
    return FALSE;
 }
 
+BOOL
+MenuInit(VOID)
+{
+  NONCLIENTMETRICSW ncm;
+
+  /* get the menu font */
+  if(!ghMenuFont || !ghMenuFontBold)
+  {
+    ncm.cbSize = sizeof(ncm);
+    if(!UserSystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
+    {
+      ERR("MenuInit(): SystemParametersInfo(SPI_GETNONCLIENTMETRICS) failed!\n");
+      return FALSE;
+    }
+
+    ERR("Win32k MenuInit()\n");
+
+    ghMenuFont = GreCreateFontIndirectW(&ncm.lfMenuFont);
+    if (ghMenuFont == NULL)
+    {
+      ERR("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
+      return FALSE;
+    }
+
+    ncm.lfMenuFont.lfWeight = max(ncm.lfMenuFont.lfWeight + 300, 1000);
+    ghMenuFontBold = GreCreateFontIndirectW(&ncm.lfMenuFont);
+    if (ghMenuFontBold == NULL)
+    {
+      ERR("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
+      GreDeleteObject(ghMenuFont);
+      ghMenuFont = NULL;
+      return FALSE;
+    }
+  }
+
+  return TRUE;
+}
+
+
 /**********************************************************************
  *		MENU_depth
  *
@@ -1098,6 +1140,164 @@
    return ( fByPos ) ? i : MenuItem->wID;
 }
 
+/***********************************************************************
+ *           MENU_MenuBarCalcSize
+ *
+ * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap
+ * height is off by 1 pixel which causes lengthy window relocations when
+ * active document window is maximized/restored.
+ *
+ * Calculate the size of the menu bar.
+ */
+static void MENU_MenuBarCalcSize( HDC hdc, LPRECT lprect, PMENU lppop, PWND pwndOwner )
+{
+    ITEM *lpitem;
+    UINT start, i, helpPos;
+    int orgX, orgY, maxY;
+
+    if ((lprect == NULL) || (lppop == NULL)) return;
+    if (lppop->cItems == 0) return;
+    //TRACE("lprect %p %s\n", lprect, wine_dbgstr_rect( lprect));
+    lppop->cxMenu  = lprect->right - lprect->left;
+    lppop->cyMenu = 0;
+    maxY = lprect->top+1;
+    start = 0;
+    helpPos = ~0U;
+    lppop->cxTextAlign = 0;
+    while (start < lppop->cItems)
+    {
+	lpitem = &lppop->rgItems[start];
+	orgX = lprect->left;
+	orgY = maxY;
+
+	  /* Parse items until line break or end of menu */
+	for (i = start; i < lppop->cItems; i++, lpitem++)
+	{
+	    if ((helpPos == ~0U) && (lpitem->fType & MF_RIGHTJUSTIFY)) helpPos = i;
+	    if ((i != start) &&
+		(lpitem->fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
+
+	    TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY );
+	    //debug_print_menuitem ("  item: ", lpitem, "");
+	    //MENU_CalcItemSize( hdc, lpitem, hwndOwner, orgX, orgY, TRUE, lppop );
+
+	    if (lpitem->cxItem > lprect->right)
+	    {
+		if (i != start) break;
+		else lpitem->cxItem = lprect->right;
+	    }
+	    maxY = max( maxY, lpitem->cyItem );
+	    orgX = lpitem->cxItem;
+	}
+
+	  /* Finish the line (set all items to the largest height found) */
+	while (start < i) lppop->rgItems[start++].cyItem = maxY;
+    }
+
+    lprect->bottom = maxY;
+    lppop->cyMenu = lprect->bottom - lprect->top;
+
+    /* Flush right all items between the MF_RIGHTJUSTIFY and */
+    /* the last item (if several lines, only move the last line) */
+    if (helpPos == ~0U) return;
+    lpitem = &lppop->rgItems[lppop->cItems-1];
+    orgY = lpitem->yItem;
+    orgX = lprect->right;
+    for (i = lppop->cItems - 1; i >= helpPos; i--, lpitem--) {
+        if (lpitem->yItem != orgY) break;	/* Other line */
+        if (lpitem->cxItem >= orgX) break;	/* Too far right already */
+        lpitem->xItem += orgX - lpitem->cxItem;
+        lpitem->cxItem = orgX;
+        orgX = lpitem->xItem;
+    }
+}
+
+
+DWORD WINAPI
+IntDrawMenuBarTemp(PWND pWnd, HDC hDC, LPRECT Rect, PMENU pMenu, HFONT Font)
+{
+  UINT i;
+  HFONT FontOld = NULL;
+  BOOL flat_menu = FALSE;
+
+  UserSystemParametersInfo(SPI_GETFLATMENU, 0, &flat_menu, 0);
+
+  if (!pMenu)
+  {
+      pMenu = UserGetMenuObject(UlongToHandle(pWnd->IDMenu));
+  }
+
+  if (!Font)
+  {
+      Font = ghMenuFont;
+  }
+
+  if (Rect == NULL || !pMenu)
+  {
+      return UserGetSystemMetrics(SM_CYMENU);
+  }
+
+  TRACE("(%x, %x, %p, %x, %x)\n", pWnd, hDC, Rect, pMenu, Font);
+
+  FontOld = NtGdiSelectFont(hDC, Font);
+
+  if (pMenu->cyMenu == 0)
+  {
+      MENU_MenuBarCalcSize(hDC, Rect, pMenu, pWnd);
+  }
+
+  Rect->bottom = Rect->top + pMenu->cyMenu;
+
+  FillRect(hDC, Rect, IntGetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU));
+
+  NtGdiSelectPen(hDC, NtGdiGetStockObject(DC_PEN));
+  IntSetDCPenColor(hDC, IntGetSysColor(COLOR_3DFACE));
+  GreMoveTo(hDC, Rect->left, Rect->bottom - 1, NULL);
+  NtGdiLineTo(hDC, Rect->right, Rect->bottom - 1);
+
+  if (pMenu->cItems == 0)
+  {
+      NtGdiSelectFont(hDC, FontOld);
+      return UserGetSystemMetrics(SM_CYMENU);
+  }
+
+  for (i = 0; i < pMenu->cItems; i++)
+  {
+      //MENU_DrawMenuItem(pWnd, pMenu, pWnd, DC, &pMenu->rgItems[i], pMenu->cyMenu, TRUE, ODA_DRAWENTIRE);
+  }
+
+  NtGdiSelectFont(hDC, FontOld);
+
+  return pMenu->cyMenu;
+}
+
+
+UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, PWND pWnd, BOOL suppress_draw )
+{
+    HFONT hfontOld = 0;
+    PMENU lppop = UserGetMenuObject(UlongToHandle(pWnd->IDMenu));
+
+    if (lppop == NULL || lprect == NULL)
+    {
+        return UserGetSystemMetrics(SM_CYMENU);
+    }
+
+    if (suppress_draw)
+    {
+       hfontOld = NtGdiSelectFont(hDC, ghMenuFont);
+
+       MENU_MenuBarCalcSize(hDC, lprect, lppop, pWnd);
+
+       lprect->bottom = lprect->top + lppop->cyMenu;
+
+       if (hfontOld) NtGdiSelectFont( hDC, hfontOld);
+       return lppop->cyMenu;
+    }   
+    else
+       return IntDrawMenuBarTemp(pWnd, hDC, lprect, lppop, NULL);
+}
+
+
 VOID FASTCALL
 co_IntInitTracking(PWND Window, PMENU Menu, BOOL Popup,
                    UINT Flags)
Index: win32ss/user/ntuser/menu.h
===================================================================
--- win32ss/user/ntuser/menu.h	(revision 68595)
+++ win32ss/user/ntuser/menu.h	(working copy)
@@ -51,3 +51,5 @@
 BOOL FASTCALL IntRemoveMenuItem(PMENU Menu, UINT uPosition, UINT uFlags, BOOL bRecurse);
 PITEM FASTCALL MENU_FindItem( PMENU *pmenu, UINT *nPos, UINT wFlags );
 BOOL FASTCALL IntMenuItemInfo(PMENU Menu, UINT Item, BOOL ByPosition, PROSMENUITEMINFO UnsafeItemInfo, BOOL SetOrGet, PUNICODE_STRING lpstr);
+UINT MENU_DrawMenuBar( HDC hDC, LPRECT lprect, PWND pWnd, BOOL suppress_draw );
+BOOL MenuInit(VOID);
Index: win32ss/user/ntuser/message.c
===================================================================
--- win32ss/user/ntuser/message.c	(revision 68595)
+++ win32ss/user/ntuser/message.c	(working copy)
@@ -136,6 +136,8 @@
     { WM_WINDOWPOSCHANGING, sizeof(WINDOWPOS), MMS_FLAG_READWRITE },
     { WM_SIZING, sizeof(RECT), MMS_FLAG_READWRITE },
     { WM_MOVING, sizeof(RECT), MMS_FLAG_READWRITE },
+    //{ WM_MEASUREITEM, sizeof(MEASUREITEMSTRUCT), MMS_FLAG_WRITE },
+    //{ WM_DRAWITEM, sizeof(DRAWITEMSTRUCT), MMS_FLAG_WRITE },
 };
 
 static PMSGMEMORY FASTCALL
Index: win32ss/user/ntuser/nonclient.c
===================================================================
--- win32ss/user/ntuser/nonclient.c	(revision 68595)
+++ win32ss/user/ntuser/nonclient.c	(working copy)
@@ -31,7 +31,14 @@
 #define ON_BOTTOM_BORDER(hit) \
  (((hit) == HTBOTTOM) || ((hit) == HTBOTTOMLEFT) || ((hit) == HTBOTTOMRIGHT))
 
+#define HASSIZEGRIP(Style, ExStyle, ParentStyle, WindowRect, ParentClientRect) \
+            ((!(Style & WS_CHILD) && (Style & WS_THICKFRAME) && !(Style & WS_MAXIMIZE))  || \
+             ((Style & WS_CHILD) && (ParentStyle & WS_THICKFRAME) && !(ParentStyle & WS_MAXIMIZE) && \
+             (WindowRect.right - WindowRect.left == ParentClientRect.right) && \
+             (WindowRect.bottom - WindowRect.top == ParentClientRect.bottom)))
 
+
+
 VOID FASTCALL
 UserDrawWindowFrame(HDC hdc,
                     RECTL *rect,
@@ -598,6 +605,732 @@
    return pIcon;
 }
 
+BOOL
+IntIsScrollBarVisible(PWND pWnd, INT hBar)
+{
+  SCROLLBARINFO sbi;
+  sbi.cbSize = sizeof(SCROLLBARINFO);
+
+  if(!co_IntGetScrollBarInfo(pWnd, hBar, &sbi))
+    return FALSE;
+
+  return !(sbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN);
+}
+
+BOOL
+UserHasMenu(PWND pWnd, ULONG Style)
+{
+   return (!(Style & WS_CHILD) && UlongToHandle(pWnd->IDMenu) != 0);
+}
+
+/*
+ * FIXME:
+ * - Cache bitmaps, then just bitblt instead of calling DFC() (and
+ *   wasting precious CPU cycles) every time
+ * - Center the buttons verticaly in the rect
+ */
+VOID
+UserDrawCaptionButton(PWND pWnd, LPRECT Rect, DWORD Style, DWORD ExStyle, HDC hDC, BOOL bDown, ULONG Type)
+{
+   RECT TempRect;
+
+   if (!(Style & WS_SYSMENU))
+   {
+      return;
+   }
+
+   TempRect = *Rect;
+
+   switch (Type)
+   {
+      case DFCS_CAPTIONMIN:
+      {
+         if (ExStyle & WS_EX_TOOLWINDOW)
+            return; /* ToolWindows don't have min/max buttons */
+
+         if (Style & WS_SYSMENU)
+             TempRect.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
+
+         if (Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+             TempRect.right -= UserGetSystemMetrics(SM_CXSIZE) - 2;
+
+         TempRect.left = TempRect.right - UserGetSystemMetrics(SM_CXSIZE) + 1;
+         TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYSIZE) - 2;
+         TempRect.top += 2;
+         TempRect.right -= 1;
+
+         DrawFrameControl(hDC, &TempRect, DFC_CAPTION,
+                          ((Style & WS_MINIMIZE) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMIN) |
+                          (bDown ? DFCS_PUSHED : 0) |
+                          ((Style & WS_MINIMIZEBOX) ? 0 : DFCS_INACTIVE));
+         break;
+      }
+      case DFCS_CAPTIONMAX:
+      {
+         if (ExStyle & WS_EX_TOOLWINDOW)
+             return; /* ToolWindows don't have min/max buttons */
+
+         if (Style & WS_SYSMENU)
+             TempRect.right -= UserGetSystemMetrics(SM_CXSIZE) + 1;
+
+         TempRect.left = TempRect.right - UserGetSystemMetrics(SM_CXSIZE) + 1;
+         TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYSIZE) - 2;
+         TempRect.top += 2;
+         TempRect.right -= 1;
+
+         DrawFrameControl(hDC, &TempRect, DFC_CAPTION,
+                          ((Style & WS_MAXIMIZE) ? DFCS_CAPTIONRESTORE : DFCS_CAPTIONMAX) |
+                          (bDown ? DFCS_PUSHED : 0) |
+                          ((Style & WS_MAXIMIZEBOX) ? 0 : DFCS_INACTIVE));
+         break;
+      }
+      case DFCS_CAPTIONCLOSE:
+      {
+          PMENU pSysMenu = IntGetSystemMenu(pWnd, FALSE);
+          UINT MenuState = IntGetMenuState(UserHMGetHandle(pSysMenu), SC_CLOSE, MF_BYCOMMAND); /* in case of error MenuState==0xFFFFFFFF */
+
+         /* FIXME: A tool window has a smaller Close button */
+
+         if (ExStyle & WS_EX_TOOLWINDOW)
+         {
+            TempRect.left = TempRect.right - UserGetSystemMetrics(SM_CXSMSIZE);
+            TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYSMSIZE) - 2;
+         }
+         else
+         {
+            TempRect.left = TempRect.right - UserGetSystemMetrics(SM_CXSIZE);
+            TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYSIZE) - 2;
+         }
+         TempRect.top += 2;
+         TempRect.right -= 2;
+
+         DrawFrameControl(hDC, &TempRect, DFC_CAPTION,
+                          (DFCS_CAPTIONCLOSE | (bDown ? DFCS_PUSHED : 0) |
+                          ((!(MenuState & (MF_GRAYED|MF_DISABLED)) && !(pWnd->pcls->style & CS_NOCLOSE)) ? 0 : DFCS_INACTIVE)));
+         break;
+      }
+   }
+}
+
+VOID
+UserDrawCaptionButtonWnd(PWND pWnd, HDC hDC, BOOL bDown, ULONG Type)
+{
+   RECT WindowRect;
+   SIZE WindowBorder;
+
+   IntGetWindowRect(pWnd, &WindowRect);
+
+   WindowRect.right -= WindowRect.left;
+   WindowRect.bottom -= WindowRect.top;
+   WindowRect.left = WindowRect.top = 0;
+
+   UserGetWindowBorders(pWnd->style, pWnd->ExStyle, &WindowBorder, FALSE);
+
+   RECTL_vInflateRect(&WindowRect, -WindowBorder.cx, -WindowBorder.cy);
+
+   UserDrawCaptionButton(pWnd, &WindowRect, pWnd->style, pWnd->ExStyle, hDC, bDown, Type);
+}
+
+VOID
+NC_DrawFrame( HDC hDC, RECT *CurrentRect, BOOL Active, DWORD Style, DWORD ExStyle)
+{
+   /* Firstly the "thick" frame */
+   if ((Style & WS_THICKFRAME) && !(Style & WS_MINIMIZE))
+   {
+      LONG Width =
+         (UserGetSystemMetrics(SM_CXFRAME) - UserGetSystemMetrics(SM_CXDLGFRAME)) *
+         UserGetSystemMetrics(SM_CXBORDER);
+
+      LONG Height =
+         (UserGetSystemMetrics(SM_CYFRAME) - UserGetSystemMetrics(SM_CYDLGFRAME)) *
+         UserGetSystemMetrics(SM_CYBORDER);
+
+      NtGdiSelectBrush(hDC, IntGetSysColorBrush(Active ? COLOR_ACTIVEBORDER : COLOR_INACTIVEBORDER));
+
+      /* Draw frame */
+      NtGdiPatBlt(hDC, CurrentRect->left, CurrentRect->top, CurrentRect->right - CurrentRect->left, Height, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect->left, CurrentRect->top, Width, CurrentRect->bottom - CurrentRect->top, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect->left, CurrentRect->bottom - 1, CurrentRect->right - CurrentRect->left, -Height, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect->right - 1, CurrentRect->top, -Width, CurrentRect->bottom - CurrentRect->top, PATCOPY);
+
+      RECTL_vInflateRect(CurrentRect, -Width, -Height);
+   }
+
+   /* Now the other bit of the frame */
+   if (Style & (WS_DLGFRAME | WS_BORDER) || ExStyle & WS_EX_DLGMODALFRAME)
+   {
+      DWORD Width = UserGetSystemMetrics(SM_CXBORDER);
+      DWORD Height = UserGetSystemMetrics(SM_CYBORDER);
+
+      NtGdiSelectBrush(hDC, IntGetSysColorBrush(
+         (ExStyle & (WS_EX_DLGMODALFRAME | WS_EX_CLIENTEDGE)) ? COLOR_3DFACE :
+         (ExStyle & WS_EX_STATICEDGE) ? COLOR_WINDOWFRAME :
+         (Style & (WS_DLGFRAME | WS_THICKFRAME)) ? COLOR_3DFACE :
+         COLOR_WINDOWFRAME));
+
+      /* Draw frame */
+      NtGdiPatBlt(hDC, CurrentRect->left, CurrentRect->top, CurrentRect->right - CurrentRect->left, Height, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect->left, CurrentRect->top, Width, CurrentRect->bottom - CurrentRect->top, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect->left, CurrentRect->bottom - 1, CurrentRect->right - CurrentRect->left, -Height, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect->right - 1, CurrentRect->top, -Width, CurrentRect->bottom - CurrentRect->top, PATCOPY);
+
+      RECTL_vInflateRect(CurrentRect, -Width, -Height);
+   }
+}
+
+VOID UserDrawCaptionBar(
+   PWND pWnd,
+   HDC hDC,
+   INT Flags)
+{
+   RECT ClientRect, WindowRect, CurrentRect, TempRect;
+   HPEN PreviousPen;
+   BOOL Gradient = FALSE;
+
+   if (!(Flags & DC_NOVISIBLE) && !IntIsWindowVisible(pWnd)) return;
+
+   IntGetWindowRect(pWnd, &WindowRect);
+   IntGetClientRect(pWnd, &ClientRect);
+
+   CurrentRect.top = CurrentRect.left = 0;
+   CurrentRect.right = WindowRect.right - WindowRect.left;
+   CurrentRect.bottom = WindowRect.bottom - WindowRect.top;
+
+   /* Draw outer edge */
+   if (UserHasWindowEdge(pWnd->style, pWnd->ExStyle))
+   {
+      DrawEdge(hDC, &CurrentRect, EDGE_RAISED, BF_RECT | BF_ADJUST);
+   }
+   else if (pWnd->ExStyle & WS_EX_STATICEDGE)
+   {
+#if 0
+      DrawEdge(hDC, &CurrentRect, BDR_SUNKENINNER, BF_RECT | BF_ADJUST | BF_FLAT);
+#else
+      NtGdiSelectBrush(hDC, IntGetSysColorBrush(COLOR_BTNSHADOW));
+      NtGdiPatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, 1, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect.left, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY);
+
+      NtGdiSelectBrush(hDC, IntGetSysColorBrush(COLOR_BTNHIGHLIGHT));
+      NtGdiPatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, 1, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY);
+
+      RECTL_vInflateRect(&CurrentRect, -1, -1);
+#endif
+   }
+
+   if (Flags & DC_FRAME) NC_DrawFrame(hDC, &CurrentRect, (Flags & DC_ACTIVE), pWnd->style, pWnd->ExStyle);
+
+   /* Draw caption */
+   if ((pWnd->style & WS_CAPTION) == WS_CAPTION)
+   {
+
+      TempRect = CurrentRect;
+
+      if (UserSystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &Gradient, 0) && Gradient)
+      {
+         Flags |= DC_GRADIENT;
+      }
+
+      if (pWnd->ExStyle & WS_EX_TOOLWINDOW)
+      {
+         Flags |= DC_SMALLCAP;
+         TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYSMCAPTION) - 1;
+         CurrentRect.top += UserGetSystemMetrics(SM_CYSMCAPTION);
+      }
+      else
+      {
+         TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYCAPTION) - 1;
+         CurrentRect.top += UserGetSystemMetrics(SM_CYCAPTION);
+      }
+
+      UserDrawCaption(pWnd, hDC, &TempRect, NULL, NULL, NULL, Flags);
+
+      /* Draw buttons */
+      if (pWnd->style & WS_SYSMENU)
+      {
+         UserDrawCaptionButton(pWnd, &TempRect, pWnd->style, pWnd->ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE);
+         if ((pWnd->style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(pWnd->ExStyle & WS_EX_TOOLWINDOW))
+         {
+            UserDrawCaptionButton(pWnd, &TempRect, pWnd->style, pWnd->ExStyle, hDC, FALSE, DFCS_CAPTIONMIN);
+            UserDrawCaptionButton(pWnd, &TempRect, pWnd->style, pWnd->ExStyle, hDC, FALSE, DFCS_CAPTIONMAX);
+         }
+      }
+
+      if (!(pWnd->style & WS_MINIMIZE))
+      {
+         /* Line under caption */
+         PreviousPen = NtGdiSelectPen(hDC, NtGdiGetStockObject(DC_PEN));
+
+         IntSetDCPenColor( hDC, IntGetSysColor(((pWnd->ExStyle & (WS_EX_STATICEDGE|WS_EX_CLIENTEDGE|WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
+                                             COLOR_WINDOWFRAME : COLOR_3DFACE));
+
+         GreMoveTo(hDC, TempRect.left, TempRect.bottom, NULL);
+
+         NtGdiLineTo(hDC, TempRect.right, TempRect.bottom);
+
+         NtGdiSelectPen(hDC, PreviousPen);
+      }
+   }
+
+   if (!(pWnd->style & WS_MINIMIZE))
+   {
+      if (pWnd->ExStyle & WS_EX_CLIENTEDGE)
+      {
+          DrawEdge(hDC, &CurrentRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
+      }
+   }
+}
+
+// Note from Wine:
+/* MSDN docs are pretty idiotic here, they say app CAN use clipRgn in
+   the call to GetDCEx implying that it is allowed not to use it either.
+   However, the suggested GetDCEx(    , DCX_WINDOW | DCX_INTERSECTRGN)
+   will cause clipRgn to be deleted after ReleaseDC().
+   Now, how is the "system" supposed to tell what happened?
+ */
+/*
+ * FIXME:
+ * - Drawing of WS_BORDER after scrollbars
+ * - Correct drawing of size-box
+ */
+LRESULT
+NC_DoNCPaint(PWND pWnd, HDC hDC, INT Flags)
+{
+   DWORD Style, ExStyle;
+   PWND Parent;
+   RECT ClientRect, WindowRect, CurrentRect, TempRect;
+   BOOL Active = FALSE;
+
+   if (!IntIsWindowVisible(pWnd) ||
+       (pWnd->state & WNDS_NONCPAINT && !(pWnd->state & WNDS_FORCEMENUDRAW)) ||
+        IntEqualRect(&pWnd->rcWindow, &pWnd->rcClient) )
+      return 0;
+
+   Style = pWnd->style;
+
+   TRACE("DefWndNCPaint: pWnd %p, hDc %p, Active %s.\n", pWnd, hDC, Active ? "TRUE" : "FALSE");
+
+   Parent = IntGetParent(pWnd);
+   ExStyle = pWnd->ExStyle;
+
+   if (Flags == -1) // NC paint mode.
+   {
+      if (ExStyle & WS_EX_MDICHILD)
+      {
+         Active = IntIsChildWindow(gpqForeground->spwndActive, pWnd);
+
+         if (Active)
+            Active = (UserHMGetHandle(pWnd) == (HWND)co_IntSendMessage(UserHMGetHandle(Parent), WM_MDIGETACTIVE, 0, 0));
+      }
+      else
+      {
+         Active = (gpqForeground->spwndActive == pWnd);
+      }
+      Flags = DC_NC;
+   }
+
+   IntGetWindowRect(pWnd, &WindowRect);
+   IntGetClientRect(pWnd, &ClientRect);
+
+   CurrentRect.top = CurrentRect.left = 0;
+   CurrentRect.right = WindowRect.right - WindowRect.left;
+   CurrentRect.bottom = WindowRect.bottom - WindowRect.top;
+
+   /* Draw outer edge */
+   if (UserHasWindowEdge(pWnd->style, pWnd->ExStyle))
+   {
+      DrawEdge(hDC, &CurrentRect, EDGE_RAISED, BF_RECT | BF_ADJUST);
+   }
+   else if (pWnd->ExStyle & WS_EX_STATICEDGE)
+   {
+#if 0
+      DrawEdge(hDC, &CurrentRect, BDR_SUNKENINNER, BF_RECT | BF_ADJUST | BF_FLAT);
+#else
+      NtGdiSelectBrush(hDC, IntGetSysColorBrush(COLOR_BTNSHADOW));
+      NtGdiPatBlt(hDC, CurrentRect.left, CurrentRect.top, CurrentRect.right - CurrentRect.left, 1, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect.left, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY);
+
+      NtGdiSelectBrush(hDC, IntGetSysColorBrush(COLOR_BTNHIGHLIGHT));
+      NtGdiPatBlt(hDC, CurrentRect.left, CurrentRect.bottom - 1, CurrentRect.right - CurrentRect.left, 1, PATCOPY);
+      NtGdiPatBlt(hDC, CurrentRect.right - 1, CurrentRect.top, 1, CurrentRect.bottom - CurrentRect.top, PATCOPY);
+
+      RECTL_vInflateRect(&CurrentRect, -1, -1);
+#endif
+   }
+
+   if (Flags & DC_FRAME) NC_DrawFrame(hDC, &CurrentRect, Active, Style, ExStyle);
+
+   /* Draw caption */
+   if ((Style & WS_CAPTION) == WS_CAPTION)
+   {
+      HPEN PreviousPen;
+      BOOL Gradient = FALSE;
+
+      if (Flags & DCF_REDRAWHUNGWND)
+      {
+         Flags &= ~DCF_REDRAWHUNGWND;
+         Flags |= DC_NOSENDMSG;
+      }
+
+      if (UserSystemParametersInfo(SPI_GETGRADIENTCAPTIONS, 0, &Gradient, 0) && Gradient)
+      {
+         Flags |= DC_GRADIENT;
+      }
+
+      if (Active)
+      {
+         if (!(pWnd->state & WNDS_ACTIVEFRAME))
+         {
+            ERR("Wnd is active and not set active!\n");
+         }
+         Flags |= DC_ACTIVE;
+      }
+
+      TempRect = CurrentRect;
+
+      if (ExStyle & WS_EX_TOOLWINDOW)
+      {
+         Flags |= DC_SMALLCAP;
+         TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYSMCAPTION) - 1;
+         CurrentRect.top += UserGetSystemMetrics(SM_CYSMCAPTION);
+      }
+      else
+      {
+         TempRect.bottom = TempRect.top + UserGetSystemMetrics(SM_CYCAPTION) - 1;
+         CurrentRect.top += UserGetSystemMetrics(SM_CYCAPTION);
+      }
+
+      UserDrawCaption(pWnd, hDC, &TempRect, NULL, NULL, NULL, Flags);
+
+      /* Draw buttons */
+      if (Style & WS_SYSMENU)
+      {
+         UserDrawCaptionButton(pWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONCLOSE);
+         if ((Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX)) && !(ExStyle & WS_EX_TOOLWINDOW))
+         {
+            UserDrawCaptionButton(pWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMIN);
+            UserDrawCaptionButton(pWnd, &TempRect, Style, ExStyle, hDC, FALSE, DFCS_CAPTIONMAX);
+         }
+      }
+      if (!(Style & WS_MINIMIZE))
+      {
+        /* Line under caption */
+         PreviousPen = NtGdiSelectPen(hDC, NtGdiGetStockObject(DC_PEN));
+
+         IntSetDCPenColor( hDC, IntGetSysColor(
+                         ((ExStyle & (WS_EX_STATICEDGE | WS_EX_CLIENTEDGE | WS_EX_DLGMODALFRAME)) == WS_EX_STATICEDGE) ?
+                          COLOR_WINDOWFRAME : COLOR_3DFACE));
+
+         GreMoveTo(hDC, TempRect.left, TempRect.bottom, NULL);
+
+         NtGdiLineTo(hDC, TempRect.right, TempRect.bottom);
+
+         NtGdiSelectPen(hDC, PreviousPen);
+      }
+   }
+
+   if (!(Style & WS_MINIMIZE))
+   {
+     PMENU menu = UserGetMenuObject(UlongToHandle(pWnd->IDMenu));
+     /* Draw menu bar */
+     if (menu && !(Style & WS_CHILD))
+     {
+         TempRect = CurrentRect;
+         TempRect.bottom = TempRect.top + menu->cyMenu;
+         CurrentRect.top += MENU_DrawMenuBar(hDC, &TempRect, pWnd, FALSE);
+     }
+
+     if (ExStyle & WS_EX_CLIENTEDGE)
+     {
+         DrawEdge(hDC, &CurrentRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
+     }
+
+     /* Draw the scrollbars */
+     if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL) &&
+         IntIsScrollBarVisible(pWnd, OBJID_VSCROLL) && IntIsScrollBarVisible(pWnd, OBJID_HSCROLL))
+     {
+        RECT ParentClientRect;
+
+        TempRect = CurrentRect;
+
+        if (ExStyle & WS_EX_LEFTSCROLLBAR)
+           TempRect.right = TempRect.left + UserGetSystemMetrics(SM_CXVSCROLL);
+        else
+           TempRect.left = TempRect.right - UserGetSystemMetrics(SM_CXVSCROLL);
+
+        TempRect.top = TempRect.bottom - UserGetSystemMetrics(SM_CYHSCROLL);
+
+        FillRect(hDC, &TempRect, IntGetSysColorBrush(COLOR_BTNFACE));
+
+        if (Parent)
+           IntGetClientRect(Parent, &ParentClientRect);
+
+        if (HASSIZEGRIP(Style, ExStyle, Parent->style, WindowRect, ParentClientRect))
+        {
+           DrawFrameControl(hDC, &TempRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
+        }
+
+        IntDrawScrollBar(pWnd, hDC, SB_VERT);
+        IntDrawScrollBar(pWnd, hDC, SB_HORZ);
+     }
+     else
+     {
+        if (Style & WS_VSCROLL && IntIsScrollBarVisible(pWnd, OBJID_VSCROLL))
+        {
+           IntDrawScrollBar(pWnd, hDC, SB_VERT);
+        }
+        else if (Style & WS_HSCROLL && IntIsScrollBarVisible(pWnd, OBJID_HSCROLL))
+        {
+           IntDrawScrollBar(pWnd, hDC, SB_HORZ);
+        }
+     }
+   }
+   return 0; // For WM_NCPAINT message, return 0.
+}
+
+LRESULT NC_HandleNCCalcSize( PWND Wnd, WPARAM wparam, RECTL *Rect )
+{
+   LRESULT Result = 0;
+   SIZE WindowBorders;
+   RECT OrigRect;
+   DWORD Style = Wnd->style;
+
+   if (Rect == NULL)
+   {
+      return Result;
+   }
+   OrigRect = *Rect;
+
+   Wnd->state &= ~WNDS_HASCAPTION;
+
+   if (wparam)
+   {
+      if (Wnd->pcls->style & CS_VREDRAW)
+      {
+         Result |= WVR_VREDRAW;
+      }
+      if (Wnd->pcls->style & CS_HREDRAW)
+      {
+         Result |= WVR_HREDRAW;
+      }
+      Result |= WVR_VALIDRECTS;
+   }
+
+   if (!(Wnd->style & WS_MINIMIZE))
+   {
+      if (UserHasWindowEdge(Wnd->style, Wnd->ExStyle))
+      {
+         UserGetWindowBorders(Wnd->style, Wnd->ExStyle, &WindowBorders, FALSE);
+         RECTL_vInflateRect(Rect, -WindowBorders.cx, -WindowBorders.cy);
+      }
+      else if ((Wnd->ExStyle & WS_EX_STATICEDGE) || (Wnd->style & WS_BORDER))
+      {
+         RECTL_vInflateRect(Rect, -1, -1);
+      }
+
+      if ((Wnd->style & WS_CAPTION) == WS_CAPTION)
+      {
+         Wnd->state |= WNDS_HASCAPTION;
+
+         if (Wnd->ExStyle & WS_EX_TOOLWINDOW)
+            Rect->top += UserGetSystemMetrics(SM_CYSMCAPTION);
+         else
+            Rect->top += UserGetSystemMetrics(SM_CYCAPTION);
+      }
+
+      if (Wnd->IDMenu && ((Wnd->style & (WS_CHILD | WS_POPUP)) != WS_CHILD))
+      {
+         HDC hDC = UserGetDCEx(Wnd, 0, DCX_USESTYLE | DCX_WINDOW);
+
+         Wnd->state |= WNDS_HASMENU;
+         ERR("WNDS_HASMENU\n");
+         if (hDC)
+         {
+           RECT CliRect = *Rect;
+           CliRect.bottom -= OrigRect.top;
+           CliRect.right -= OrigRect.left;
+           CliRect.left -= OrigRect.left;
+           CliRect.top -= OrigRect.top;
+           Rect->top += MENU_DrawMenuBar(hDC, &CliRect, Wnd, TRUE);
+           UserReleaseDC(Wnd, hDC, FALSE);
+         }
+      }
+
+      if (Wnd->ExStyle & WS_EX_CLIENTEDGE)
+      {
+         RECTL_vInflateRect(Rect, -2 * UserGetSystemMetrics(SM_CXBORDER), -2 * UserGetSystemMetrics(SM_CYBORDER));
+      }
+
+      if (Wnd->style & (WS_VSCROLL | WS_HSCROLL))
+      {
+        SCROLLBARINFO sbi;
+        SETSCROLLBARINFO ssbi;
+
+        sbi.cbSize = sizeof(SCROLLBARINFO);
+        if ((Style & WS_VSCROLL) && co_IntGetScrollBarInfo(Wnd, OBJID_VSCROLL, &sbi))
+        {
+          int i;
+          LONG sx = Rect->right;
+
+          Wnd->state |= WNDS_HASVERTICALSCROOLLBAR;
+
+          sx -= UserGetSystemMetrics(SM_CXVSCROLL);
+
+          for (i = 0; i <= CCHILDREN_SCROLLBAR; i++)
+              ssbi.rgstate[i] = sbi.rgstate[i];
+
+          if (sx <= Rect->left)
+             ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
+          else
+             ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
+
+          co_IntSetScrollBarInfo(Wnd, OBJID_VSCROLL, &ssbi);
+
+          if (ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
+             Style &= ~WS_VSCROLL;
+        }
+        else
+          Style &= ~WS_VSCROLL;
+
+        if ((Style & WS_HSCROLL) && co_IntGetScrollBarInfo(Wnd, OBJID_HSCROLL, &sbi))
+        {
+          int i;
+          LONG sy = Rect->bottom;
+
+          Wnd->state |= WNDS_HASHORIZONTALSCROLLBAR;
+
+          sy -= UserGetSystemMetrics(SM_CYHSCROLL);
+
+          for (i = 0; i <= CCHILDREN_SCROLLBAR; i++)
+              ssbi.rgstate[i] = sbi.rgstate[i];
+
+          if (sy <= Rect->top)
+             ssbi.rgstate[0] |= STATE_SYSTEM_OFFSCREEN;
+          else
+             ssbi.rgstate[0] &= ~STATE_SYSTEM_OFFSCREEN;
+
+          co_IntSetScrollBarInfo(Wnd, OBJID_HSCROLL, &ssbi);
+
+          if (ssbi.rgstate[0] & STATE_SYSTEM_OFFSCREEN)
+             Style &= ~WS_HSCROLL;
+        }
+        else
+          Style &= ~WS_HSCROLL;
+      }
+
+      if ((Style & WS_VSCROLL) && (Style & WS_HSCROLL))
+      {
+         if ((Wnd->ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
+            Rect->left += UserGetSystemMetrics(SM_CXVSCROLL);
+         else
+            Rect->right -= UserGetSystemMetrics(SM_CXVSCROLL);
+
+         Rect->bottom -= UserGetSystemMetrics(SM_CYHSCROLL);
+      }
+      else
+      {
+         if (Style & WS_VSCROLL)
+         {
+            if ((Wnd->ExStyle & WS_EX_LEFTSCROLLBAR) != 0)
+               Rect->left += UserGetSystemMetrics(SM_CXVSCROLL);
+            else
+               Rect->right -= UserGetSystemMetrics(SM_CXVSCROLL);
+         }
+         else if (Style & WS_HSCROLL)
+            Rect->bottom -= UserGetSystemMetrics(SM_CYHSCROLL);
+      }
+
+      if (Rect->top > Rect->bottom)
+         Rect->bottom = Rect->top;
+
+      if (Rect->left > Rect->right)
+         Rect->right = Rect->left;
+   }
+   else
+   {
+      Rect->right = Rect->left;
+      Rect->bottom = Rect->top;
+   }
+
+   return Result;
+}
+
+static
+INT NC_DoNCActive(PWND Wnd)
+{
+   INT Ret = 0;
+
+   if ( IntGetSysColor(COLOR_CAPTIONTEXT) != IntGetSysColor(COLOR_INACTIVECAPTIONTEXT) ||
+        IntGetSysColor(COLOR_ACTIVECAPTION) != IntGetSysColor(COLOR_INACTIVECAPTION) )
+       Ret = DC_CAPTION;
+
+   if (!(Wnd->style & WS_MINIMIZED) && UserHasThickFrameStyle(Wnd->style, Wnd->ExStyle))
+   {
+      if (IntGetSysColor(COLOR_ACTIVEBORDER) != IntGetSysColor(COLOR_INACTIVEBORDER))
+      {
+          Ret = DC_FRAME;
+      }
+   }
+   return Ret;
+}
+
+LRESULT NC_HandleNCActivate( PWND Wnd, WPARAM wParam, LPARAM lParam )
+{
+   INT Flags;
+  /* Lotus Notes draws menu descriptions in the caption of its main
+   * window. When it wants to restore original "system" view, it just
+   * sends WM_NCACTIVATE message to itself. Any optimizations here in
+   * attempt to minimize redrawings lead to a not restored caption.
+   */
+   if (wParam & DC_ACTIVE)
+   {
+      Wnd->state |= WNDS_ACTIVEFRAME;
+      wParam = DC_CAPTION|DC_ACTIVE;
+   }
+   else
+   {
+      Wnd->state &= ~WNDS_ACTIVEFRAME;
+      wParam = DC_CAPTION;
+   }
+
+   if (Wnd->state & WNDS_NONCPAINT || !(Wnd->style & WS_VISIBLE))
+      return 0;
+
+   /* This isn't documented but is reproducible in at least XP SP2 and
+    * Outlook 2007 depends on it
+    */
+   // MSDN:
+   // If this parameter is set to -1, DefWindowProc does not repaint the
+   // nonclient area to reflect the state change.
+   if ( lParam != -1 &&
+        ( Flags = NC_DoNCActive(Wnd)) != 0 )
+   {
+      HDC hDC;
+      HRGN hRgnTemp = NULL, hRgn = (HRGN)lParam;
+
+      if (GreIsHandleValid(hRgn))
+      {
+         hRgnTemp = NtGdiCreateRectRgn(0, 0, 0, 0);
+         if (NtGdiCombineRgn(hRgnTemp, hRgn, 0, RGN_COPY) == ERROR)
+         {
+            GreDeleteObject(hRgnTemp);
+            hRgnTemp = NULL;
+         }
+      }
+
+      if ((hDC = UserGetDCEx(Wnd, hRgnTemp, DCX_WINDOW|DCX_USESTYLE)))
+      {
+         ERR("Flags %d wParam %d\n",wParam, Flags);
+         NC_DoNCPaint(Wnd, hDC, wParam | Flags); // Redraw MENUs.
+         UserReleaseDC(Wnd, hDC, FALSE);
+      }
+      else
+         GreDeleteObject(hRgnTemp);
+   }
+
+   return TRUE;
+}
+
 DWORD FASTCALL
 GetNCHitEx(PWND pWnd, POINT pt)
 {
Index: win32ss/user/ntuser/painting.c
===================================================================
--- win32ss/user/ntuser/painting.c	(revision 68595)
+++ win32ss/user/ntuser/painting.c	(working copy)
@@ -1882,6 +1882,7 @@
    NTSTATUS Status;
    BOOLEAN bDeleteFont = FALSE;
    SIZE Size;
+   BOOL Ret = TRUE;
    ULONG fit = 0, Length;
    WCHAR szText[128];
    RECTL r = *lpRc;
@@ -1942,6 +1943,7 @@
    if (Text->Length/sizeof(WCHAR) > Length && Length > 3)
    {
       RtlCopyMemory(&szText[Length-3], ELLIPSISW, sizeof(ELLIPSISW));
+      Ret = FALSE;
    }
 
    GreExtTextOutW( hDc,
@@ -1962,9 +1964,12 @@
    if (bDeleteFont)
       GreDeleteObject(hFont);
 
-   return TRUE;
+   return Ret;
 }
 
+//
+// This draws Buttons, Icons and Text...
+//
 BOOL UserDrawCaption(
    PWND pWnd,
    HDC hDc,
@@ -2087,10 +2092,11 @@
 
    if((uFlags & DC_TEXT))
    {
+      BOOL Set = FALSE;
       Rect.left += 2;
 
       if (Str)
-         UserDrawCaptionText(pWnd, hDc, Str, &Rect, uFlags, hFont);
+         Set = UserDrawCaptionText(pWnd, hDc, Str, &Rect, uFlags, hFont);
       else if (pWnd != NULL) // FIXME: Windows does not do that
       {
          UNICODE_STRING ustr;
@@ -2097,8 +2103,15 @@
          ustr.Buffer = pWnd->strName.Buffer; // FIXME: LARGE_STRING truncated!
          ustr.Length = (USHORT)min(pWnd->strName.Length, MAXUSHORT);
          ustr.MaximumLength = (USHORT)min(pWnd->strName.MaximumLength, MAXUSHORT);
-         UserDrawCaptionText(pWnd, hDc, &ustr, &Rect, uFlags, hFont);
+         Set = UserDrawCaptionText(pWnd, hDc, &ustr, &Rect, uFlags, hFont);
       }
+      if (pWnd)
+      {
+         if (Set)
+            pWnd->state2 &= ~WNDS2_CAPTIONTEXTTRUNCATED;
+         else
+            pWnd->state2 |= WNDS2_CAPTIONTEXTTRUNCATED;
+      }
    }
 
    Ret = TRUE;
Index: win32ss/user/ntuser/painting.h
===================================================================
--- win32ss/user/ntuser/painting.h	(revision 68595)
+++ win32ss/user/ntuser/painting.h	(working copy)
@@ -33,4 +33,6 @@
 PCURICON_OBJECT FASTCALL NC_IconForWindow( PWND );
 BOOL FASTCALL IntFlashWindowEx(PWND,PFLASHWINFO);
 BOOL FASTCALL IntIntersectWithParents(PWND, RECTL *);
-BOOL FASTCALL IntIsWindowDrawable(PWND);
\ No newline at end of file
+BOOL FASTCALL IntIsWindowDrawable(PWND);
+BOOL UserDrawCaption(PWND,HDC,RECTL*,HFONT,HICON,const PUNICODE_STRING,UINT);
+
Index: win32ss/user/ntuser/scroll.h
===================================================================
--- win32ss/user/ntuser/scroll.h	(revision 68595)
+++ win32ss/user/ntuser/scroll.h	(working copy)
@@ -39,5 +39,9 @@
 #define SBOBJ_TO_SBID(Obj)	((Obj) - OBJID_HSCROLL)
 #define SBID_IS_VALID(id)	(id == SB_HORZ || id == SB_VERT || id == SB_CTL)
 
-BOOL FASTCALL co_IntCreateScrollBars(PWND Window);
-BOOL FASTCALL IntDestroyScrollBars(PWND Window);
+BOOL FASTCALL co_IntCreateScrollBars(PWND);
+BOOL FASTCALL IntDestroyScrollBars(PWND);
+DWORD FASTCALL co_UserShowScrollBar(PWND,int,BOOL,BOOL);
+BOOL FASTCALL co_IntGetScrollBarInfo(PWND,LONG,PSCROLLBARINFO);
+BOOL FASTCALL co_IntSetScrollBarInfo(PWND,LONG,PSETSCROLLBARINFO);
+void IntDrawScrollBar(PWND,HDC,INT);
Index: win32ss/user/ntuser/scrollbar.c
===================================================================
--- win32ss/user/ntuser/scrollbar.c	(revision 68595)
+++ win32ss/user/ntuser/scrollbar.c	(working copy)
@@ -10,6 +10,32 @@
 #include <win32k.h>
 DBG_DEFAULT_CHANNEL(UserScrollbar);
 
+/* Definitions for scrollbar hit testing [See SCROLLBARINFO in MSDN] */
+#define SCROLL_NOWHERE		0x00    /* Outside the scroll bar */
+#define SCROLL_TOP_ARROW	0x01    /* Top or left arrow */
+#define SCROLL_TOP_RECT		0x02    /* Rectangle between the top arrow and the thumb */
+#define SCROLL_THUMB		0x03    /* Thumb rectangle */
+#define SCROLL_BOTTOM_RECT	0x04    /* Rectangle between the thumb and the bottom arrow */
+#define SCROLL_BOTTOM_ARROW	0x05    /* Bottom or right arrow */
+
+#define SCROLL_FIRST_DELAY   200        /* Delay (in ms) before first repetition when
+                                           holding the button down */
+#define SCROLL_REPEAT_DELAY  50         /* Delay (in ms) between scroll repetitions */
+
+#define SCROLL_TIMER   0                /* Scroll timer id */
+
+  /* Minimum size of the rectangle between the arrows */
+#define SCROLL_MIN_RECT  4
+
+  /* Minimum size of the thumb in pixels */
+#define SCROLL_MIN_THUMB 6
+
+  /* Overlap between arrows and thumb */
+#define SCROLL_ARROW_THUMB_OVERLAP 0
+
+//
+//
+//
 #define MINTRACKTHUMB    8               /* Minimum size of the rectangle between the arrows */
 
  /* What to do after SetScrollInfo() */
@@ -555,6 +581,39 @@
 }
 
 BOOL FASTCALL
+co_IntSetScrollBarInfo(PWND Window, LONG idObject, PSETSCROLLBARINFO psbi)
+{
+   INT Bar;
+   PSCROLLBARINFO sbi;
+   LPSCROLLINFO psi;
+   ASSERT_REFS_CO(Window);
+
+   Bar = SBOBJ_TO_SBID(idObject);
+
+   if(!SBID_IS_VALID(Bar))
+   {
+      EngSetLastError(ERROR_INVALID_PARAMETER);
+      ERR("Trying to get scrollinfo for unknown scrollbar type %d\n", Bar);
+      return FALSE;
+   }
+
+   if(!co_IntCreateScrollBars(Window))
+   {
+      ERR("Failed to create scrollbars for window.\n");
+      return FALSE;
+   }
+
+   sbi = IntGetScrollbarInfoFromWindow(Window, Bar);
+   psi = IntGetScrollInfoFromWindow(Window, Bar);
+
+   psi->nTrackPos = psbi->nTrackPos;
+   sbi->reserved  = psbi->reserved;
+   RtlCopyMemory(&sbi->rgstate, &psbi->rgstate, sizeof(psbi->rgstate));
+
+   return TRUE;
+}
+
+BOOL FASTCALL
 co_IntCreateScrollBars(PWND Window)
 {
    PSCROLLBARINFO psbi;
@@ -709,6 +768,248 @@
    return FALSE;
 }
 
+static void
+IntDrawScrollInterior(PWND pWnd, HDC hDC, INT nBar, BOOL Vertical, PSCROLLBARINFO ScrollBarInfo)
+{
+   INT ThumbSize = ScrollBarInfo->xyThumbBottom - ScrollBarInfo->xyThumbTop;
+   INT ThumbTop = ScrollBarInfo->xyThumbTop;
+   RECT Rect;
+   HBRUSH hSaveBrush, hBrush;
+   BOOL TopSelected = FALSE, BottomSelected = FALSE;
+
+   if (ScrollBarInfo->rgstate[SCROLL_TOP_RECT] & STATE_SYSTEM_PRESSED)
+      TopSelected = TRUE;
+   if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_RECT] & STATE_SYSTEM_PRESSED)
+      BottomSelected = TRUE;
+
+   /*
+    * Only scrollbar controls send WM_CTLCOLORSCROLLBAR.
+    * The window-owned scrollbars need to call DefWndControlColor
+    * to correctly setup default scrollbar colors
+    */
+   if (nBar == SB_CTL)
+   {
+      hBrush = GetControlBrush( pWnd, hDC, WM_CTLCOLORSCROLLBAR);
+      if (!hBrush)
+         hBrush = IntGetSysColorBrush(COLOR_SCROLLBAR);
+   }
+   else
+   {
+      hBrush = DefWndControlColor(hDC, CTLCOLOR_SCROLLBAR);
+   }
+
+   hSaveBrush = NtGdiSelectBrush(hDC, hBrush);
+
+   /* Calculate the scroll rectangle */
+   if (Vertical)
+   {
+      Rect.top = ScrollBarInfo->rcScrollBar.top + ScrollBarInfo->dxyLineButton;
+      Rect.bottom = ScrollBarInfo->rcScrollBar.bottom - ScrollBarInfo->dxyLineButton;
+      Rect.left = ScrollBarInfo->rcScrollBar.left;
+      Rect.right = ScrollBarInfo->rcScrollBar.right;
+   }
+   else
+   {
+      Rect.top = ScrollBarInfo->rcScrollBar.top;
+      Rect.bottom = ScrollBarInfo->rcScrollBar.bottom;
+      Rect.left = ScrollBarInfo->rcScrollBar.left + ScrollBarInfo->dxyLineButton;
+      Rect.right = ScrollBarInfo->rcScrollBar.right - ScrollBarInfo->dxyLineButton;
+   }
+
+   /* Draw the scroll rectangles and thumb */
+   if (!ScrollBarInfo->xyThumbBottom)
+   {
+      NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
+         Rect.bottom - Rect.top, PATCOPY);
+
+      /* Cleanup and return */
+      NtGdiSelectBrush(hDC, hSaveBrush);
+      return;
+   }
+
+   ThumbTop -= ScrollBarInfo->dxyLineButton;
+
+   if (ScrollBarInfo->dxyLineButton)
+   {
+      if (Vertical)
+      {
+         if (ThumbSize)
+         {
+            NtGdiPatBlt(hDC, Rect.left, Rect.top, Rect.right - Rect.left,
+                   ThumbTop, TopSelected ? BLACKNESS : PATCOPY);
+            Rect.top += ThumbTop;
+            NtGdiPatBlt(hDC, Rect.left, Rect.top + ThumbSize, Rect.right - Rect.left,
+               Rect.bottom - Rect.top - ThumbSize, BottomSelected ? BLACKNESS : PATCOPY);
+            Rect.bottom = Rect.top + ThumbSize;
+         }
+         else
+         {
+            if (ThumbTop)
+            {
+               NtGdiPatBlt(hDC, Rect.left, ScrollBarInfo->dxyLineButton,
+                  Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
+            }
+         }
+      }
+      else
+      {
+         if (ThumbSize)
+         {
+            NtGdiPatBlt(hDC, Rect.left, Rect.top, ThumbTop,
+               Rect.bottom - Rect.top, TopSelected ? BLACKNESS : PATCOPY);
+            Rect.left += ThumbTop;
+            NtGdiPatBlt(hDC, Rect.left + ThumbSize, Rect.top,
+               Rect.right - Rect.left - ThumbSize, Rect.bottom - Rect.top,
+               BottomSelected ? BLACKNESS : PATCOPY);
+            Rect.right = Rect.left + ThumbSize;
+         }
+         else
+         {
+            if (ThumbTop)
+            {
+               NtGdiPatBlt(hDC, ScrollBarInfo->dxyLineButton, Rect.top,
+                  Rect.right - Rect.left, Rect.bottom - Rect.top, PATCOPY);
+            }
+         }
+      }
+   }
+
+   /* Draw the thumb */
+   if (ThumbSize)
+      DrawEdge(hDC, &Rect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
+
+   /* Cleanup */
+   NtGdiSelectBrush(hDC, hSaveBrush);
+}
+
+
+static VOID FASTCALL
+IntDrawScrollArrows(HDC hDC, PSCROLLBARINFO ScrollBarInfo, BOOL Vertical)
+{
+   RECT RectLT, RectRB;
+   INT ScrollDirFlagLT, ScrollDirFlagRB;
+
+   RectLT = RectRB = ScrollBarInfo->rcScrollBar;
+   if (Vertical)
+   {
+      ScrollDirFlagLT = DFCS_SCROLLUP;
+      ScrollDirFlagRB = DFCS_SCROLLDOWN;
+      RectLT.bottom = RectLT.top + ScrollBarInfo->dxyLineButton;
+      RectRB.top = RectRB.bottom - ScrollBarInfo->dxyLineButton;
+   }
+   else
+   {
+      ScrollDirFlagLT = DFCS_SCROLLLEFT;
+      ScrollDirFlagRB = DFCS_SCROLLRIGHT;
+      RectLT.right = RectLT.left + ScrollBarInfo->dxyLineButton;
+      RectRB.left = RectRB.right - ScrollBarInfo->dxyLineButton;
+   }
+
+   if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_PRESSED)
+   {
+      ScrollDirFlagLT |= DFCS_PUSHED | DFCS_FLAT;
+   }
+   if (ScrollBarInfo->rgstate[SCROLL_TOP_ARROW] & STATE_SYSTEM_UNAVAILABLE)
+   {
+      ScrollDirFlagLT |= DFCS_INACTIVE;
+   }
+   if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_PRESSED)
+   {
+      ScrollDirFlagRB |= DFCS_PUSHED | DFCS_FLAT;
+   }
+   if (ScrollBarInfo->rgstate[SCROLL_BOTTOM_ARROW] & STATE_SYSTEM_UNAVAILABLE)
+   {
+      ScrollDirFlagRB |= DFCS_INACTIVE;
+   }
+
+   DrawFrameControl(hDC, &RectLT, DFC_SCROLL, ScrollDirFlagLT);
+   DrawFrameControl(hDC, &RectRB, DFC_SCROLL, ScrollDirFlagRB);
+}
+
+static LONG FASTCALL
+IntScrollGetObjectId(INT SBType)
+{
+   if (SBType == SB_VERT)
+       return OBJID_VSCROLL;
+   if (SBType == SB_HORZ)
+       return OBJID_HSCROLL;
+   return OBJID_CLIENT;
+}
+
+void
+IntDrawScrollBar(PWND Wnd, HDC DC, INT Bar)
+{
+   //PSBWND pSBWnd;
+   //INT ThumbSize;
+   PTHREADINFO pti;
+   SCROLLBARINFO Info;
+   BOOL Vertical;
+
+   pti = PsGetCurrentThreadWin32Thread();
+
+  /*
+   * Get scroll bar info.
+   */
+   switch (Bar)
+   {
+      case SB_HORZ:
+        Vertical = FALSE;
+        break;
+
+      case SB_VERT:
+        Vertical = TRUE;
+        break;
+
+      case SB_CTL:
+        Vertical = (Wnd->style & SBS_VERT) != 0;
+        break;
+
+      default:
+        return;
+   }
+
+   if (!co_IntGetScrollBarInfo(Wnd, IntScrollGetObjectId(Bar), &Info))
+   {
+      return;
+   }
+
+   if (RECTL_bIsEmptyRect(&Info.rcScrollBar))
+   {
+      return;
+   }
+
+  //ThumbSize = pSBWnd->pSBCalc->pxThumbBottom - pSBWnd->pSBCalc->pxThumbTop;
+
+  /*
+   * Draw the arrows.
+   */
+   if (Info.dxyLineButton)
+   {
+      IntDrawScrollArrows(DC, &Info, Vertical);
+   }
+
+  /*
+   * Draw the interior.
+   */
+   IntDrawScrollInterior(Wnd, DC, Bar, Vertical, &Info);
+
+  /*
+   * If scroll bar has focus, reposition the caret.
+   */
+   if ( Wnd == pti->MessageQueue->spwndFocus && Bar == SB_CTL )
+   {
+      if (Vertical)
+      {
+          co_IntSetCaretPos(Info.rcScrollBar.top + 1, Info.dxyLineButton + 1);
+      }
+      else
+      {
+          co_IntSetCaretPos(Info.dxyLineButton + 1, Info.rcScrollBar.top + 1);
+      }
+   }
+}
+
+
 LRESULT APIENTRY
 ScrollBarWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
 {
Index: win32ss/user/ntuser/userfuncs.h
===================================================================
--- win32ss/user/ntuser/userfuncs.h	(revision 68595)
+++ win32ss/user/ntuser/userfuncs.h	(working copy)
@@ -97,14 +97,11 @@
 VOID FASTCALL IntSetWindowState(PWND, UINT);
 VOID FASTCALL IntClearWindowState(PWND, UINT);
 PTHREADINFO FASTCALL IntTID2PTI(HANDLE);
+HBRUSH FASTCALL GetControlBrush(PWND pwnd,HDC  hdc,UINT ctlType);
 
 /*************** MESSAGE.C ***************/
 
-BOOL FASTCALL
-UserPostMessage(HWND Wnd,
-        UINT Msg,
-        WPARAM wParam,
-        LPARAM lParam);
+BOOL FASTCALL UserPostMessage(HWND Wnd,UINT Msg, WPARAM wParam, LPARAM lParam);
 
 /*************** WINDOW.C ***************/
 
@@ -121,12 +118,19 @@
 BOOL FASTCALL UserSetMenuDefaultItem(PMENU Menu, UINT uItem, UINT fByPos);
 BOOL FASTCALL UserDestroyMenu(HMENU hMenu);
 
-/*************** SCROLLBAR.C ***************/
-
-DWORD FASTCALL co_UserShowScrollBar(PWND Wnd, int nBar, BOOL fShowH, BOOL fShowV);
-
 /************** NONCLIENT **************/
 
 VOID FASTCALL DefWndDoSizeMove(PWND pwnd, WORD wParam);
+LRESULT NC_DoNCPaint(PWND,HDC,INT);
 
+/************** DEFWND **************/
+
+#define DCF_REDRAWHUNGWND 0x20000000
+
+HBRUSH FASTCALL DefWndControlColor(HDC hDC,UINT ctlType);
+LRESULT NC_HandleNCActivate( PWND Wnd, WPARAM wParam, LPARAM lParam );
+LRESULT NC_HandleNCCalcSize( PWND wnd, WPARAM wparam, RECTL *winRect );
+VOID NC_DrawFrame( HDC hDC, RECT *CurrentRect, BOOL Active, DWORD Style, DWORD ExStyle);
+VOID UserDrawCaptionBar( PWND pWnd, HDC hDC, INT Flags);
+
 /* EOF */
Index: win32ss/user/ntuser/winpos.h
===================================================================
--- win32ss/user/ntuser/winpos.h	(revision 68595)
+++ win32ss/user/ntuser/winpos.h	(working copy)
@@ -69,3 +69,5 @@
 BOOL FASTCALL IntScreenToClient(PWND,LPPOINT);
 BOOL FASTCALL IntClientToScreen(PWND,LPPOINT);
 BOOL FASTCALL IntGetWindowRect(PWND,RECTL*);
+BOOL UserHasWindowEdge(DWORD,DWORD);
+VOID UserGetWindowBorders(DWORD,DWORD,SIZE*,BOOL);
Index: win32ss/user/ntuser/winsta.c
===================================================================
--- win32ss/user/ntuser/winsta.c	(revision 68595)
+++ win32ss/user/ntuser/winsta.c	(working copy)
@@ -297,6 +297,9 @@
    /* Setup the icons */
    co_IntSetWndIcons();
 
+   /* Setup Menu */
+   MenuInit();
+
    /* Show the desktop */
    pdesk = IntGetActiveDesktop();
    ASSERT(pdesk);
Index: win32ss/user/user32/windows/defwnd.c
===================================================================
--- win32ss/user/user32/windows/defwnd.c	(revision 68595)
+++ win32ss/user/user32/windows/defwnd.c	(working copy)
@@ -549,9 +549,12 @@
 
     switch (Msg)
     {
-	case WM_NCPAINT:
+/*	case WM_NCPAINT:
 	{
-            return DefWndNCPaint(hWnd, (HRGN)wParam, -1);
+	    NtUserxSetWindowState(pWnd, 16);
+            DefWndNCPaint(hWnd, (HRGN)wParam, -1);
+            NtUserxClearWindowState(pWnd, 16);
+            return 0;
         }
 
         case WM_NCCALCSIZE:
@@ -558,7 +561,7 @@
         {
             return DefWndNCCalcSize(hWnd, (BOOL)wParam, (RECT*)lParam);
         }
-
+*/
         case WM_POPUPSYSTEMMENU:
         {
             /* This is an undocumented message used by the windows taskbar to
@@ -570,12 +573,12 @@
                                LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL);
             return 0;
         }
-
+/*
         case WM_NCACTIVATE:
         {
             return DefWndNCActivate(hWnd, wParam, lParam);
         }
-
+*/
         case WM_NCHITTEST:
         {
             POINT Point;
@@ -1201,6 +1204,11 @@
 /* Move to Win32k !*/
         case WM_SHOWWINDOW:
             if (!lParam) break; // Call when it is necessary.
+        case WM_NCUAHDRAWCAPTION:
+        case WM_NCUAHDRAWFRAME:
+        case WM_NCPAINT:
+        case WM_NCACTIVATE:
+        case WM_NCCALCSIZE:
         case WM_SYNCPAINT:
         case WM_SETREDRAW:
         case WM_CLIENTSHUTDOWN:
Index: win32ss/user/user32/windows/menu.c
===================================================================
--- win32ss/user/user32/windows/menu.c	(revision 68595)
+++ win32ss/user/user32/windows/menu.c	(working copy)
@@ -121,8 +121,8 @@
 #define GET_DWORD(ptr) (*(DWORD *)(ptr))
 #endif
 
-HFONT hMenuFont = NULL;
-HFONT hMenuFontBold = NULL;
+static HFONT hMenuFont = NULL;
+static HFONT hMenuFontBold = NULL;
 
 /* Dimension of the menu bitmaps */
 static HBITMAP BmpSysMenu = NULL;
@@ -4422,7 +4422,7 @@
       ERR("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n");
       return FALSE;
     }
-
+    ERR("User32 MenuInit()\n");
     hMenuFont = CreateFontIndirectW(&ncm.lfMenuFont);
     if(hMenuFont == NULL)
     {
Index: win32ss/user/user32/windows/nonclient.c
===================================================================
--- win32ss/user/user32/windows/nonclient.c	(revision 68595)
+++ win32ss/user/user32/windows/nonclient.c	(working copy)
@@ -275,8 +275,13 @@
    DWORD Style, ExStyle;
    HWND Parent;
    RECT ClientRect, WindowRect, CurrentRect, TempRect;
+   PWND pWnd;
 
-   if (!IsWindowVisible(hWnd))
+   pWnd = ValidateHwnd(hWnd);
+
+   if (!IsWindowVisible(hWnd) ||
+       (pWnd->state & WNDS_NONCPAINT && !(pWnd->state & WNDS_FORCEMENUDRAW)) ||
+        EqualRect(&pWnd->rcWindow, &pWnd->rcClient) )
       return 0;
 
    Style = GetWindowLongPtrW(hWnd, GWL_STYLE);
