剛開始以為實現起來很難,所以就在網上尋找實現的擴展控件,到最后才發現只要把CTreeCtrl 控件的Check Boxes 屬性設為真就可以了,會在每個樹形節點前添加一個CheckBox。
多選已經實現了,下面就是取得選中的項了,在網上搜了以下也沒有太好的辦法,於是就自己動手寫。大概思路是,遍歷整個樹形控件,訪問每個節點並判斷該節點是否被選中,使用CTreeCtrl類的成員函數GetCheck()來判斷,返回真假。
實例的界面如下:
代碼如下:
首先是插入測試節點函數,在OnInitDialog()函數中調用
1 void CCheckBoxTreeDlg::InsertNode() 2 { 3 HTREEITEM hRootItem, hSubItem; 4 CString strTest("TestNode"); 5 for(int i = 0;i < 10;i++) 6 { 7 hSubItem = m_treeTest.InsertItem(strTest + TCHAR(48 + i), 0, 0, TVI_ROOT, TVI_LAST); 8 m_treeTest.InsertItem(strTest + TCHAR(48 + i) + "child", 0, 0, hSubItem, TVI_LAST); 9 } 10 11 hRootItem = m_treeTest.GetRootItem(); 12 if(NULL != hRootItem) 13 { 14 hSubItem = m_treeTest.GetNextSiblingItem(hRootItem); 15 CString strText = m_treeTest.GetItemText(hSubItem); 16 } 17 }
接着是在增加按鈕的點擊消息處理函數中獲取選中的節點並插入到右邊的CListBox控件中
1 // 雙擊添加按鈕 2 void CCheckBoxTreeDlg::OnBnClickedBtnAdd() 3 { 4 // TODO: 在此添加控件通知處理程序代碼 5 HTREEITEM hRoot = m_treeTest.GetRootItem(); 6 7 while(NULL != hRoot) 8 { 9 CheckAndAddNode(hRoot); 10 hRoot = m_treeTest.GetNextSiblingItem(hRoot); 11 } 12 } 13 // 遞歸遍歷樹形控件 14 void CCheckBoxTreeDlg::CheckAndAddNode(HTREEITEM hRoot) 15 { 16 // 如果不是葉子節點 17 if(TRUE == m_treeTest.ItemHasChildren(hRoot)) 18 { 19 if(TRUE == m_treeTest.GetCheck(hRoot)) 20 { 21 // 插入所有頁節點 22 InsertAllLeaves(hRoot); 23 } 24 else 25 { 26 // 查詢所有節點,遞歸 27 HTREEITEM hChild = m_treeTest.GetChildItem(hRoot); 28 while(NULL != hChild) 29 { 30 CheckAndAddNode(hChild); 31 hChild = m_treeTest.GetNextSiblingItem(hChild); 32 } 33 } 34 } 35 else // 是葉子節點 36 { 37 // 被選中 38 if(TRUE == m_treeTest.GetCheck(hRoot)) 39 { 40 m_listClients.InsertString(m_listClients.GetCount(), m_treeTest.GetItemText(hRoot)); 41 } 42 } 43 } 44 // 插入所有頁節點 45 void CCheckBoxTreeDlg::InsertAllLeaves(HTREEITEM hRoot) 46 { 47 HTREEITEM hChild = m_treeTest.GetChildItem(hRoot); 48 while(NULL != hChild) 49 { 50 if(TRUE == m_treeTest.ItemHasChildren(hChild)) 51 { 52 InsertAllLeaves(hChild); 53 } 54 else 55 { 56 m_listClients.InsertString(m_listClients.GetCount(), m_treeTest.GetItemText(hChild)); 57 } 58 hChild = m_treeTest.GetNextSiblingItem(hChild); 59 } 60 }
有一點需要解釋的是,考慮到非葉子節點一般都是作為分類來使用的,所以添加的時候只添加葉子節點。
至此這個小程序的功能就完成了,但是有點不完美的是不能實現父節點與子節點的級聯選中或者取消選中。
這個功能在我的下篇博客中實現。