[COMCTL32] -Implement taking into account the contents margins from the theme when...
[reactos.git] / reactos / dll / win32 / comctl32 / toolbar.c
index 17f17fd..eeb805b 100644 (file)
@@ -126,6 +126,7 @@ typedef struct
 #ifdef __REACTOS__
     SIZE     szBarPadding;       /* padding values around the toolbar (NOT USED BUT STORED) */
     SIZE     szSpacing;       /* spacing values between buttons */
+    MARGINS  themeMargins;
 #endif
     INT      iTopMargin;      /* the top margin */
     INT      iListGap;        /* default gap between text and image for toolbar with list style */
@@ -253,12 +254,11 @@ static LRESULT TOOLBAR_SetButtonInfo(TOOLBAR_INFO *infoPtr, INT Id,
 
 static inline int default_top_margin(const TOOLBAR_INFO *infoPtr)
 {
-#ifndef __REACTOS__
-    return (infoPtr->dwStyle & TBSTYLE_FLAT ? 0 : TOP_BORDER);
-#else /* r65766 */
-    /* This is the behaviour in comctl32 v6 */
-    return 0;
+#ifdef __REACTOS__
+    if (infoPtr->iVersion == 6)
+        return 0;
 #endif
+    return (infoPtr->dwStyle & TBSTYLE_FLAT ? 0 : TOP_BORDER);
 }
 
 static inline BOOL TOOLBAR_HasDropDownArrows(DWORD exStyle)
@@ -617,6 +617,9 @@ TOOLBAR_DrawString (const TOOLBAR_INFO *infoPtr, RECT *rcText, LPCWSTR lpText,
     COLORREF clrOldBk = 0;
     int oldBkMode = 0;
     UINT state = tbcd->nmcd.uItemState;
+#ifdef __REACTOS__
+    HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
+#endif
 
     /* draw text */
     if (lpText && infoPtr->nMaxTextRows > 0) {
@@ -646,6 +649,25 @@ TOOLBAR_DrawString (const TOOLBAR_INFO *infoPtr, RECT *rcText, LPCWSTR lpText,
            clrOld = SetTextColor (hdc, tbcd->clrText);
        }
 
+#ifdef __REACTOS__
+    if (theme)
+    {
+        int partId = TP_BUTTON;
+        int stateId = TS_NORMAL;
+
+        if (state & CDIS_DISABLED)
+            stateId = TS_DISABLED;
+        else if (state & CDIS_SELECTED)
+            stateId = TS_PRESSED;
+        else if (state & CDIS_CHECKED)
+            stateId = (state & CDIS_HOT) ? TS_HOTCHECKED : TS_HOT;
+        else if (state & CDIS_HOT)
+            stateId = TS_HOT;
+
+        DrawThemeText(theme, hdc, partId, stateId, lpText, -1, infoPtr->dwDTFlags, 0, rcText);
+    }
+    else
+#endif
        DrawTextW (hdc, lpText, -1, rcText, infoPtr->dwDTFlags);
        SetTextColor (hdc, clrOld);
        if ((state & CDIS_MARKED) && !(dwItemCDFlag & TBCDRF_NOMARK))
@@ -925,7 +947,7 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc,
     HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
 
     rc = btnPtr->rect;
-    CopyRect (&rcArrow, &rc);
+    rcArrow = rc;
 
     /* separator - doesn't send NM_CUSTOMDRAW */
     if (btnPtr->fsStyle & BTNS_SEP) {
@@ -979,8 +1001,8 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc,
     /* copy text & bitmap rects after adjusting for drop-down arrow
      * so that text & bitmap is centered in the rectangle not containing
      * the arrow */
-    CopyRect(&rcText, &rc);
-    CopyRect(&rcBitmap, &rc);
+    rcText = rc;
+    rcBitmap = rc;
 
     /* Center the bitmap horizontally and vertically */
     if (dwStyle & TBSTYLE_LIST)
@@ -1007,8 +1029,7 @@ TOOLBAR_DrawButton (const TOOLBAR_INFO *infoPtr, TBUTTON_INFO *btnPtr, HDC hdc,
     /* calculate text position */
     if (lpText)
     {
-        rcText.left += GetSystemMetrics(SM_CXEDGE);
-        rcText.right -= GetSystemMetrics(SM_CXEDGE);
+        InflateRect(&rcText, -GetSystemMetrics(SM_CXEDGE), 0);
         if (dwStyle & TBSTYLE_LIST)
         {
             rcText.left += infoPtr->nBitmapWidth + infoPtr->iListGap + 2;
@@ -1290,9 +1311,7 @@ TOOLBAR_MeasureString(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *btnPtr,
            GetTextExtentPoint32W (hdc, lpText, strlenW (lpText), lpSize);
 
            /* feed above size into the rectangle for DrawText */
-           myrect.left = myrect.top = 0;
-           myrect.right = lpSize->cx;
-           myrect.bottom = lpSize->cy;
+            SetRect(&myrect, 0, 0, lpSize->cx, lpSize->cy);
 
            /* Use DrawText to get true size as drawn (less pesky "&") */
            DrawTextW (hdc, lpText, -1, &myrect, DT_VCENTER | DT_SINGLELINE |
@@ -1688,6 +1707,12 @@ static inline SIZE TOOLBAR_MeasureButton(const TOOLBAR_INFO *infoPtr, SIZE sizeS
                 max(2*GetSystemMetrics(SM_CXEDGE) + sizeString.cx, infoPtr->nBitmapWidth);
         }
     }
+
+#ifdef __REACTOS__
+    sizeButton.cx += infoPtr->themeMargins.cxLeftWidth + infoPtr->themeMargins.cxRightWidth;
+    sizeButton.cy += infoPtr->themeMargins.cyTopHeight + infoPtr->themeMargins.cyBottomHeight;
+#endif
+
     return sizeButton;
 }
 
@@ -1761,6 +1786,7 @@ TOOLBAR_LayoutToolbar(TOOLBAR_INFO *infoPtr)
        if (btnPtr->fsState & TBSTATE_HIDDEN)
        {
            SetRectEmpty (&btnPtr->rect);
+           TOOLBAR_TooltipSetRect(infoPtr, btnPtr);
            continue;
        }
 
@@ -2045,16 +2071,6 @@ TOOLBAR_RelayEvent (HWND hwndTip, HWND hwndMsg, UINT uMsg,
     SendMessageW (hwndTip, TTM_RELAYEVENT, 0, (LPARAM)&msg);
 }
 
-#ifdef __REACTOS__
-static LRESULT
-TOOLBAR_ThemeChanged(HWND hwnd)
-{
-    HTHEME theme = GetWindowTheme(hwnd);
-    CloseThemeData(theme);
-    OpenThemeData(hwnd, themeClass);
-    return 0;
-}
-#endif
 
 static void
 TOOLBAR_TooltipAddTool(const TOOLBAR_INFO *infoPtr, const TBUTTON_INFO *button)
@@ -2736,9 +2752,9 @@ TOOLBAR_CustomizeDialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
                           lpdis->rcItem.right, lpdis->rcItem.bottom);
 
                /* calculate button and text rectangles */
-               CopyRect (&rcButton, &lpdis->rcItem);
+                rcButton = lpdis->rcItem;
                InflateRect (&rcButton, -1, -1);
-               CopyRect (&rcText, &rcButton);
+                rcText = rcButton;
                rcButton.right = rcButton.left + custInfo->tbInfo->nBitmapWidth + 6;
                rcText.left = rcButton.right + 2;
 
@@ -3486,7 +3502,7 @@ TOOLBAR_GetButtonInfoT(const TOOLBAR_INFO *infoPtr, INT Id, LPTBBUTTONINFOW lpTb
                 Str_GetPtrW(lpText, lpTbInfo->pszText, lpTbInfo->cchText);
             else
                 Str_GetPtrWtoA(lpText, (LPSTR)lpTbInfo->pszText, lpTbInfo->cchText);
-        } else
+        } else if (!bUnicode || lpTbInfo->pszText)
             lpTbInfo->pszText[0] = '\0';
     }
     return nIndex;
@@ -4582,8 +4598,13 @@ TOOLBAR_SetButtonSize (TOOLBAR_INFO *infoPtr, LPARAM lParam)
     if (cx == 0) cx = 24;
     if (cy == 0) cy = 22;
 
+#ifdef __REACTOS__
+    cx = max(cx, infoPtr->szPadding.cx + infoPtr->nBitmapWidth + infoPtr->themeMargins.cxLeftWidth + infoPtr->themeMargins.cxRightWidth);
+    cy = max(cy, infoPtr->szPadding.cy + infoPtr->nBitmapHeight + infoPtr->themeMargins.cyTopHeight + infoPtr->themeMargins.cyBottomHeight);
+#else
     cx = max(cx, infoPtr->szPadding.cx + infoPtr->nBitmapWidth);
     cy = max(cy, infoPtr->szPadding.cy + infoPtr->nBitmapHeight);
+#endif
 
     if (cx != infoPtr->nButtonWidth || cy != infoPtr->nButtonHeight ||
         top != infoPtr->iTopMargin)
@@ -4665,17 +4686,16 @@ TOOLBAR_SetDisabledImageList (TOOLBAR_INFO *infoPtr, WPARAM wParam, HIMAGELIST h
 
 
 static LRESULT
-TOOLBAR_SetDrawTextFlags (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+TOOLBAR_SetDrawTextFlags (TOOLBAR_INFO *infoPtr, DWORD mask, DWORD flags)
 {
-    DWORD dwTemp;
+    DWORD old_flags;
 
-    TRACE("hwnd = %p, dwMask = 0x%08x, dwDTFlags = 0x%08x\n", infoPtr->hwndSelf, (DWORD)wParam, (DWORD)lParam);
+    TRACE("hwnd = %p, mask = 0x%08x, flags = 0x%08x\n", infoPtr->hwndSelf, mask, flags);
 
-    dwTemp = infoPtr->dwDTFlags;
-    infoPtr->dwDTFlags =
-       (infoPtr->dwDTFlags & (DWORD)wParam) | (DWORD)lParam;
+    old_flags = infoPtr->dwDTFlags;
+    infoPtr->dwDTFlags = (old_flags & ~mask) | (flags & mask);
 
-    return (LRESULT)dwTemp;
+    return (LRESULT)old_flags;
 }
 
 /* This function differs a bit from what MSDN says it does:
@@ -5249,6 +5269,16 @@ TOOLBAR_SetVersion (TOOLBAR_INFO *infoPtr, INT iVersion)
 {
     INT iOldVersion = infoPtr->iVersion;
 
+#ifdef __REACTOS__
+    /* The v6 control doesn't support changing its version */
+    if (iOldVersion == 6)
+        return iOldVersion;
+
+    /* And a control that is not v6 can't be set to be a v6 one */
+    if (iVersion >= 6)
+        return -1;
+#endif
+
     infoPtr->iVersion = iVersion;
 
     if (infoPtr->iVersion >= 5)
@@ -5435,8 +5465,16 @@ TOOLBAR_Create (HWND hwnd, const CREATESTRUCTW *lpcs)
 
     SystemParametersInfoW (SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
     infoPtr->hFont = infoPtr->hDefaultFont = CreateFontIndirectW (&logFont);
-    
+
+#ifdef __REACTOS__
+    {
+        HTHEME theme = OpenThemeData (hwnd, themeClass);
+        if (theme)
+            GetThemeMargins(theme, NULL, TP_BUTTON, TS_NORMAL, TMT_CONTENTMARGINS, NULL, &infoPtr->themeMargins);
+    }
+#else
     OpenThemeData (hwnd, themeClass);
+#endif
 
     TOOLBAR_CheckStyle (infoPtr);
 
@@ -5706,7 +5744,7 @@ TOOLBAR_LButtonDown (TOOLBAR_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
             RECT arrowRect;
             infoPtr->nOldHit = nHit;
 
-            CopyRect(&arrowRect, &btnPtr->rect);
+            arrowRect = btnPtr->rect;
             arrowRect.left = max(btnPtr->rect.left, btnPtr->rect.right - DDARROW_WIDTH);
 
             /* for EX_DRAWDDARROWS style,  click must be in the drop-down arrow rect */
@@ -6159,7 +6197,11 @@ TOOLBAR_NCCalcSize (HWND hwnd, WPARAM wParam, LPARAM lParam)
 
 
 static LRESULT
+#ifdef __REACTOS__
+TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs, int iVersion)
+#else
 TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs)
+#endif
 {
     TOOLBAR_INFO *infoPtr;
     DWORD styleadd = 0;
@@ -6193,7 +6235,11 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs)
     infoPtr->dwDTFlags = (lpcs->style & TBSTYLE_LIST) ? DT_LEFT | DT_VCENTER | DT_SINGLELINE | DT_END_ELLIPSIS: DT_CENTER | DT_END_ELLIPSIS;
     infoPtr->bAnchor = FALSE; /* no anchor highlighting */
     infoPtr->bDragOutSent = FALSE;
+#ifdef __REACTOS__
+    infoPtr->iVersion = iVersion;
+#else
     infoPtr->iVersion = 0;
+#endif
     infoPtr->hwndSelf = hwnd;
     infoPtr->bDoRedraw = TRUE;
     infoPtr->clrBtnHighlight = CLR_DEFAULT;
@@ -6203,6 +6249,7 @@ TOOLBAR_NCCreate (HWND hwnd, WPARAM wParam, const CREATESTRUCTW *lpcs)
 #ifdef __REACTOS__
     infoPtr->szSpacing.cx = DEFSPACE_CX;
     infoPtr->szSpacing.cy = DEFSPACE_CY;
+    memset(&infoPtr->themeMargins, 0 , sizeof(infoPtr->themeMargins));
 #endif
     infoPtr->iListGap = DEFLISTGAP;
     infoPtr->iTopMargin = default_top_margin(infoPtr);
@@ -6613,8 +6660,22 @@ TOOLBAR_SysColorChange (void)
     return 0;
 }
 
-#ifndef __REACTOS__
+#ifdef __REACTOS__
 /* update theme after a WM_THEMECHANGED message */
+static LRESULT theme_changed (TOOLBAR_INFO *infoPtr)
+{
+    HTHEME theme = GetWindowTheme (infoPtr->hwndSelf);
+    CloseThemeData (theme);
+    OpenThemeData (infoPtr->hwndSelf, themeClass);
+    theme = GetWindowTheme (infoPtr->hwndSelf);
+    if (theme)
+        GetThemeMargins(theme, NULL, TP_BUTTON, TS_NORMAL, TMT_CONTENTMARGINS, NULL, &infoPtr->themeMargins);
+    else
+        memset(&infoPtr->themeMargins, 0 ,sizeof(infoPtr->themeMargins));
+
+    return 0;
+}
+#else
 static LRESULT theme_changed (HWND hwnd)
 {
     HTHEME theme = GetWindowTheme (hwnd);
@@ -6984,7 +7045,11 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
            return TOOLBAR_NCCalcSize (hwnd, wParam, lParam);
 
        case WM_NCCREATE:
+#ifdef __REACTOS__
+           return TOOLBAR_NCCreate (hwnd, wParam, (CREATESTRUCTW*)lParam, 0);
+#else
            return TOOLBAR_NCCreate (hwnd, wParam, (CREATESTRUCTW*)lParam);
+#endif
 
        case WM_NCPAINT:
            return TOOLBAR_NCPaint (hwnd, wParam, lParam);
@@ -7016,10 +7081,9 @@ ToolbarWindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 
        case WM_SYSCOLORCHANGE:
            return TOOLBAR_SysColorChange ();
-            
     case WM_THEMECHANGED:
 #ifdef __REACTOS__
-        return TOOLBAR_ThemeChanged(hwnd);
+            return theme_changed (infoPtr);
 #else
             return theme_changed (hwnd);
 #endif
@@ -7070,6 +7134,40 @@ TOOLBAR_Unregister (void)
     UnregisterClassW (TOOLBARCLASSNAMEW, NULL);
 }
 
+#ifdef __REACTOS__
+static LRESULT WINAPI
+ToolbarV6WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    if (uMsg == WM_NCCREATE)
+        return TOOLBAR_NCCreate (hwnd, wParam, (CREATESTRUCTW*)lParam, 6);
+    else
+        return ToolbarWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+VOID
+TOOLBARv6_Register (void)
+{
+    WNDCLASSW wndClass;
+
+    ZeroMemory (&wndClass, sizeof(WNDCLASSW));
+    wndClass.style         = CS_GLOBALCLASS | CS_DBLCLKS;
+    wndClass.lpfnWndProc   = ToolbarV6WindowProc;
+    wndClass.cbClsExtra    = 0;
+    wndClass.cbWndExtra    = sizeof(TOOLBAR_INFO *);
+    wndClass.hCursor       = LoadCursorW (0, (LPWSTR)IDC_ARROW);
+    wndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1);
+    wndClass.lpszClassName = TOOLBARCLASSNAMEW;
+
+    RegisterClassW (&wndClass);
+}
+
+VOID
+TOOLBARv6_Unregister (void)
+{
+    UnregisterClassW (TOOLBARCLASSNAMEW, NULL);
+}
+#endif
+
 static HIMAGELIST TOOLBAR_InsertImageList(PIMLENTRY **pies, INT *cies, HIMAGELIST himl, INT id)
 {
     HIMAGELIST himlold;