你好,新年快乐,(可以说直到周四)
我正在尝试更改CTabCtrl类中选项卡的颜色.我正在尝试创建自己的ReskinCTablCtrl,以便我可以在单独的类中调用它,并在整个程序中轻松使用它.
目前我能够改变CTabCtrl的背景颜色,但我无法修改标签本身.
我用ON_WM_ERASEBKGND()它画背景,它没有问题:
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来获取特定的tab rect,类似于我在这个问题的最后发布的第二个链接示例.
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);
        }
    }
    ...
}
我真的很感激至少有一些方向来解决这个问题,也许还有一些例子或者我应该关注哪些方法.我不需要标签是不同的颜色,也许有一个简单的方法来做到这一点?
我一直试图遵循以下链接的一些例子,但我仍然无法找到正确的方法来做到这一点.
https://support.microsoft.com/en-us/help/179909/how-to-change-the-background-color-of-a-tab-control
https://www.codeproject.com/Articles/1786/Ownerdraw-Tab-Controls-Borders-and-All
启用的OwnerDraw的标签控制,无论是在资源编辑器,或设置TCS_OWNERDRAWFIXED在OnInitDialog
CTabCtrl有消息反射,WM_DRAWITEM因此我们不想覆盖WM_DRAWITEM/ OnDrawItem从父类.而是覆盖CTabCtrl::DrawItem(LPDRAWITEMSTRUCT).
不幸的是,结果相当丑陋.这有点像覆盖DrawItem按钮.
如果可用并启用了视觉样式,则可以CTabCtrl::OnPaint手动覆盖和绘制所有内容.例:
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;
}