如何更改 CTabCtrl 选项卡颜色?
你好,新年快乐,(可以说到星期四)
我正在尝试更改 CTabCtrl 类中选项卡的颜色.我正在尝试创建自己的 ReskinCTablCtrl,以便我可以在单独的类中调用它并在整个程序中轻松使用它.
目前我可以更改 CTabCtrl 的背景颜色,但我无法修改选项卡本身.
我使用 ON_WM_ERASEBKGND()
来绘制背景,并且没有问题:
BOOL ReskinCTabCtrl::OnEraseBkgnd(CDC* pDC){CRect 矩形;GetClientRect(&rect);CBrush myBrush(RGB(51, 51, 51));//对话框背景颜色BOOL bRes = pDC->PatBlt(0, 0, rect.Width(), rect.Height(), PATCOPY);pDC->SetBkColor(RGB(51, 51, 51));pDC->FillRect(&rect, &myBrush);返回 bRes;}
但是,我在更改标签颜色方面没有成功.它们仍然是默认的 MFC 颜色.我试图实现 ON_WM_PAINT()
和 ON_WM_DRAWITEM()
没有任何成功.我想我可以使用 OnDraw 和 DrawItem 来访问特定的选项卡矩形,类似于我在这个问题末尾发布的第二个链接示例.
void ReskinCTabCtrl::OnPaint() {...//先绘制标签,然后绘制边框int nTab = GetItemCount();int nSel = GetCurSel();if (!nTab)//没有添加页面返回;而 (nTab--){如果(nTab!= nSel){dis.itemID = nTab;dis.itemState = 0;VERIFY(GetItemRect(nTab, &dis.rcItem));dis.rcItem.bottom -= 2;绘制项目(&dis);DrawItemBorder(&dis);}}...}
我真的很感激至少有一些解决这个问题的方向,也许还有更多的例子或者我应该专注于使用什么方法.我不需要标签是不同的颜色,也许有一种简单的方法可以做到这一点?
我一直在尝试遵循以下链接之类的示例,但我仍然无法找到正确的方法.
Hello and happy new year, (it is acceptable to say it until Thursday)
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.
Currently I am able to change the background color of the CTabCtrl but I cannot modify the tab's themselves.
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;
}
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://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
解决方案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;
}
相关文章