102上位机VC MFC标签控件CTabCtrl的自绘美化
102上位机VC MFC标签控件CTabCtrl的自绘美化
功能展示
VC的控件都支持自绘效果进行界面美化,CTabCtrl控件也是可以自绘,我们当前例程实现标签控件自绘,设置字体及颜色,也可再进行DIY更多美化效果设置,效果如图;
要点提示
要实现控件的自绘,控件自身具备有自绘属性,标签控件自绘得具有TCS_OWNERDRAWFIXED属性;可以通过ModifyStyle(0,TCS_OWNERDRAWFIXED);设置属性;然后在DrawItem()函数中实现自绘效果;
实现功能 1.新建基于对话框的应用程序 2.从CTabCtrl派生自己的类class CTabCtrlEx : public CTabCtrl,添加变量 COLORREFm_crSelColour, m_crUnselColour; CFont m_SelFont, m_UnselFont;并在构造函数中初始化 m_crSelColour = RGB(0,0,255); m_crUnselColour = RGB(250,00,00);
添加这些变量的设置函数 - void CTabCtrlEx::SetColours(COLORREF bSelColour, COLORREF bUnselColour)
- {
- m_crSelColour = bSelColour;
- m_crUnselColour = bUnselColour;
- Invalidate();
- } void CTabCtrlEx::SetFonts(CFont* pSelFont, CFont* pUnselFont)
- {
- ASSERT(pSelFont && pUnselFont);
- LOGFONT lFont;
- int nSelHeight, nUnselHeight;
- m_SelFont.DeleteObject();
- m_UnselFont.DeleteObject();
- pSelFont->GetLogFont(&lFont);
- m_SelFont.CreateFontIndirect(&lFont);
- nSelHeight = lFont.lfHeight;
复制代码
- pUnselFont->GetLogFont(&lFont);
- m_UnselFont.CreateFontIndirect(&lFont);
- nUnselHeight = lFont.lfHeight;
- SetFont( (nSelHeight > nUnselHeight)? &m_SelFont : &m_UnselFont);
- }
- void CTabCtrlEx::SetFonts(int nSelWeight, BOOL bSelItalic, BOOL bSelUnderline,
- int nUnselWeight, BOOL bUnselItalic, BOOL bUnselUnderline)
- {
- // Free any memory currently used by the fonts.
- m_SelFont.DeleteObject();
- m_UnselFont.DeleteObject();
- // Get the current font
- LOGFONT lFont;
- CFont *pFont = GetFont();
- if (pFont)
- pFont->GetLogFont(&lFont);
- else {
- NONCLIENTMETRICS ncm;
- ncm.cbSize = sizeof(NONCLIENTMETRICS);
- VERIFY(SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(NONCLIENTMETRICS), &ncm, 0));
- lFont = ncm.lfMessageFont;
- }
- // Create the "Selected" font
- lFont.lfWeight = nSelWeight;
- lFont.lfItalic = bSelItalic;
- lFont.lfUnderline = bSelUnderline;
- m_SelFont.CreateFontIndirect(&lFont);
- // Create the "Unselected" font
- lFont.lfWeight = nUnselWeight;
- lFont.lfItalic = bUnselItalic;
- lFont.lfUnderline = bUnselUnderline;
- m_UnselFont.CreateFontIndirect(&lFont);
- SetFont( (nSelWeight > nUnselWeight)? &m_SelFont : &m_UnselFont);
- }
复制代码3.添加PreSubclassWindow()实现自绘属性设置 - void CTabCtrlEx::PreSubclassWindow()
- {
- CTabCtrl::PreSubclassWindow();
- ModifyStyle(0, TCS_OWNERDRAWFIXED);
- }
- 4.添加DrawItem()函数实现自绘效果
- void CTabCtrlEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
- {
- CRect rect = lpDrawItemStruct->rcItem;
- int nTabIndex = lpDrawItemStruct->itemID;
- if (nTabIndex < 0) return;
- BOOL bSelected = (nTabIndex == GetCurSel());
- char label[64];
- TC_ITEM tci;
- tci.mask = TCIF_TEXT|TCIF_IMAGE;
- tci.pszText = label;
- tci.cchTextMax = 63;
- if (!GetItem(nTabIndex, &tci )) return;
- CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
- if (!pDC) return;
- int nSavedDC = pDC->SaveDC();
- // For some bizarre reason the rcItem you get extends above the actual
- // drawing area. We have to workaround this "feature".
- rect.top += ::GetSystemMetrics(SM_CYEDGE);
- pDC->SetBkMode(TRANSPARENT);
- pDC->FillSolidRect(rect, ::GetSysColor(COLOR_BTNFACE));
- // Draw image
- CImageList* pImageList = GetImageList();
- if (pImageList && tci.iImage >= 0) {
- rect.left += pDC->GetTextExtent(_T(" ")).cx; // Margin
复制代码- // Get height of image so we
- IMAGEINFO info;
- pImageList->GetImageInfo(tci.iImage, &info);
- CRect ImageRect(info.rcImage);
- int nYpos = rect.top;
- pImageList->Draw(pDC, tci.iImage, CPoint(rect.left, nYpos), ILD_TRANSPARENT);
- rect.left += ImageRect.Width();
- }
- if (bSelected) {
- pDC->SetTextColor(m_crSelColour);
- pDC->SelectObject(&m_SelFont);
- rect.top -= ::GetSystemMetrics(SM_CYEDGE);
- pDC->DrawText(label, rect, DT_SINGLELINE|DT_VCENTER|DT_CENTER);
- } else {
- pDC->SetTextColor(m_crUnselColour);
- pDC->SelectObject(&m_UnselFont);
- pDC->DrawText(label, rect, DT_SINGLELINE|DT_BOTTOM|DT_CENTER);
- }
- pDC->RestoreDC(nSavedDC);
- }
复制代码5.自定义标签类的使用:在主对话框资源添加Tab控件,关联变量 CTabCtrlEx m_Tab;再添加两对话框资源,设置为子窗口属性,关联两个类,并在主对话框中添加两个类的变量,作为标签中显示的窗口内容,如我们例程为 CDlg1 m_Dlg1;CDlg1 m_Dlg2; 6.然后是这些变量的初始化 m_Tab.InsertItem(0,"设备参数",0); m_Tab.InsertItem(1,"工艺参数",1); m_Dlg1.Create(IDD_DIALOG1,&m_Tab);m_Dlg2.Create(IDD_DIALOG2,&m_Tab); m_Dlg1.CenterWindow(); m_Dlg1.ShowWindow(SW_SHOW);
7.添加TCN_SELCHANGE的消息响应函数OnSelchangeTab1(),实现标签切换时,显示不同的窗口 - void CGkbc8Dlg::OnSelchangeTab1(NMHDR* pNMHDR, LRESULT* pResult)
- {
- int nIndex = m_Tab.GetCurSel();
- switch(nIndex)
- {
- case 0:
- {
- m_Dlg1.CenterWindow();
- m_Dlg1.ShowWindow(SW_SHOW);
- m_Dlg2.ShowWindow(SW_HIDE);
- }
- break;
- case 1:
- {
- m_Dlg2.CenterWindow();
- m_Dlg2.ShowWindow(SW_SHOW);
- m_Dlg1.ShowWindow(SW_HIDE);
- }
- break;
- default:
- break;
- }
- *pResult = 0;
- }
- <div style="text-align: center;"><b style="font-size: large; line-height: 1.5;">我们来演示功能实现的整个过程</b></div>
复制代码
|