在最近的項目中,需要實現(xiàn)一個類似QQ游戲大廳導(dǎo)航樹型控件。考試大參考了網(wǎng)絡(luò)上的部分資料,動手制作了一個類CTreeCtrlBT。其界面如下:

實現(xiàn)步驟
第一步:新建一個基于對話框的MFC工程,拖動一棵標(biāo)準(zhǔn)樹型控件放于界面之上。添加一個新類CTreeCtrlBT派生自CTreeCtrl。
第二步:為該類添加一些消息響應(yīng)以及虛函數(shù)。其詳細作用如下:
void PreSubclassWindow(); //用于添加初始化控件的相關(guān)信息
WM_SIZE //控件區(qū)域發(fā)生變化時候的處理
WM_PAINT //繪制控件
WM_MOUSEMOVE //主要獲取鼠標(biāo)所在位置的單元項
第三步:TreeCtrlBT.h中首先聲明一個結(jié)構(gòu)用于保存單元項的相關(guān)信息,并把所有項的信息放入一個map。
實現(xiàn)代碼如下:typedef struct tagItemMsg
{
HTREEITEM hItem; //項的句柄
CBitmap ItemBitmap; //項的位圖
COLORREF crTransparent; //透明顏色
tagItemMsg()
{
hItem = NULL;
crTransparent = RGB(255,255,255);
}
~tagItemMsg()
{
if ( ItemBitmap.GetSafeHandle() )
{
ItemBitmap.DeleteObject();
}
}
}ITEM_MSG;
typedef map
ITEMMSG_MAP;
第四步:計算控件的客戶區(qū)域大小,以及滾動條滾動的偏移量。詳細過程參考源代碼
Calculate函數(shù)。
第五步:添加接口函數(shù)以及成員變量。如下:
(注意:TransparentBlt函數(shù),需要包含msimg32.dll)
//設(shè)置背景位圖
BOOL SetBackgroudBitmap( UINT nID );
BOOL SetBackgroudBitmap(LPCTSTR lpszRecourceName);
//設(shè)置某一項位圖
void SetItemBitmap(HTREEITEM hItem, UINT nIdBitmap);
void SetItemBitmap(HTREEITEM hItem, LPCTSTR lpszBitmap);
//設(shè)置展開收縮的圖表
void SetExpandBitmap(UINT nIdExpand, UINT nIdCollapse, COLORREF crTransparent = RGB(255,255,255));
//插入新的項目
HTREEITEM InsertItemEx(HTREEITEM hParent, LPCTSTR lpszItem, UINT nIdBitmap = 0,
OLORREF crTransparent = RGB(255,255,255));
HTREEITEM InsertItemEx(HTREEITEM hParent, LPCTSTR lpszItem, LPCTSTR lpszBitmap,
COLORREF crTransparent = RGB(255,255,255));
//開啟橫線
void EnableRowLine( BOOL bEnable = TRUE );
//是否開啟橫線
BOOL IsEnableRowLine();
//開啟根節(jié)點背景
void EnableRootBk( BOOL bEnable = TRUE );
//是否開啟根節(jié)點背景
BOOL IsEnableRootBk();
//獲取某一項信息
ITEM_MSG* GetItemMsg(HTREEITEM hItem);
第六步:繪制控件。需要的繪制函數(shù)如下://繪制漸變色矩形區(qū)域
void GradientFillRect( CDC *pDC, CRect &rect, COLORREF col_from, COLORREF col_to, bool vert_grad );
//繪制控件背景
void DrawBackgroudBitmap(CDC* pDc);
//繪制單元項
void DrawItem( CDC* pDC );
//繪制單元項下部橫線
void DrawRowLine(CPoint ptBegin, CPoint ptEnd, CDC *pDc = NULL);
//繪制展開收縮按鈕
void DrawExpand(CRect rect, int state, CDC *pDc = NULL);
//繪制單元項位圖
void DrawItemBitmap(CRect rect, HTREEITEM hItem, CDC *pDc = NULL);
//繪制單元項目文本
void DrawItemText(CRect rect, HTREEITEM hItem, bool bselected,CDC *pDc = NULL);

實現(xiàn)步驟
第一步:新建一個基于對話框的MFC工程,拖動一棵標(biāo)準(zhǔn)樹型控件放于界面之上。添加一個新類CTreeCtrlBT派生自CTreeCtrl。
第二步:為該類添加一些消息響應(yīng)以及虛函數(shù)。其詳細作用如下:
void PreSubclassWindow(); //用于添加初始化控件的相關(guān)信息
WM_SIZE //控件區(qū)域發(fā)生變化時候的處理
WM_PAINT //繪制控件
WM_MOUSEMOVE //主要獲取鼠標(biāo)所在位置的單元項
第三步:TreeCtrlBT.h中首先聲明一個結(jié)構(gòu)用于保存單元項的相關(guān)信息,并把所有項的信息放入一個map。
實現(xiàn)代碼如下:typedef struct tagItemMsg
{
HTREEITEM hItem; //項的句柄
CBitmap ItemBitmap; //項的位圖
COLORREF crTransparent; //透明顏色
tagItemMsg()
{
hItem = NULL;
crTransparent = RGB(255,255,255);
}
~tagItemMsg()
{
if ( ItemBitmap.GetSafeHandle() )
{
ItemBitmap.DeleteObject();
}
}
}ITEM_MSG;
typedef map
ITEMMSG_MAP;
第四步:計算控件的客戶區(qū)域大小,以及滾動條滾動的偏移量。詳細過程參考源代碼
Calculate函數(shù)。
第五步:添加接口函數(shù)以及成員變量。如下:
(注意:TransparentBlt函數(shù),需要包含msimg32.dll)
//設(shè)置背景位圖
BOOL SetBackgroudBitmap( UINT nID );
BOOL SetBackgroudBitmap(LPCTSTR lpszRecourceName);
//設(shè)置某一項位圖
void SetItemBitmap(HTREEITEM hItem, UINT nIdBitmap);
void SetItemBitmap(HTREEITEM hItem, LPCTSTR lpszBitmap);
//設(shè)置展開收縮的圖表
void SetExpandBitmap(UINT nIdExpand, UINT nIdCollapse, COLORREF crTransparent = RGB(255,255,255));
//插入新的項目
HTREEITEM InsertItemEx(HTREEITEM hParent, LPCTSTR lpszItem, UINT nIdBitmap = 0,
OLORREF crTransparent = RGB(255,255,255));
HTREEITEM InsertItemEx(HTREEITEM hParent, LPCTSTR lpszItem, LPCTSTR lpszBitmap,
COLORREF crTransparent = RGB(255,255,255));
//開啟橫線
void EnableRowLine( BOOL bEnable = TRUE );
//是否開啟橫線
BOOL IsEnableRowLine();
//開啟根節(jié)點背景
void EnableRootBk( BOOL bEnable = TRUE );
//是否開啟根節(jié)點背景
BOOL IsEnableRootBk();
//獲取某一項信息
ITEM_MSG* GetItemMsg(HTREEITEM hItem);
第六步:繪制控件。需要的繪制函數(shù)如下://繪制漸變色矩形區(qū)域
void GradientFillRect( CDC *pDC, CRect &rect, COLORREF col_from, COLORREF col_to, bool vert_grad );
//繪制控件背景
void DrawBackgroudBitmap(CDC* pDc);
//繪制單元項
void DrawItem( CDC* pDC );
//繪制單元項下部橫線
void DrawRowLine(CPoint ptBegin, CPoint ptEnd, CDC *pDc = NULL);
//繪制展開收縮按鈕
void DrawExpand(CRect rect, int state, CDC *pDc = NULL);
//繪制單元項位圖
void DrawItemBitmap(CRect rect, HTREEITEM hItem, CDC *pDc = NULL);
//繪制單元項目文本
void DrawItemText(CRect rect, HTREEITEM hItem, bool bselected,CDC *pDc = NULL);

