要更改的每个选项卡,您必须使选项卡控件所有者绘制和使用 FillRect() 方法来填充选项卡的本身使用您创建和调用 SetBkColor() 方法之前的画笔矩形区域的背景色进行调用 TextOut() 方法,与文本要显示在选项卡上。
第一次显示选项卡控件在资源编辑器中的属性,并选中样式选项卡,选择在"所有者绘制固定"复选框并保存您的工作。如果要在与 CreateWindow() 或 CreateWindowEx() 对话框的初始化过程中动态地创建 Tab 控件一定要包括在 TCS_OWNERDRAWFIXED 位 dwStyle 参数中。
以下 # 定义了在该示例中使用:
#define RED RGB(255,0,0)
#define YELLOW RGB(255,255,0)
#define MAGENTA RGB(255,0,255)
#define WHITE RGB(255,255,255)
#define BLUE RGB(0,0,255)
如果您正在使用 SDK
此示例的摘录中画笔 WM_INITDIALOG 中创建了,是静态的控点。
将 WM_DRAWITEM 消息添加到对话框中的过程。
示例代码
case WM_DRAWITEM:
lpdis = (LPDRAWITEMSTRUCT) lParam; // item drawing information
hTabCtrl = GetDlgItem(hDlg, IDC_TAB1);
if (hTabCtrl == lpdis->hwndItem) // is this the tab control?
{
// which tab? first, second...fifth
switch (lpdis->itemID)
{
case 0:
hbr = hbrRed;
bkColor = RED;
break;
case 1:
hbr = hbrYellow;
bkColor = YELLOW;
break;
case 2:
hbr = hbrMagenta;
bkColor = MAGENTA;
break;
case 3:
hbr = hbrWhite;
bkColor = WHITE;
break;
case 4:
hbr = hbrBlue;
bkColor = BLUE;
break;
}
memset(szTabText, '\0', sizeof(szTabText));
tci.mask = TCIF_TEXT;
tci.pszText = szTabText;
tci.cchTextMax = sizeof(szTabText)-1;
TabCtrl_GetItem(hTabCtrl, lpdis->itemID, &tci);
FillRect(lpdis->hDC, &lpdis->rcItem, hbr);
SetBkColor(lpdis->hDC, bkColor);
TextOut(lpdis->hDC,
lpdis->rcItem.left,
lpdis->rcItem.top,
tci.pszText,
lstrlen(tci.pszText));
}
break;
如果您正在使用 MFC
引用该画笔是在对话框类的一部分,对话框构造函数调用时创建。
重写为 CDialog 派生类使用类向导 OnDrawItem() 方法,并添加下面的代码更改为所需的变量名。 值得注意是必需的 CDC 对象指向设置为从该LPDRAWITEMSTRUCT 通过传递在 DC 的句柄,否则只在文本的背景将所需的颜色。
示例代码
void CMFCTabCtrlDlg::OnDrawItem(int nIDCtl,LPDRAWITEMSTRUCT lpdis)
{
CDialog::OnDrawItem(nIDCtl, lpdis);
char szTabText[100];
RECT rect;
UINT bkColor;
CBrush *cbr;
TC_ITEM tci;
CTabCtrl *pTabCtrl = (CTabCtrl *)GetDlgItem(IDC_TAB1);
if (pTabCtrl->m_hWnd == lpdis->hwndItem)
{
// which tab?
switch (lpdis->itemID)
{
case 0:
cbr = &m_brRed;
bkColor = RED;
break;
case 1:
cbr = &m_brYellow;
bkColor = YELLOW;
break;
case 2:
cbr = &m_brMagenta;
bkColor = MAGENTA;
break;
case 3:
cbr = &m_brWhite;
bkColor = WHITE;
break;
case 4:
cbr = &m_brBlue;
bkColor = BLUE;
break;
}
memset(szTabText, '\0', sizeof(szTabText));
tci.mask = TCIF_TEXT;
tci.pszText = szTabText;
tci.cchTextMax = sizeof(szTabText)-1;
pTabCtrl->GetItem(lpdis->itemID, &tci);
CDC *dc = CDC::FromHandle(lpdis->hDC);
dc->FillRect(&lpdis->rcItem, cbr);
dc->SetBkColor(bkColor);
TextOut(lpdis->hDC,
lpdis->rcItem.left,
lpdis->rcItem.top,
tci.pszText,
lstrlen(tci.pszText));
}
}
以上是Microsoft主页上MSDN所说的方法,但是我在操作的过程中无论如何也追踪不到对话框执行OnDrawItem函数,也试图自己给对话框发送WM_DRAWITEM消息,但由于对LPDRAWITEMSTRUCT的结构理解不是很清楚,所以总是出现各种无法预料的断言错误,找了好久终于找到了LPDRAWITEMSTRUCT结构比较详细的阐述,特贴上来供大家分享。
但是我最终还是放弃了在对话框中重绘的方法,也许是太难了吧!我选择了继承CTabCtrl类,在类中的DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)函数中进行重绘,重绘代码参考了Microsoft上MSDN的代码,完整形式如下:
void CMyTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
char szTabText[100];
RECT rect;
UINT bkColor;
CBrush *cbr;
TC_ITEM tci;
switch (lpDrawItemStruct->itemID)
{
case 0:
cbr = &m_brRed;
bkColor = RED;
break;
case 1:
cbr = &m_brYellow;
bkColor = YELLOW;
break;
case 2:
cbr = &m_brMagenta;
bkColor = MAGENTA;
break;
case 3:
cbr = &m_brWhite;
bkColor = WHITE;
break;
case 4:
cbr = &m_brBlue;
bkColor = BLUE;
break;
}
memset(szTabText, '\0', sizeof(szTabText));
tci.mask = TCIF_TEXT;
tci.pszText = szTabText;
tci.cchTextMax = sizeof(szTabText)-1;
GetItem(lpDrawItemStruct->itemID, &tci);
CDC *dc = CDC::FromHandle(lpDrawItemStruct->hDC);
dc->FillRect(&lpDrawItemStruct->rcItem, cbr);
dc->SetBkColor(bkColor);
TextOut(lpDrawItemStruct->hDC,
lpDrawItemStruct->rcItem.left,
lpDrawItemStruct->rcItem.top,
tci.pszText,
lstrlen(tci.pszText));
}
如果你还是出现断言错误,那么在VC2005中你应该在CTabCtrl的属性页中Owner Draw Fixed选项选择为TRUE。
最终实现效果如下: