How to change CTabCtrl tab colors?

放肆的年华 提交于 2019-11-30 22:05:32

Enable OwnerDraw for tab control, either in resource editor, or set TCS_OWNERDRAWFIXED in OnInitDialog

CTabCtrl has message reflection for WM_DRAWITEM therefore we don't want to override WM_DRAWITEM/OnDrawItem from parent class. Instead override in CTabCtrl::DrawItem(LPDRAWITEMSTRUCT).

Unfortunately the result is rather ugly. It's sort of like overriding DrawItem in a button.

If Visual Style is available and enabled, then you can override CTabCtrl::OnPaint and draw everything manually. Example:

void CMyTabCtrl::OnPaint()
{
    CPaintDC dc(this);

    dc.SelectObject(GetFont());

    CPen pen, pen_active;
    COLORREF color_off = RGB(240, 240, 240);
    COLORREF color_active = RGB(200, 240, 240);
    CBrush brush_off, brush_active;
    brush_off.CreateSolidBrush(color_off);
    brush_active.CreateSolidBrush(color_active);
    pen.CreatePen(PS_SOLID, 1, RGB(200, 200, 200));
    pen_active.CreatePen(PS_SOLID, 1, color_active);

    CRect rcitem;
    GetItemRect(0, &rcitem);

    CRect rc;
    GetClientRect(&rc);
    rc.bottom = rcitem.bottom;
    dc.FillSolidRect(&rc, GetSysColor(COLOR_3DFACE));

    GetClientRect(&rc);
    rc.top = rcitem.bottom - 1;
    dc.SelectObject(&pen);
    dc.SelectObject(&brush_active);
    dc.Rectangle(&rc);

    for(int i = 0; i < GetItemCount(); i++)
    {
        dc.SelectObject(&pen);
        if(i == GetCurSel())
        {
            dc.SelectObject(&brush_active);
            dc.SetBkColor(color_active);
        }
        else
        {
            dc.SelectObject(&brush_off);
            dc.SetBkColor(color_off);
        }

        GetItemRect(i, &rcitem);
        rcitem.right++;
        dc.Rectangle(&rcitem);

        if(i == GetCurSel())
        {
            dc.SelectObject(pen_active);
            dc.MoveTo(rcitem.left+1, rcitem.bottom - 1);
            dc.LineTo(rcitem.right, rcitem.bottom - 1);
        }

        TCITEM item = { 0 };
        wchar_t buf[32];
        item.pszText = buf;
        item.cchTextMax = 32;
        item.mask = TCIF_TEXT;
        GetItem(i, &item);
        dc.DrawText(buf, &rcitem, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    }
}

BOOL CMyTabCtrl::OnEraseBkgnd(CDC*)
{
    return TRUE;
}

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!