MFC CTreeCtrl 设置每一项Item颜色

1.CTreeCtrlXX继承CTreeCtrl,在CTreeCtrlXX里添加SetItemColor方法和重载OnPaint方法

2.添加消息yings

3.重载树控件#define CTreeCtrl CTreeCtrlXX, CTreeCtrl也有了SetItemColor

 

代码如下:

.cpp

// TreeCtrlXX.cpp : 实现文件
//

#include "stdafx.h"
#include "TreeCtrlXX.h"


// CTreeCtrlXX
struct Color_Font
{
	COLORREF color;
	LOGFONT logfont;
};
//使用CMap来保存各个Item对应的字体、颜色信息
CMap< void*, void*, Color_Font, Color_Font& > m_mapColorFont ;
IMPLEMENT_DYNAMIC(CTreeCtrlXX, CTreeCtrl)

CTreeCtrlXX::CTreeCtrlXX()
{
      
}

CTreeCtrlXX::~CTreeCtrlXX()
{

}


BEGIN_MESSAGE_MAP(CTreeCtrlXX, CTreeCtrl)
	ON_WM_PAINT()
END_MESSAGE_MAP()



// CTreeCtrlXX 消息处理程序
void CTreeCtrlXX::SetItemColor(HTREEITEM hItem, COLORREF color)
{
	Color_Font cf;
	if( !m_mapColorFont.Lookup( hItem, cf ) )
		cf.logfont.lfFaceName[0] = '\0';
	cf.color = color;
	m_mapColorFont[hItem] = cf;

}
afx_msg void CTreeCtrlXX::OnPaint()
{
	//获取当前绘制对象的DC
	CPaintDC dc(this);
	// 使用将要绘制的对象的DC创建一个memory DC
	//memory device context的概念:是在内存中创建一个结构来反映一个显示(屏幕区域、窗口、
	//打印机等)的表面。可以用来先在内存中准备好要显示的图像,从而实现双缓存,提高刷新
	//速度减少刷新时产生的闪烁。
	CDC memDC;
	//从当前DC创建内存对象
	memDC.CreateCompatibleDC( &dc );

	//定义CRect对象,用来确定区域
	CRect rcClip, rcClient;
	//获取当前对象的边界区域
	dc.GetClipBox( &rcClip );
	//获取当前对象的用户区域
	GetClientRect(&rcClient);

	// Select a compatible bitmap into the memory DC
	//创建一个bmp文件,作为memDC的内容
	//该文件的大小与用于区域相同
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap( &dc, rcClient.Width(), rcClient.Height() );
	memDC.SelectObject( &bitmap );

	// Set clip region to be same as that in paint DC
	//通过对象的边界区域创建CRgn对象
	CRgn rgn;
	rgn.CreateRectRgnIndirect( &rcClip );
	memDC.SelectClipRgn(&rgn);
	rgn.DeleteObject();


	// First let the control do its default drawing.
	//首先让控件自己进行默认的绘制,绘制到内存中
	CWnd::DefWindowProc( WM_PAINT, (WPARAM)memDC.m_hDC, 0 );

	//获取树状控件的第一个节点
	HTREEITEM hItem = GetFirstVisibleItem();

	//遍历这棵树
	int n = GetVisibleCount()+1;
	while( hItem && n--)
	{
		CRect rect;

		// Do not meddle with selected items or drop highlighted items
		//不对选中的节点和实行拖放功能的节点进行操作
		UINT selflag = TVIS_DROPHILITED | TVIS_SELECTED;

		//定义字体、颜色
		Color_Font cf;


		//设置字体
		if ( !(GetItemState( hItem, selflag ) & selflag )
			&& m_mapColorFont.Lookup( hItem, cf ))
		{
			CFont *pFontDC;
			CFont fontDC;
			LOGFONT logfont;

			if( cf.logfont.lfFaceName[0] != '\0' )
			{
				//用户定义了字体
				logfont = cf.logfont;
			}
			else
			{
				// 用户没有定义,使用系统字体
				CFont *pFont = GetFont();
				pFont->GetLogFont( &logfont );
			}

			//用户是否设定节点为加粗

			//创建字体
			fontDC.CreateFontIndirect( &logfont );
			pFontDC = memDC.SelectObject( &fontDC );

			//设置字体颜色
			if( cf.color != (COLORREF)-1 )
				memDC.SetTextColor( cf.color );

			//获取节点文字
			CString sItem = GetItemText( hItem );

			//获取节点区域
			GetItemRect( hItem, &rect, TRUE );
			//设置背景色为系统色
			memDC.SetBkColor( GetSysColor( COLOR_WINDOW ) );
			memDC.SetBkMode(TRANSPARENT);
			//向内存中的图片写入内容,为该节点的内容
			memDC.TextOut( rect.left+2, rect.top+1, sItem );

			memDC.SelectObject( pFontDC );
		}
		hItem = GetNextVisibleItem( hItem );
	}


	dc.BitBlt( rcClip.left, rcClip.top, rcClip.Width(), rcClip.Height(), &memDC,
		rcClip.left, rcClip.top, SRCCOPY );


}


// CTreeCtrlXX 消息处理程序


.h

#pragma once


// CTreeCtrlXX

class CTreeCtrlXX : public CTreeCtrl
{
 DECLARE_DYNAMIC(CTreeCtrlXX)

public:
 CTreeCtrlXX();
 virtual ~CTreeCtrlXX();
 void SetItemColor(HTREEITEM hItem, COLORREF color);
protected:
 afx_msg void OnPaint();

protected:
 DECLARE_MESSAGE_MAP()
};

重载CTreeCtrl:

#define  CTreeCtrl CTreeCtrlXX



 

 

你可能感兴趣的:(开发经验)