如何更改CTabCtrl选项卡的颜色? [英] How to change CTabCtrl tab colors?
问题描述
你好,新年快乐,(可以说到星期四)
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屋!