[ros-diffs] [jimtabor] 23525: - DrawCaption - Patch by Saveliy Tretiakov, new NtUserDrawCaption implementation. See URL for more details, http://www.reactos.org/archives/public/ros-dev/2006-July/008575.html

jimtabor at svn.reactos.org jimtabor at svn.reactos.org
Tue Aug 8 22:00:54 CEST 2006


Author: jimtabor
Date: Wed Aug  9 00:00:53 2006
New Revision: 23525

URL: http://svn.reactos.org/svn/reactos?rev=23525&view=rev
Log:
- DrawCaption
  - Patch by Saveliy Tretiakov, new NtUserDrawCaption implementation.
    See URL for more details, http://www.reactos.org/archives/public/ros-dev/2006-July/008575.html


Modified:
    trunk/reactos/dll/win32/user32/windows/nonclient.c
    trunk/reactos/include/reactos/win32k/ntuser.h
    trunk/reactos/subsystems/win32/win32k/include/intgdi.h
    trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
    trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
    trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
    trunk/reactos/subsystems/win32/win32k/objects/stockobj.c

Modified: trunk/reactos/dll/win32/user32/windows/nonclient.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/user32/windows/nonclient.c?rev=23525&r1=23524&r2=23525&view=diff
==============================================================================
--- trunk/reactos/dll/win32/user32/windows/nonclient.c (original)
+++ trunk/reactos/dll/win32/user32/windows/nonclient.c Wed Aug  9 00:00:53 2006
@@ -1097,230 +1097,8 @@
 BOOL WINAPI
 DrawCaption(HWND hWnd, HDC hDC, LPCRECT lprc, UINT uFlags)
 {
-    NONCLIENTMETRICSW nclm;
-    BOOL result = FALSE;
-    RECT r = *lprc;
-    UINT VCenter = 0, Padding = 0, Height;
-    ULONG Style;
-    WCHAR buffer[256];
-    HFONT hFont = NULL;
-    HFONT hOldFont = NULL;
-    HBRUSH OldBrush = NULL;
-    HDC MemDC = NULL;
-    int ButtonWidth;
-    COLORREF OldTextColor;
-
-#ifdef DOUBLE_BUFFER_CAPTION
-    HBITMAP MemBMP = NULL, OldBMP = NULL;
-
-    MemDC = CreateCompatibleDC(hDC);
-    if (! MemDC) goto cleanup;
-    MemBMP = CreateCompatibleBitmap(hDC, lprc->right - lprc->left, lprc->bottom - lprc->top);
-    if (! MemBMP) goto cleanup;
-    OldBMP = SelectObject(MemDC, MemBMP);
-    if (! OldBMP) goto cleanup;
-#else
-    MemDC = hDC;
-
-    OffsetViewportOrgEx(MemDC, lprc->left, lprc->top, NULL);
-#endif
-
-    Style = GetWindowLongW(hWnd, GWL_STYLE);
-
-    /* Windows behaves like this */
-    Height = GetSystemMetrics(SM_CYCAPTION) - 1;
-
-    VCenter = (lprc->bottom - lprc->top) / 2;
-    Padding = VCenter - (Height / 2);
-
-    r.left = Padding;
-    r.right = r.left + (lprc->right - lprc->left);
-    r.top = Padding;
-    r.bottom = r.top + (Height / 2);
-
-    // Draw the caption background
-    if (uFlags & DC_INBUTTON)
-    {
-        OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_BTNFACE : COLOR_BTNSHADOW) );
-        if (! OldBrush) goto cleanup;
-        if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
-    }
-    else
-    {
-        if (uFlags & DC_GRADIENT)
-        {
-          static GRADIENT_RECT gcap = {0, 1};
-		  TRIVERTEX vert[2];
-          COLORREF Colors[2];
-          LONG xx;
-
-          r.right = (lprc->right - lprc->left);
-          if (uFlags & DC_SMALLCAP)
-            ButtonWidth = GetSystemMetrics(SM_CXSMSIZE) - 2;
-          else
-            ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2;
-
-          //if (Style & WS_SYSMENU)
-          //{
-          //  r.right -= 3 + ButtonWidth;
-          //  if (! (uFlags & DC_SMALLCAP))
-          //  {
-          //    if(Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
-          //      r.right -= 2 + 2 * ButtonWidth;
-          //    else
-          //      r.right -= 2;
-          //    r.right -= 2;
-          //  }
-          //}
-
-          Colors[0] = GetSysColor((uFlags & DC_ACTIVE) ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);
-          Colors[1] = GetSysColor((uFlags & DC_ACTIVE) ? COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION);
-
-          vert[0].x = r.left;
-          vert[0].y = 0;
-          vert[0].Red = GetRValue(Colors[0]) << 8;
-          vert[0].Green = GetGValue(Colors[0]) << 8;
-          vert[0].Blue = GetBValue(Colors[0]) << 8;
-          vert[0].Alpha = 0;
-
-          vert[1].x = r.right;
-          vert[1].y = lprc->bottom - lprc->top;
-          vert[1].Red = GetRValue(Colors[1]) << 8;
-          vert[1].Green = GetGValue(Colors[1]) << 8;
-          vert[1].Blue = GetBValue(Colors[1]) << 8;
-          vert[1].Alpha = 0;
-
-          GdiGradientFill(MemDC, vert, 2, &gcap, 1, GRADIENT_FILL_RECT_V);
-
-          if ((uFlags & DC_ICON) && (Style & WS_SYSMENU) && !(uFlags & DC_SMALLCAP))
-          {
-            r.top --;
-			SetBkMode( MemDC, TRANSPARENT );
-			xx = GetSystemMetrics(SM_CXSIZE) + Padding;
-            if (UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE))
-              r.left += xx;
-            r.top ++;
-          }
-
-          if(OldBrush)
-          {
-            SelectObject(MemDC, OldBrush);
-            OldBrush = NULL;
-          }
-          //xx = lprc->right - lprc->left - r.right;
-          //if(xx > 0)
-          //{
-          //  OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION));
-          //  if (!OldBrush) goto cleanup;
-          //  PatBlt(MemDC, r.right, 0, xx, lprc->bottom - lprc->top, PATCOPY);
-          //}
-        }
-        else
-        {
-            OldBrush = SelectObject(MemDC, GetSysColorBrush(uFlags & DC_ACTIVE ? COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION) );
-            if (! OldBrush) goto cleanup;
-            if (! PatBlt(MemDC, 0, 0, lprc->right - lprc->left, lprc->bottom - lprc->top, PATCOPY )) goto cleanup;
-        }
-    }
-
-    if ((uFlags & DC_ICON) && !(uFlags & DC_GRADIENT) && (Style & WS_SYSMENU) && !(uFlags & DC_SMALLCAP))
-    {
-        /* For some reason the icon isn't centered correctly... */
-        r.top --;
-        if (UserDrawSysMenuButton(hWnd, MemDC, &r, FALSE))
-          r.left += GetSystemMetrics(SM_CXSIZE) + Padding;
-        r.top ++;
-    }
-    r.top ++;
-    r.left += 2;
-
-    r.bottom = r.top + Height;
-
-  if ((uFlags & DC_TEXT) && (NtUserInternalGetWindowText( hWnd, buffer, sizeof(buffer)/sizeof(buffer[0]) )))
-  {
-    if(!(uFlags & DC_GRADIENT))
-    {
-    r.right = (lprc->right - lprc->left);
-    if (uFlags & DC_SMALLCAP)
-      ButtonWidth = GetSystemMetrics(SM_CXSMSIZE) - 2;
-    else
-      ButtonWidth = GetSystemMetrics(SM_CXSIZE) - 2;
-
-    if (Style & WS_SYSMENU)
-    {
-      r.right -= 3 + ButtonWidth;
-      if (! (uFlags & DC_SMALLCAP))
-      {
-        if(Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
-	      r.right -= 2 + 2 * ButtonWidth;
-        else
-	      r.right -= 2;
-        r.right -= 2;
-      }
-    }
-    }
-
-    nclm.cbSize = sizeof(nclm);
-    if (! SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICSW), &nclm, 0)) goto cleanup;
-
-    SetBkMode( MemDC, TRANSPARENT );
-    if (uFlags & DC_SMALLCAP)
-        hFont = CreateFontIndirectW(&nclm.lfSmCaptionFont);
-    else
-        hFont = CreateFontIndirectW(&nclm.lfCaptionFont);
-
-    if (! hFont) goto cleanup;
-
-    hOldFont = SelectObject(MemDC, hFont);
-    if (! hOldFont) goto cleanup;
-
-    if (uFlags & DC_INBUTTON)
-        OldTextColor = SetTextColor(MemDC, GetSysColor(uFlags & DC_ACTIVE ? COLOR_BTNTEXT : COLOR_GRAYTEXT));
-    else
-        OldTextColor = SetTextColor(MemDC, GetSysColor(uFlags & DC_ACTIVE ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
-
-    DrawTextW(MemDC, buffer, wcslen(buffer), &r, DT_VCENTER | DT_END_ELLIPSIS);
-
-    SetTextColor(MemDC, OldTextColor);
-  }
-
-#if 0
-    if (uFlags & DC_BUTTONS)
-    {
-        // Windows XP draws the caption buttons with DC_BUTTONS
-//        r.left += GetSystemMetrics(SM_CXSIZE) + 1;
-//        UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONCLOSE);
-//        r.right -= GetSystemMetrics(SM_CXSMSIZE) + 1;
-//        UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMIN);
-//        UserDrawCaptionButton( hWnd, hDC, FALSE, DFCS_CAPTIONMAX);
-    }
-#endif
-
-#ifdef DOUBLE_BUFFER_CAPTION
-    if (! BitBlt(hDC, lprc->left, lprc->top, lprc->right - lprc->left, lprc->bottom - lprc->top,
-            MemDC, 0, 0, SRCCOPY)) goto cleanup;
-#endif
-
-    result = TRUE;
-
-    cleanup :
-        if (MemDC)
-        {
-            if (OldBrush) SelectObject(MemDC, OldBrush);
-            if (hOldFont) SelectObject(MemDC, hOldFont);
-            if (hFont) DeleteObject(hFont);
-#ifdef DOUBLE_BUFFER_CAPTION
-            if (OldBMP) SelectObject(MemDC, OldBMP);
-            if (MemBMP) DeleteObject(MemBMP);
-            DeleteDC(MemDC);
-#else
-            OffsetViewportOrgEx(MemDC, -lprc->left, -lprc->top, NULL);
-#endif
-        }
-
-        return result;
-}
-
+ return NtUserDrawCaption(hWnd, hDC, lprc, uFlags);
+}
 
 /*
  * @unimplemented

Modified: trunk/reactos/include/reactos/win32k/ntuser.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/win32k/ntuser.h?rev=23525&r1=23524&r2=23525&view=diff
==============================================================================
--- trunk/reactos/include/reactos/win32k/ntuser.h (original)
+++ trunk/reactos/include/reactos/win32k/ntuser.h Wed Aug  9 00:00:53 2006
@@ -689,12 +689,11 @@
 DWORD
 NTAPI
 NtUserDragObject(
-	   HWND    hwnd1,
-	   HWND    hwnd2,
-	   UINT    u1,
-	   DWORD   dw1,
-	   HCURSOR hc1
-	   );
+   HWND    hwnd1,
+   HWND    hwnd2,
+   UINT    u1,
+   DWORD   dw1,
+   HCURSOR hc1);
 
 DWORD
 NTAPI
@@ -704,24 +703,24 @@
   DWORD Unknown2,
   DWORD Unknown3);
 
-DWORD
+BOOL
 NTAPI
 NtUserDrawCaption(
-  DWORD Unknown0,
-  DWORD Unknown1,
-  DWORD Unknown2,
-  DWORD Unknown3);
-
-DWORD
-NTAPI
+   HWND hWnd,
+   HDC hDc,
+   LPCRECT lpRc,
+   UINT uFlags);
+
+DWORD
+STDCALL
 NtUserDrawCaptionTemp(
-  DWORD Unknown0,
-  DWORD Unknown1,
-  DWORD Unknown2,
-  DWORD Unknown3,
-  DWORD Unknown4,
-  DWORD Unknown5,
-  DWORD Unknown6);
+   DWORD Unknown0,
+   DWORD Unknown1,
+   DWORD Unknown2,
+   DWORD Unknown3,
+   DWORD Unknown4,
+   DWORD Unknown5,
+   DWORD Unknown6);
 
 BOOL
 NTAPI

Modified: trunk/reactos/subsystems/win32/win32k/include/intgdi.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/include/intgdi.h?rev=23525&r1=23524&r2=23525&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/intgdi.h (original)
+++ trunk/reactos/subsystems/win32/win32k/include/intgdi.h Wed Aug  9 00:00:53 2006
@@ -188,11 +188,17 @@
 BOOL FASTCALL
 IntGetSysColorBrushes(HBRUSH *Brushes, UINT nBrushes);
 
+HGDIOBJ FASTCALL
+IntGetSysColorBrush(INT Object);
+
 BOOL FASTCALL
 IntGetSysColorPens(HPEN *Pens, UINT nPens);
 
 BOOL FASTCALL
 IntGetSysColors(COLORREF *Colors, UINT nColors);
+
+DWORD FASTCALL
+IntGetSysColor(INT nIndex);
 
 /* Other Stuff */
 

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c?rev=23525&r1=23524&r2=23525&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/cursoricon.c Wed Aug  9 00:00:53 2006
@@ -72,7 +72,6 @@
 }
 
 
-static
 PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon)
 {
    PCURICON_OBJECT CurIcon;
@@ -1346,6 +1345,191 @@
                         (Rop3), 0)
 #endif /* STRETCH_CAN_SRCCOPY_ONLY */
 
+BOOL 
+UserDrawIconEx(
+   HDC hDc,
+   INT xLeft,
+   INT yTop,
+   PCURICON_OBJECT pIcon,
+   INT cxWidth,
+   INT cyHeight,
+   UINT istepIfAniCur,
+   HBRUSH hbrFlickerFreeDraw,
+   UINT diFlags)
+{
+   BOOL Ret = FALSE;
+   HBITMAP hbmMask, hbmColor;
+   BITMAP bmpMask, bmpColor;
+   COLORREF oldFg, oldBg;
+   BOOL DoFlickerFree;
+   INT nStretchMode;
+   SIZE IconSize;
+        
+   HDC hdcOff;
+   HGDIOBJ hOldOffBrush = 0;
+   HGDIOBJ hOldOffBmp = 0;
+   HBITMAP hbmOff = 0;
+   HDC hdcMem = 0;
+   HGDIOBJ hOldMem;
+   
+   hbmMask = pIcon->IconInfo.hbmMask;
+   hbmColor = pIcon->IconInfo.hbmColor;
+
+   if(istepIfAniCur)
+      DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
+
+   if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
+   {
+      return FALSE;
+   }
+
+   if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
+   {
+      return FALSE;
+   }
+   
+   if(hbmColor)
+   {
+      IconSize.cx = bmpColor.bmWidth;
+      IconSize.cy = bmpColor.bmHeight;
+   }
+   else
+   {
+      IconSize.cx = bmpMask.bmWidth;
+      IconSize.cy = bmpMask.bmHeight / 2;
+   }
+
+   if(!diFlags)
+      diFlags = DI_NORMAL;
+
+   if(!cxWidth)
+      cxWidth = ((diFlags & DI_DEFAULTSIZE) ? 
+         UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
+   
+   if(!cyHeight)
+      cyHeight = ((diFlags & DI_DEFAULTSIZE) ? 
+         UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
+
+   DoFlickerFree = (hbrFlickerFreeDraw && 
+      (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH));
+
+   if(DoFlickerFree)
+   {
+      RECT r;
+      r.right = cxWidth;
+      r.bottom = cyHeight;
+
+      hdcOff = NtGdiCreateCompatibleDC(hDc);
+      if(!hdcOff)
+      {
+         DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
+         return FALSE;
+      }
+
+      hbmOff = NtGdiCreateCompatibleBitmap(hDc, cxWidth, cyHeight);
+      if(!hbmOff)
+      {
+         DPRINT1("NtGdiCreateCompatibleBitmap() failed!\n");
+         goto cleanup;
+      }
+      
+      hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
+      if(!hOldOffBrush)
+      {
+         DPRINT1("NtGdiSelectObject() failed!\n");
+         goto cleanup;
+      }
+      
+      hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
+      if(!hOldOffBmp)
+      {
+         DPRINT1("NtGdiSelectObject() failed!\n");
+         goto cleanup;
+      }
+      
+      NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
+   }
+   else hdcOff = hDc;
+   
+   hdcMem = NtGdiCreateCompatibleDC(hDc);
+   if(!hdcMem)
+   {
+      DPRINT1("NtGdiCreateCompatibleDC() failed!\n");
+      goto cleanup;
+   }
+
+   nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
+
+   oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
+   oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255));
+
+   if(diFlags & DI_MASK)
+   {
+      hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
+      if(!hOldMem)
+      {
+         DPRINT("NtGdiSelectObject() failed!\n");
+         goto cleanup;
+      }
+
+      DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
+                   (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
+                   0, 0, IconSize.cx, IconSize.cy,
+                   ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
+
+      if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) 
+         && (diFlags & DI_IMAGE))
+      {
+         DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
+                      (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
+                      0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT,
+                      FALSE);
+
+         diFlags &= ~DI_IMAGE;
+      }
+      
+      NtGdiSelectObject(hdcMem, hOldMem);
+   }
+   
+   if(diFlags & DI_IMAGE)
+   {
+      hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
+
+      DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
+                   (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
+                   0, (hbmColor ? 0 : IconSize.cy), IconSize.cx, IconSize.cy,
+                   ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY),
+                   NULL != hbmColor);
+
+      NtGdiSelectObject(hdcMem, hOldMem);
+   }
+
+   if(DoFlickerFree)
+   {
+      NtGdiBitBlt(hDc, xLeft, yTop, cxWidth, 
+         cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
+   }
+   
+   NtGdiSetTextColor(hdcOff, oldFg);
+   NtGdiSetBkColor(hdcOff, oldBg);
+   NtGdiSetStretchBltMode(hdcOff, nStretchMode);
+   
+   Ret = TRUE;
+     
+cleanup:
+   if(DoFlickerFree)
+   {
+
+      if(hOldOffBmp) NtGdiSelectObject(hdcOff, hOldOffBmp);
+      if(hOldOffBrush) NtGdiSelectObject(hdcOff, hOldOffBrush);
+      if(hbmOff) NtGdiDeleteObject(hbmOff);
+      if(hdcOff) NtGdiDeleteObjectApp(hdcOff);
+   }
+   
+   if(hdcMem) NtGdiDeleteObjectApp(hdcMem);
+   return Ret;
+}
+
 /*
  * @implemented
  */
@@ -1364,167 +1548,29 @@
    DWORD Unknown0,
    DWORD Unknown1)
 {
-   PCURICON_OBJECT CurIcon;
-   PWINSTATION_OBJECT WinSta;
-   HBITMAP hbmMask, hbmColor;
-   BITMAP bmpMask, bmpColor;
-   BOOL DoFlickerFree;
-   SIZE IconSize;
-   COLORREF oldFg, oldBg;
-   HDC hdcMem, hdcOff = (HDC)0;
-   HBITMAP hbmOff = (HBITMAP)0;
-   HGDIOBJ hOldOffBrush = 0, hOldOffBmp = 0, hOldMem;
-   BOOL Ret = FALSE;
-   INT nStretchMode;
-
-   DECLARE_RETURN(BOOL);
+   PCURICON_OBJECT pIcon;
+   BOOL Ret;
 
    DPRINT("Enter NtUserDrawIconEx\n");
    UserEnterExclusive();
-
-   WinSta = IntGetWinStaObj();
-   if(WinSta == NULL)
-   {
-      RETURN( FALSE);
-   }
-
-   if (!(CurIcon = UserGetCurIconObject(hIcon)))
-   {
-      ObDereferenceObject(WinSta);
-      RETURN(FALSE);
-   }
-   
-   hbmMask = CurIcon->IconInfo.hbmMask;
-   hbmColor = CurIcon->IconInfo.hbmColor;
-
-   if(istepIfAniCur)
-      DPRINT1("NtUserDrawIconEx: istepIfAniCur is not supported!\n");
-
-   if(!hbmMask || !IntGdiGetObject(hbmMask, sizeof(BITMAP), &bmpMask))
-      goto done;
-
-   if(hbmColor && !IntGdiGetObject(hbmColor, sizeof(BITMAP), &bmpColor))
-      goto done;
-
-   if(hbmColor)
-   {
-      IconSize.cx = bmpColor.bmWidth;
-      IconSize.cy = bmpColor.bmHeight;
-   }
-   else
-   {
-      IconSize.cx = bmpMask.bmWidth;
-      IconSize.cy = bmpMask.bmHeight / 2;
-   }
-
-   if(!diFlags)
-      diFlags = DI_NORMAL;
-
-   if(!cxWidth)
-      cxWidth = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CXICON) : IconSize.cx);
-   if(!cyHeight)
-      cyHeight = ((diFlags & DI_DEFAULTSIZE) ? UserGetSystemMetrics(SM_CYICON) : IconSize.cy);
-
-   DoFlickerFree = (hbrFlickerFreeDraw && (NtGdiGetObjectType(hbrFlickerFreeDraw) == OBJ_BRUSH));
-
-   if(DoFlickerFree)
-   {
-      RECT r;
-      r.right = cxWidth;
-      r.bottom = cyHeight;
-
-      hdcOff = NtGdiCreateCompatibleDC(hdc);
-      if(!hdcOff)
-         goto done;
-
-      hbmOff = NtGdiCreateCompatibleBitmap(hdc, cxWidth, cyHeight);
-      if(!hbmOff)
-      {
-         NtGdiDeleteObjectApp(hdcOff);
-         goto done;
-      }
-      hOldOffBrush = NtGdiSelectObject(hdcOff, hbrFlickerFreeDraw);
-      hOldOffBmp = NtGdiSelectObject(hdcOff, hbmOff);
-      NtGdiPatBlt(hdcOff, 0, 0, r.right, r.bottom, PATCOPY);
-      NtGdiSelectObject(hdcOff, hbmOff);
-   }
-
-   hdcMem = NtGdiCreateCompatibleDC(hdc);
-   if(!hdcMem)
-      goto cleanup;
-
-   if(!DoFlickerFree)
-      hdcOff = hdc;
-
-   nStretchMode = NtGdiSetStretchBltMode(hdcOff, STRETCH_DELETESCANS);
-
-   oldFg = NtGdiSetTextColor(hdcOff, RGB(0, 0, 0));
-   oldBg = NtGdiSetBkColor(hdcOff, RGB(255, 255, 255));
-
-   if(diFlags & DI_MASK)
-   {
-      hOldMem = NtGdiSelectObject(hdcMem, hbmMask);
-
-      DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
-                   (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
-                   0, 0, IconSize.cx, IconSize.cy,
-                   ((diFlags & DI_IMAGE) ? SRCAND : SRCCOPY), FALSE);
-
-      if(!hbmColor && (bmpMask.bmHeight == 2 * bmpMask.bmWidth) && (diFlags & DI_IMAGE))
-      {
-         DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
-                      (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
-                      0, IconSize.cy, IconSize.cx, IconSize.cy, SRCINVERT,
-                      FALSE);
-
-         diFlags &= ~DI_IMAGE;
-      }
-      NtGdiSelectObject(hdcMem, hOldMem);
-   }
-
-   if(diFlags & DI_IMAGE)
-   {
-      hOldMem = NtGdiSelectObject(hdcMem, (hbmColor ? hbmColor : hbmMask));
-
-      DoStretchBlt(hdcOff, (DoFlickerFree ? 0 : xLeft),
-                   (DoFlickerFree ? 0 : yTop), cxWidth, cyHeight, hdcMem,
-                   0, (hbmColor ? 0 : IconSize.cy), IconSize.cx, IconSize.cy,
-                   ((diFlags & DI_MASK) ? SRCINVERT : SRCCOPY),
-                   NULL != hbmColor);
-
-      NtGdiSelectObject(hdcMem, hOldMem);
-   }
-
-   if(DoFlickerFree)
-      NtGdiBitBlt(hdc, xLeft, yTop, cxWidth, cyHeight, hdcOff, 0, 0, SRCCOPY, 0, 0);
-
-   NtGdiSetTextColor(hdcOff, oldFg);
-   NtGdiSetBkColor(hdcOff, oldBg);
-
-   NtGdiSetStretchBltMode(hdcOff, nStretchMode);
-
-   Ret = TRUE;
-
-cleanup:
-   if(DoFlickerFree)
-   {
-
-      NtGdiSelectObject(hdcOff, hOldOffBmp);
-      NtGdiSelectObject(hdcOff, hOldOffBrush);
-      NtGdiDeleteObject(hbmOff);
-      NtGdiDeleteObjectApp(hdcOff);
-   }
-   if(hdcMem)
-      NtGdiDeleteObjectApp(hdcMem);
-
-done:
-   ObDereferenceObject(WinSta);
-
-   RETURN( Ret);
-
-CLEANUP:
-   DPRINT("Leave NtUserDrawIconEx, ret=%i\n",_ret_);
+   
+   if(!(pIcon = UserGetCurIconObject(hIcon)))
+   {
+      DPRINT1("UserGetCurIconObject() failed!\n");
+      UserLeave();
+      return FALSE;
+   }
+   
+   Ret = UserDrawIconEx(hdc,
+      xLeft,
+      yTop,
+      pIcon,
+      cxWidth,
+      cyHeight,
+      istepIfAniCur,
+      hbrFlickerFreeDraw,
+      diFlags);
+
    UserLeave();
-   END_CLEANUP;
-}
-
+   return Ret;
+}

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c?rev=23525&r1=23524&r2=23525&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/ntstubs.c Wed Aug  9 00:00:53 2006
@@ -181,19 +181,6 @@
 DWORD
 STDCALL
 NtUserDrawAnimatedRects(
-   DWORD Unknown0,
-   DWORD Unknown1,
-   DWORD Unknown2,
-   DWORD Unknown3)
-{
-   UNIMPLEMENTED
-
-   return 0;
-}
-
-DWORD
-STDCALL
-NtUserDrawCaption(
    DWORD Unknown0,
    DWORD Unknown1,
    DWORD Unknown2,

Modified: trunk/reactos/subsystems/win32/win32k/ntuser/painting.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntuser/painting.c?rev=23525&r1=23524&r2=23525&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/painting.c (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/painting.c Wed Aug  9 00:00:53 2006
@@ -1372,4 +1372,392 @@
    END_CLEANUP;
 }
 
+/* Don't know where to put this */
+BOOL FASTCALL IntGdiGradientFill(DC *dc, PTRIVERTEX pVertex, ULONG uVertex, PVOID pMesh, ULONG uMesh, ULONG ulMode);
+ULONG FASTCALL IntSystemParametersInfo(UINT uiAction, UINT uiParam, PVOID pvParam, UINT fWinIni);
+BOOL UserDrawIconEx(HDC hDc, INT xLeft, INT yTop, PCURICON_OBJECT pIcon, INT cxWidth, 
+   INT cyHeight, UINT istepIfAniCur, HBRUSH hbrFlickerFreeDraw, UINT diFlags);
+PCURICON_OBJECT FASTCALL UserGetCurIconObject(HCURSOR hCurIcon);
+
+BOOL
+IntDrawSysMenuButton(
+   PWINDOW_OBJECT pWnd, 
+   HDC hDc, 
+   LPRECT lpRc, 
+   BOOL Down)
+{
+   HICON hIcon;
+   PCURICON_OBJECT pIcon;
+   
+   ASSERT(pWnd && lpRc);
+   
+   /* Get the icon to draw. We don't care about WM_GETICON here. */
+   
+   hIcon = pWnd->Class->hIconSm;
+   
+   if(!hIcon)
+   {
+      DPRINT("Wnd class has no small icon.\n");
+      hIcon = pWnd->Class->hIcon;
+   }
+   
+   if(!hIcon)
+   {
+      DPRINT("Wnd class hasn't any icon.\n");
+      //FIXME: Draw "winlogo" icon. 
+      return FALSE;
+   }
+   
+   if(!(pIcon = UserGetCurIconObject(hIcon)))
+   {
+      DPRINT1("UserGetCurIconObject() failed!\n");
+      return FALSE;
+   }
+
+   return UserDrawIconEx(hDc, lpRc->left, lpRc->top, pIcon,
+                        UserGetSystemMetrics(SM_CXSMICON), 
+                        UserGetSystemMetrics(SM_CYSMICON),
+                        0, NULL, DI_NORMAL);
+}
+
+BOOL
+IntDrawCaptionText(HDC hDc,
+   const PUNICODE_STRING Text,
+   const LPRECT lpRc,
+   UINT uFlags)
+{
+   HFONT hOldFont = NULL, hFont = NULL;
+   COLORREF OldTextColor;
+   NONCLIENTMETRICS nclm;
+   NTSTATUS Status;
+   INT i;
+   
+   #ifndef NDEBUG
+   DPRINT("%s:", __FUNCTION__);
+   for(i = 0; i < Text->Length/sizeof(WCHAR); i++)
+      DbgPrint("%C", Text->Buffer[i]);
+   DbgPrint(", %d\n", Text->Length/sizeof(WCHAR));
+   #endif
+   
+   nclm.cbSize = sizeof(nclm);
+   if(!IntSystemParametersInfo(SPI_GETNONCLIENTMETRICS,
+      sizeof(NONCLIENTMETRICS), &nclm, 0)) 
+   {
+      DPRINT1("%s: IntSystemParametersInfo() failed!\n", __FUNCTION__);
+      return FALSE;
+   }
+
+   NtGdiSetBkMode(hDc, TRANSPARENT);
+
+   if(uFlags & DC_SMALLCAP)
+      Status = TextIntCreateFontIndirect(&nclm.lfSmCaptionFont, &hFont);
+   else Status = TextIntCreateFontIndirect(&nclm.lfCaptionFont, &hFont);
+
+   if(!NT_SUCCESS(Status)) 
+   {
+      DPRINT1("%s: TextIntCreateFontIndirect() failed! Status: 0x%x\n",
+         __FUNCTION__, Status);
+      return FALSE;
+   }
+
+   hOldFont = NtGdiSelectObject(hDc, hFont);
+   if(!hOldFont) 
+   {
+      DPRINT1("%s: SelectObject() failed!\n", __FUNCTION__);
+      NtGdiDeleteObject(hFont);
+      return FALSE;
+   }
+
+   if(uFlags & DC_INBUTTON)
+      OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(COLOR_BTNTEXT));
+   else OldTextColor = NtGdiSetTextColor(hDc, IntGetSysColor(uFlags & DC_ACTIVE
+         ? COLOR_CAPTIONTEXT : COLOR_INACTIVECAPTIONTEXT));
+   
+   //FIXME: If string doesn't fit to rc, truncate it and add ellipsis.
+   
+   NtGdiTextOut(hDc, lpRc->left, 
+      lpRc->top, Text->Buffer, 
+      Text->Length/sizeof(WCHAR));
+   
+   NtGdiSetTextColor(hDc, OldTextColor);
+   NtGdiSelectObject(hDc, hOldFont);
+   NtGdiDeleteObject(hFont);
+   
+   return TRUE;
+}
+
+BOOL UserDrawCaption(
+   PWINDOW_OBJECT pWnd,
+   HDC hDc,
+   LPCRECT lpRc,
+   UINT uFlags)
+{
+   BOOL Ret = FALSE;
+   HBITMAP hMemBmp = NULL, hOldBmp = NULL;
+   HBRUSH hOldBrush = NULL;
+   HDC hMemDc = NULL;
+   ULONG Height;
+   UINT VCenter = 0, Padding = 0;
+   RECT r = *lpRc;
+   LONG ButtonWidth, IconWidth;
+   BOOL HasIcon;
+   
+   ASSERT(pWnd != NULL);
+
+   hMemBmp = NtGdiCreateCompatibleBitmap(hDc, 
+      lpRc->right - lpRc->left, 
+      lpRc->bottom - lpRc->top);
+
+   if(!hMemBmp)
+   {
+      DPRINT1("%s: NtGdiCreateCompatibleBitmap() failed!\n", __FUNCTION__);
+      return FALSE;
+   }
+
+   hMemDc = NtGdiCreateCompatibleDC(hDc);
+   if(!hMemDc)
+   {
+      DPRINT1("%s: NtGdiCreateCompatibleDC() failed!\n", __FUNCTION__);
+      goto cleanup;
+   }
+
+   hOldBmp = NtGdiSelectObject(hMemDc, hMemBmp);
+   if(!hOldBmp)
+   {
+      DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+      goto cleanup;
+   }
+
+   Height = UserGetSystemMetrics(SM_CYCAPTION) - 1;
+   VCenter = (lpRc->bottom - lpRc->top) / 2;
+   Padding = VCenter - (Height / 2);
+   HasIcon = (uFlags & DC_ICON) && (pWnd->Style & WS_SYSMENU) 
+      && !(uFlags & DC_SMALLCAP);
+   IconWidth = UserGetSystemMetrics(SM_CXSIZE) + Padding;
+
+   r.left = Padding;
+   r.right = r.left + (lpRc->right - lpRc->left);
+   r.top = Padding;
+   r.bottom = r.top + (Height / 2);
+
+   // Draw the caption background
+   if(uFlags & DC_INBUTTON)
+   {
+      hOldBrush = NtGdiSelectObject(hMemDc, 
+         IntGetSysColorBrush(uFlags & DC_ACTIVE ?
+            COLOR_BTNFACE : COLOR_BTNSHADOW));
+
+      if(!hOldBrush)
+      {
+         DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+         goto cleanup;
+      }
+
+      if(!NtGdiPatBlt(hMemDc, 0, 0,
+         lpRc->right - lpRc->left,
+         lpRc->bottom - lpRc->top,
+         PATCOPY)) 
+      {
+         DPRINT1("%s: NtGdiPatBlt() failed!\n", __FUNCTION__);
+         goto cleanup;
+      }
+      
+      if(HasIcon) r.left+=IconWidth;
+   }
+   else 
+   {
+      r.right = (lpRc->right - lpRc->left);
+      if(uFlags & DC_SMALLCAP)
+         ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
+      else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;
+        
+      hOldBrush = NtGdiSelectObject(hMemDc, 
+         IntGetSysColorBrush(uFlags & DC_ACTIVE ? 
+            COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION));
+   
+      if(!hOldBrush)
+      {
+         DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+         goto cleanup;
+      }
+
+      if(HasIcon && (uFlags & DC_GRADIENT))
+      {
+         NtGdiPatBlt(hMemDc, 0, 0, 
+            IconWidth+1, 
+            lpRc->bottom - lpRc->top, 
+            PATCOPY);
+         r.left+=IconWidth;
+      }
+      else 
+      {
+         NtGdiPatBlt(hMemDc, 0, 0, 
+            lpRc->right - lpRc->left, 
+            lpRc->bottom - lpRc->top, 
+            PATCOPY);
+      }
+         
+      if(uFlags & DC_GRADIENT)
+      {
+         static GRADIENT_RECT gcap = {0, 1};
+         TRIVERTEX vert[2];
+         COLORREF Colors[2];
+         PDC pMemDc;
+
+         if(pWnd->Style & WS_SYSMENU)
+         {
+            r.right -= 3 + ButtonWidth;
+            if(!(uFlags & DC_SMALLCAP))
+            {
+               if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+                  r.right -= 2 + 2 * ButtonWidth;
+               else r.right -= 2;
+               r.right -= 2;
+            }
+            
+            //Draw buttons background
+            if(!NtGdiSelectObject(hMemDc, 
+               IntGetSysColorBrush(uFlags & DC_ACTIVE ? 
+                  COLOR_GRADIENTACTIVECAPTION:COLOR_GRADIENTINACTIVECAPTION)))
+            {
+               DPRINT1("%s: NtGdiSelectObject() failed!\n", __FUNCTION__);
+               goto cleanup;
+            }
+
+            NtGdiPatBlt(hMemDc, 
+               r.right, 
+               0, 
+               lpRc->right - lpRc->left - r.right, 
+               lpRc->bottom - lpRc->top, 
+               PATCOPY);
+         }
+
+         Colors[0] = IntGetSysColor((uFlags & DC_ACTIVE) ? 
+            COLOR_ACTIVECAPTION : COLOR_INACTIVECAPTION);
+
+         Colors[1] = IntGetSysColor((uFlags & DC_ACTIVE) ? 
+            COLOR_GRADIENTACTIVECAPTION : COLOR_GRADIENTINACTIVECAPTION);
+
+         vert[0].x = r.left;
+         vert[0].y = 0;
+         vert[0].Red = (WORD)Colors[0]<<8;
+         vert[0].Green = (WORD)Colors[0] & 0xFF00;
+         vert[0].Blue = (WORD)(Colors[0]>>8) & 0xFF00;
+         vert[0].Alpha = 0;
+
+         vert[1].x = r.right;
+         vert[1].y = lpRc->bottom - lpRc->top;
+         vert[1].Red = (WORD)Colors[1]<<8;
+         vert[1].Green = (WORD)Colors[1] & 0xFF00;
+         vert[1].Blue = (WORD)(Colors[1]>>8) & 0xFF00;
+         vert[1].Alpha = 0;
+            
+         pMemDc = DC_LockDc(hMemDc);
+         if(!pMemDc)
+         {
+            DPRINT1("%s: Can't lock dc!\n", __FUNCTION__);
+            goto cleanup;
+         }
+
+         if(!IntGdiGradientFill(pMemDc, vert, 2, &gcap, 
+            1, GRADIENT_FILL_RECT_H))
+         {
+            DPRINT1("%s: IntGdiGradientFill() failed!\n", __FUNCTION__);
+         }
+
+         DC_UnlockDc(pMemDc);
+      } //if(uFlags & DC_GRADIENT)
+   }
+   
+   if(HasIcon)
+   {
+      r.top ++;
+      r.left -= --IconWidth;
+      IntDrawSysMenuButton(pWnd, hMemDc, &r, FALSE);
+      r.left += IconWidth;
+      r.top --;
+   }
+
+   r.top ++;
+   r.left += 2;
+
+   r.bottom = r.top + Height;
+
+   if((uFlags & DC_TEXT) && pWnd->WindowName.Length)
+   {
+      if(!(uFlags & DC_GRADIENT))
+      {
+         r.right = (lpRc->right - lpRc->left);
+
+         if(uFlags & DC_SMALLCAP) 
+            ButtonWidth = UserGetSystemMetrics(SM_CXSMSIZE) - 2;
+         else ButtonWidth = UserGetSystemMetrics(SM_CXSIZE) - 2;
+
+         if(pWnd->Style & WS_SYSMENU)
+         {
+            r.right -= 3 + ButtonWidth;
+            if(! (uFlags & DC_SMALLCAP))
+            {
+               if(pWnd->Style & (WS_MAXIMIZEBOX | WS_MINIMIZEBOX))
+                  r.right -= 2 + 2 * ButtonWidth;
+               else r.right -= 2;
+               r.right -= 2;
+            }
+         }
+      }
+
+      IntDrawCaptionText(hMemDc, &pWnd->WindowName, &r, uFlags);
+   } 
+
+   if(!NtGdiBitBlt(hDc, lpRc->left, lpRc->top, 
+      lpRc->right - lpRc->left, lpRc->bottom - lpRc->top,
+      hMemDc, 0, 0, SRCCOPY, 0, 0)) 
+   {
+      DPRINT1("%s: NtGdiBitBlt() failed!\n", __FUNCTION__);
+      goto cleanup;
+   }
+
+   Ret = TRUE;
+
+cleanup:
+   if (hOldBrush) NtGdiSelectObject(hMemDc, hOldBrush);
+   if (hOldBmp) NtGdiSelectObject(hMemDc, hOldBmp);
+   if (hMemBmp) NtGdiDeleteObject(hMemBmp);
+   if (hMemDc) NtGdiDeleteObjectApp(hMemDc);
+
+   return Ret;
+}
+
+
+BOOL 
+STDCALL 
+NtUserDrawCaption(HWND hWnd,
+   HDC hDc,
+   LPCRECT lpRc,
+   UINT uFlags)
+{
+   PWINDOW_OBJECT pWnd;
+   RECT SafeRect;
+   BOOL Ret;
+     
+   if(!NT_SUCCESS(MmCopyFromCaller(&SafeRect, lpRc, sizeof(RECT))))
+   {
+      DPRINT1("%s: MmCopyFromCaller failed!", __FUNCTION__); 
+      return FALSE;
+   }
+   
+   UserEnterExclusive();
+   
+   if(!(pWnd = UserGetWindowObject(hWnd)))
+   {
+      UserLeave();
+      return FALSE;
+   }
+   
+   Ret = UserDrawCaption(pWnd, hDc, &SafeRect, uFlags);
+   
+   UserLeave();
+   return Ret;
+}
+
 /* EOF */

Modified: trunk/reactos/subsystems/win32/win32k/objects/stockobj.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/objects/stockobj.c?rev=23525&r1=23524&r2=23525&view=diff
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/stockobj.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/stockobj.c Wed Aug  9 00:00:53 2006
@@ -210,6 +210,12 @@
   return nBrushes > 0;
 }
 
+HGDIOBJ FASTCALL
+IntGetSysColorBrush(INT Object)
+{
+  return ((Object < 0) || (NUM_SYSCOLORS <= Object)) ? NULL : SysColorBrushes[Object];
+}
+
 BOOL FASTCALL
 IntGetSysColorPens(HPEN *Pens, UINT nPens)
 {
@@ -252,6 +258,12 @@
   }
 
   return nColors > 0;
+}
+
+DWORD FASTCALL
+IntGetSysColor(INT nIndex)
+{
+  return ((nIndex < 0) || (NUM_SYSCOLORS <= nIndex)) ? 0 : SysColors[nIndex];
 }
 
 VOID FASTCALL




More information about the Ros-diffs mailing list