如何更改CTabCtrl选项卡的颜色? [英] How to change CTabCtrl tab colors?

查看:578
本文介绍了如何更改CTabCtrl选项卡的颜色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,新年快乐,(可以说到星期四)

Hello and happy new year, (it is acceptable to say it until Thursday)

我正在尝试更改CTabCtrl类中选项卡的颜色.我正在尝试创建自己的ReskinCTablCtrl,以便可以在单独的类中调用它,并在整个程序中轻松使用它.

I am trying to change the color of the tabs in the CTabCtrl class. I am trying to create my own ReskinCTablCtrl so that I can just call it in separate classes and easily use it throughout my program.

当前,我可以更改CTabCtrl的背景颜色,但不能修改选项卡本身.

Currently I am able to change the background color of the CTabCtrl but I cannot modify the tab's themselves.

我使用ON_WM_ERASEBKGND()绘制背景,并且可以正常工作:

I used ON_WM_ERASEBKGND() for painting the background and it worked without a problem:

BOOL ReskinCTabCtrl::OnEraseBkgnd(CDC* pDC)
{
    CRect rect;
    GetClientRect(&rect);
    CBrush myBrush(RGB(51, 51, 51));    // dialog background color
    BOOL bRes = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);
    pDC->SetBkColor(RGB(51, 51, 51));
    pDC->FillRect(&rect, &myBrush);
    return bRes;
}

但是,我无法自行更改选项卡的颜色.它们仍然是默认的MFC颜色.我尝试实现ON_WM_PAINT()ON_WM_DRAWITEM(),但没有成功.我想我可以同时使用OnDraw和DrawItem来进入特定的选项卡区域,类似于我在此问题结尾处发布的第二个链接示例.

However, I have been unsuccesfull at changing the tab colors themselves. They are still the default MFC colors. I have tried to implement ON_WM_PAINT() and ON_WM_DRAWITEM() without any success. I think I can get to the specific tab rect with using both OnDraw and DrawItem similar to the second link example that I have posted in the end of this question.

void ReskinCTabCtrl::OnPaint() {

    ...

    // paint the tabs first and then the borders
    int nTab = GetItemCount();
    int nSel = GetCurSel();

    if (!nTab) // no pages added
        return;

    while (nTab--)
    {
        if (nTab != nSel)
        {
            dis.itemID = nTab;
            dis.itemState = 0;

            VERIFY(GetItemRect(nTab, &dis.rcItem));

            dis.rcItem.bottom -= 2;
            DrawItem(&dis);
            DrawItemBorder(&dis);
        }
    }

    ...

}

我真的很感谢至少有一些解决这个问题的方向,也许还有更多的例子,或者我应该重点使用什么方法.我不需要选项卡使用不同的颜色,也许有一种简单的方法可以做到这一点?

I would really appreciate at least some direction to go about this problem, perhaps some more examples or what methods I should focus on using. I don't need the tabs to be different colors, maybe there is an easy way of doing this?

我一直在尝试遵循以下链接之类的示例,但我仍然找不到正确的方法.

I've been trying to follow some examples like the following links but I still couldn't figure out the right way to do it.

https://www.codeproject.com /Articles/1786/Ownerdraw-Tab-Controls-Borders-and-All

推荐答案

在资源编辑器中或在OnInitDialog

CTabCtrl具有对WM_DRAWITEM的消息反射,因此我们不想从父类覆盖WM_DRAWITEM/OnDrawItem.而是在CTabCtrl::DrawItem(LPDRAWITEMSTRUCT)中覆盖.

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).

不幸的是,结果非常丑陋.有点像在按钮中覆盖DrawItem.

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

如果视觉样式"可用并已启用,则可以覆盖CTabCtrl::OnPaint并手动绘制所有内容.示例:

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;
}

这篇关于如何更改CTabCtrl选项卡的颜色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆