背景
本篇旨在MSDN幫助文檔下總結樹形控件Tree Control的使用,並列出碰到的具體問題。
正文
樹形控件Tree Control的類則是CTreeCtrl,具體成員對象詳見鏈接,以下則描述一些典型應用。
-
樹形控件的創建
當然,所有控件均有兩種實現方式,一是在對話框模版中直接將控件Tree Control拖入對應的窗口上,另一種則是通過CtreeCtrl內的成員函數Creat(..)來創建。本文章不想過於繁瑣,因此只記錄前者。當然也可以根據Creat(...)函數的參數來創建,詳見第三部分的關於雞啄米博客的參考鏈接。
為了能對添加的樹形控件進行操作,因此需要在對應的屬性控件添加變量——在對應的窗口的樹形控件右擊選擇添加變量,取一個變量名,此處為m_DevlistTree,至此則由VS自動創建了該控件的控制變量m_DevlistTree。 -
在樹形控件上添加元素
調用函數CTreeCtrl::InsertItem(...),此函數有如下幾個函數原型;
HTREEITEM InsertItem(LPTVINSERTSTRUCT lpInsertStruct);
此函數根據結構體LPTVINSERTSTRUCT來添加屬性控件元素,結構體如下:
typedef struct {
//插入對應節點下,為TVI_ROOT value 或者 NULL則表示插入的在根節點下。
HTREEITEM hParent;
/*定義按照何種順序插入屬性控件。
TVI_FIRST:在節點下最開頭插入元素
TVI_LAST:在節點下最末尾插入元素(當節點下元素特別多的情況下,使用該屬性,在添加過程中會導致整個APP卡在此處,直至添加完畢。)
TVI_ROOT:在根節點插入元素
TVI_SORT:按照元素的首字母來排序插入元素
*/
HTREEITEM hInsertAfter;
/*
該Item結構體描述了插入的元素的屬性。
*/
TVITEM item;
#endif
} TVINSERTSTRUCT, *LPTVINSERTSTRUCT;
按照Item結構體元素定義的屬性來插入元素,如下:
// 本次未使用該函數,待使用的時候再來做詳細解釋。
HTREEITEM InsertItem(
UINT nMask,
LPCTSTR lpszItem,
int nImage,
int nSelectedImage,
UINT nState,
UINT nStateMask,
LPARAM lParam,
HTREEITEM hParent,
HTREEITEM hInsertAfter);
以下函數很好理解,在根節點的尾部插入文本地址為lpszItem的元素:
HTREEITEM InsertItem(
LPCTSTR lpszItem,
HTREEITEM hParent = TVI_ROOT,
HTREEITEM hInsertAfter = TVI_LAST);
這個函數,則同樣是在根節點的尾部插入文本地址為lpseItem的元素,不同的是,指定了元素圖片索引以及元素被選中后的圖片索引。
HTREEITEM InsertItem(
LPCTSTR lpszItem,
int nImage,
int nSelectedImage,
HTREEITEM hParent = TVI_ROOT,
HTREEITEM hInsertAfter = TVI_LAST);
圖片的索引操作如下:
// 圖標句柄數組
HICON hIcon[3];
// 加載三個圖標,並將它們的句柄保存到數組
// 此三個圖標為加載進的ICON資源文件
hIcon[0] = theApp.LoadIcon(IDI_ICON0);
hIcon[1] = theApp.LoadIcon(IDI_ICON1);
hIcon[2] = theApp.LoadIcon(IDI_ICON2);
// 創建圖像序列CImageList對象
m_imageList.Create(32, 32, ILC_COLOR32, 3, 3);
// 將三個圖標添加到圖像序列
for (int i=0; i<3; i++)
{
m_imageList.Add(hIcon[i]);
}
// 為樹形控件設置圖像序列
m_webTree.SetImageList(&m_imageList, TVSIL_NORMAL);
// 至此,0代表IDI_ICON0 1代表IDI_ICON1 2代表IDI_ICON2
// 傳入對應的值既可以使對應的元素圖標覆蓋為對應的圖標。
- 將樹形控件折疊或者展開:
調用函數Expand(..)可實現,函數如下:
BOOL Expand(
HTREEITEM hItem,
UINT nCode );
/*
hItem: 要操作的Item
nCode: 要執行的操作:
*TVE_COLLAPSE:折疊
*TVE_COLLAPSERESET:折疊並移除所有的該節點下的子節點,必須配合TVE_COLLAPSE使用
*TVE_EXPAND 展開元素
*TVE_TOGGLE 當前為折疊則展開,當前為展開則折疊。
*/
- 獲取樹形控件的焦點Item
在樹形控件右擊選擇添加事件處理程序,消息類型選擇TVN_SELCHANGED,類列表的類選擇對應窗口的類,本初的類為CMenueditortestDlg,最后點擊添加編輯,生成的代碼如下:
void CMenueditortestDlg::OnTvnSelchangedTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
LPNMTREEVIEW pNMTreeView = reinterpret_cast<LPNMTREEVIEW>(pNMHDR);
*pResult = 0;
// TODO: 在此添加控件通知處理程序代碼
*pResult = 0;
HTREEITEM hItem = m_DevlistTree.GetSelectedItem(); // 獲取點擊的焦點Item
m_DevlistTree.Expand(hItem, TVE_EXPAND); // 將焦點Item展開
}
以上事件如宏TVN_SELCHANGED(select changed)所描述的一樣,當焦點由一個Item換為另外一個Item時,就會進入該處理函數,此處函數內執行的代碼的效果既是,鼠標單擊到某個Item,對應的Item會被展開。
參考鏈接
MSDN關於CTreeCtrl的幫助文檔。;
雞啄米的博客VS2010/MFC編程入門之三十一(常用控件:樹形控件Tree Control 下)詳細敘述了該控件的使用。
至此記錄完畢。
記錄時間:2017-2-15
記錄地點:深圳WZ
