自绘CTabCtrl控件的实现

 

//头文件

#pragma once
// OwnerdrawTabCtrl.h : header file

// COwnerdrawTabCtrl window

class COwnerdrawTabCtrl : public CTabCtrl
{
// Construction
public:
	COwnerdrawTabCtrl();

// Attributes
public:

// Operations
public:

// Overrides
	// ClassWizard generated virtual function overrides
	//{​{AFX_VIRTUAL(COwnerdrawTabCtrl)
	public:
	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, 
    const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
	protected:
	virtual void PreSubclassWindow();
	//}}AFX_VIRTUAL

// Implementation
public:
	virtual ~COwnerdrawTabCtrl();

	// Generated message map functions
protected:
	//{​{AFX_MSG(COwnerdrawTabCtrl)
	//}}AFX_MSG

  void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);

	DECLARE_MESSAGE_MAP()
};

 

//CPP实现

// OwnerdrawTabCtrl.cpp
//

#include "stdafx.h"
#include "OwnerdrawTabCtrl.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// COwnerdrawTabCtrl

COwnerdrawTabCtrl::COwnerdrawTabCtrl()
{
}

COwnerdrawTabCtrl::~COwnerdrawTabCtrl()
{
}


BEGIN_MESSAGE_MAP(COwnerdrawTabCtrl, CTabCtrl)
  //{​{AFX_MSG_MAP(COwnerdrawTabCtrl)
  //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/
// COwnerdrawTabCtrl message handlers

void COwnerdrawTabCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) 
{
  if(lpDrawItemStruct->CtlType == ODT_TAB)
  {	
    CRect rect = lpDrawItemStruct->rcItem;
    INT nTabIndex = lpDrawItemStruct->itemID;
    if (nTabIndex < 0) return;

    TCHAR label[64];
    TC_ITEM tci;
    tci.mask = TCIF_TEXT|TCIF_IMAGE;
    tci.pszText = label;     
    tci.cchTextMax = 63;    	
    GetItem(nTabIndex, &tci );

    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    if (!pDC) return;
    int nSavedDC = pDC->SaveDC();

    //填充背景色
    COLORREF rcBack;
    if (lpDrawItemStruct->itemState & CDIS_SELECTED  ) 
    {
      rcBack = RGB(255, 0, 0);
    }
    else if(lpDrawItemStruct->itemState & (CDIS_DISABLED | CDIS_GRAYED) ) 
    {
      rcBack = RGB(0, 255, 0);
    }
    else
    {
      rcBack = GetSysColor(COLOR_BTNFACE);
    }    
    pDC->FillSolidRect(rect, rcBack);

    rect.top += ::GetSystemMetrics(SM_CYEDGE);

    pDC->SetBkMode(TRANSPARENT);

    //绘制图片
    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();
    }

    //绘制字体
    COLORREF txtColor;
    if (lpDrawItemStruct->itemState & CDIS_SELECTED  ) 
    {
      rect.top -= ::GetSystemMetrics(SM_CYEDGE);

      txtColor = RGB(0,255,0);
    }
    else if(lpDrawItemStruct->itemState & (CDIS_DISABLED | CDIS_GRAYED) ) 
    {
      txtColor = RGB(128, 128, 128);      
    }
    else
    {
      txtColor = GetSysColor(COLOR_WINDOWTEXT);
    }    
    pDC->SetTextColor(txtColor);
    pDC->DrawText(label, rect, DT_SINGLELINE|DT_VCENTER|DT_CENTER);

    pDC->RestoreDC(nSavedDC);

  }

}

void COwnerdrawTabCtrl::PreSubclassWindow() 
{
  ModifyStyle(0, TCS_OWNERDRAWFIXED);
  CTabCtrl::PreSubclassWindow();
}

BOOL COwnerdrawTabCtrl::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, 
  DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
  // TODO: Add your specialized code here and/or call the base class
  dwStyle |= TCS_OWNERDRAWFIXED;
  return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}

 

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: Ctabctrl是一个MFC框架下的控件,通常用于显示多个tab页,每一个tab页显示不同的内容。在实际开发中,由于多个tab页之间的内容不同,可能会出现一些需要重新绘制的情况。这时,我们就可以通过重新绘制ctabctrl来达到我们想要的效果。 在使用ctabctrl控件时,我们首先需要选择一个合适的绘制方式,并为tabctrl控件进行预处理。当我们需要对控件进行重绘时,可以先使用WM_SETREDRAW消息,将控件设置为不进行重绘状态,此时修改控件的属性并不会对界面上显示的内容产生影响。当需要恢复控件的重绘状态时,可以使用WM_SETREDRAW消息,将控件设置为可以重绘状态。 在进行重绘时,我们通常需要先擦除控件内容,并重新绘制。在绘制时,我们可以使用MFC框架下提供的CDC类和其他相关类,来进行绘制。在绘制时,需要考虑到控件的不同状态和不同信息,以达到最佳的绘制效果。最后,如果需要控制重绘的时间和频率,可以在控件初始化时设置相关的定时器和消息处理函数,来控制重绘的方式和间隔时间。 总之,ctabctrl控件的重绘是一个比较重要的开发问题,需要在具体使用时仔细研究,理解控件的特性和绘制方式,以达到理想的效果。 ### 回答2: ctabctrl 是一个MFC控件,在Windows窗口界面下使用极为广泛,主要功能是用于设置和维护多个选项卡,方便用户在多个选项间便捷切换。在使用 ctabctrl 的过程中,如果发现选项卡显示不正确,可能需要进行重绘操作。 CTabCtrl 重绘操作通常需要在如下三种情况下进行: 一、 当选项卡背景色与其他控件或窗口颜色不一致时,需要进行重绘操作,使得选项卡的背景色与其他控件或窗口颜色相统一,使得整个界面更加和谐。 二、 当选项卡中的文本或图标发生变化,或者选项卡的排列顺序发生改变时,需要进行重绘操作,使得选项卡显示的内容与实际操作结果保持一致。 三、 当选项卡中的控件需要刷新时,需要进行重绘操作,以便及时更新选项卡内的控件,保证用户操作的实时性。 CTabCtrl 重绘操作通常采用 Invalidate() 函数来触发,常见的调用方式有两种: 一、 在选项卡的 OnPaint() 函数中进行调用,并将需要刷新的区域作为参数传入。例如: void CMyTabCtrl::OnPaint() { CPaintDC dc(this); // 需要进行重绘的选项卡区域 CRect rect; GetClientRect(&rect); rect.DeflateRect(1,1); // 缩小矩形区域,保证视觉效果 m_myTabCtrl.InvalidateRect(&rect); } 二、 在选项卡的其他操作函数中(例如 OnSelChange())调用 Invalidate() 函数,以保证操作结果及时显示。 总之,CTabCtrl 重绘操作是 Windows 界面编程中的一个重要内容,需要程序员在开发中充分理解掌握其使用方法,以便打造更加完美的用户界面体验。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值