如何在树型控件中使用背景位图

引言

对于TREWVIEW控件的背景位图的实现,目前介绍的文章比较少,有人虽然实现了,但是在点击TREE时,背景闪动比较厉害。本人在参照别人代码的基础 上,把它总结一下,同时解决了这个背景闪烁的问题。目前FLASHGET1.3版也实现了TREEVIEW的背景位图。大家可以参照一下。

原理

因为WINDOWS标准TREEVIEW控件不支持背景位图,所以如果需要设置背景位图就需要先让其在内存CDC对象上对TREEVIEW缺省绘图,然后 在选择背景位图,与缺省位图合成,即采用贴图的方式,把标准的TREEVIEW窗口贴在底图上。这个操作在内存中完成。

同时为了避免闪烁,必须重载OnItemexpanding和OnItemexpanded这两个函数。SetRedraw函数主要保证其不要在子树弹出时重画,而是子树已经扩展后重画。

实现步骤

加入成员函数

BOOL CMyTreeCtrl::SetBKImage(LPCTSTR LpszResource)
{
	if( m_bitmap.m_hObject != NULL )
		m_bitmap.DeleteObject();
	
	HBITMAP hbmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), 
			LpszResource, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION|LR_LOADFROMFILE);

	if( hbmp == NULL ) 
		return FALSE;

	m_bitmap.Attach( hbmp );
	return TRUE;
}

为WM_PAINT加入消息句柄

void CMyTreeCtrl::OnPaint() 
{
	CPaintDC dc(this);
	
	CRect rcclient;
	GetClientRect(&rcclient);

	CDC memdc;
	memdc.CreateCompatibleDC(&dc);	
	CBitmap bitmap;
	bitmap.CreateCompatibleBitmap(&dc, rcclient.Width(), rcclient.Height());
	memdc.SelectObject( &bitmap );

	CWnd::DefWindowProc(WM_PAINT, (WPARAM)memdc.m_hDC , 0);

	CDC maskdc;
	maskdc.CreateCompatibleDC(&dc);
	CBitmap maskbitmap;
	maskbitmap.CreateBitmap(rcclient.Width(), rcclient.Height(), 1, 1, NULL);
	maskdc.SelectObject( &maskbitmap );
	maskdc.BitBlt( 0, 0, rcclient.Width(), rcclient.Height(), &memdc, 
		rcclient.left, rcclient.top, SRCCOPY);

	CBrush brush;
	brush.CreatePatternBrush(&m_bitmap);
	dc.FillRect(rcclient, &brush);	
	
	memdc.SetBkColor(RGB(0,0,0));          
	memdc.SetTextColor(RGB(255,255,255));  
	memdc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(),
                &maskdc, rcclient.left, rcclient.top, SRCAND);	

	dc.SetBkColor(RGB(255,255,255));
	dc.SetTextColor(RGB(0,0,0));
	dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), 
             &maskdc, rcclient.left, rcclient.top, SRCAND);
	
	dc.BitBlt(rcclient.left, rcclient.top, rcclient.Width(), rcclient.Height(), 
             &memdc, rcclient.left, rcclient.top,SRCPAINT);
	brush.DeleteObject();
}

处理tvn_itemexpanding

void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	SetRedraw(FALSE);
	*pResult = 0;
}

处理tvn_itemexpanded

void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	Invalidate();
	SetRedraw(TRUE);
	*pResult = 0;
}

加入WM_ERASEBKGND消息处理函数,既然我们在OnPaint()函数中处理位图并返回TRUE以保证默认的窗口进程不擦除背景,加入这个消息句柄可以避免额外的对客户区的刷新以减少闪烁。

BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC) 
{
	return TRUE;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值