一、引言:
對於TREWVIEW控件的背景位圖的實現,目前介紹的文章比較少,有人雖然實現了,但是在點擊TREE時,背景閃動比較厲害。本人在參照別人代碼的基礎上,把它總結一下,同時解決了這個背景閃爍的問題。目前FLASHGET1.3版也實現了TREEVIEW的背景位圖。大家可以參照一下。
本文程序運行效果如下圖:
二、原理:
因為WINDOWS標准TREEVIEW控件不支持背景位圖,所以如果需要設置背景位圖就需要先讓其在內存CDC對象上對TREEVIEW缺省繪圖,然後在選擇背景位圖,與缺省位圖合成,即采用貼圖的方式,把標准的TREEVIEW窗口貼在底圖上。這個操作在內存中完成。
同時為了避免閃爍,必須重載OnItemexpanding和OnItemexpanded這兩個函數。SetRedraw函數主要保證其不要在子樹彈出時重畫,而是子樹已經擴展後重畫。
三、實現步驟:
3.1 加入成員函數
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;
}
3.2 為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();
}
3.3 處理tvn_itemexpanding
void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
SetRedraw(FALSE);
*pResult = 0;
}
3.4 處理tvn_itemexpanded
void CMyTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
Invalidate();
SetRedraw(TRUE);
*pResult = 0;
}
3.5 加入WM_ERASEBKGND消息處理函數
既然我們在OnPaint()函數中處理位圖並返回TRUE以保證默認的窗口進程不擦除背景,加入這個消息句柄可以避免額外的對客戶區的刷新以減少閃爍。
BOOL CMyTreeCtrl::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
(完)
本文配套源碼