MFC|MFC 带有 CheckBox 的 CTreeCtrl 结点

初始化 CTreeCtrl

BOOL OnInitDialog() { CDialogEx::OnInitDialog(); HTREEITEM hTempBuilding; m_hPublicBuilding = m_treeRoomType.InsertItem(_T("公共建筑"), NULL, NULL); hTempBuilding = m_treeRoomType.InsertItem(_T("办公室"), NULL, NULL, m_hPublicBuilding, TVI_LAST); hTempBuilding = m_treeRoomType.InsertItem(_T("会议室"), NULL, NULL, m_hPublicBuilding, TVI_LAST); m_hResidentialBuilding = m_treeRoomType.InsertItem(_T("居住建筑"), NULL, NULL); hTempBuilding = m_treeRoomType.InsertItem(_T("卧室"), NULL, NULL, m_hResidentialBuilding, TVI_LAST); hTempBuilding = m_treeRoomType.InsertItem(_T("其他"), NULL, NULL, m_hResidentialBuilding, TVI_LAST); ExpandTreeAllItem(); return TRUE; }

递归展开 CTreeCtrl
///-------------------------------------------------------- void ExpandTreeAllItem() { ExpandTreeItem(m_hPublicBuilding); // 展开公共建筑 ExpandTreeItem(m_hResidentialBuilding); // 展开居住建筑 }///--------------------------------------------------------- void ExpandTreeItem(HTREEITEM hTreeItem) { if(!m_treeRoomType.ItemHasChildren(hTreeItem)) { return; } HTREEITEM hNextItem = m_treeRoomType.GetChildItem(hTreeItem); while (hNextItem != NULL) { ExpandTreeItem(hNextItem); hNextItem = m_treeRoomType.GetNextItem(hNextItem, TVGN_NEXT); } m_treeRoomType.Expand(hTreeItem,TVE_EXPAND); }

勾选根节点同步勾选子节点
void CTCDAnalysisConfig::SetChildCheck(HTREEITEM hItem, BOOL bCheck) { hItem = m_treeRoomType.GetChildItem(hItem); //获取子项句柄 while (hItem) { m_treeRoomType.SetCheck(hItem, bCheck); SetChildCheck(hItem,bCheck); // 递归调用 hItem = m_treeRoomType.GetNextSiblingItem(hItem); // 获取兄弟结点的句柄 } }

勾选所有子节点同步勾选它的根节点
///-------------------------------------------------------------- void CTCDAnalysisConfig::SetParentCheck(HTREEITEM hItem, BOOL bCheck) { HTREEITEM hParent = m_treeRoomType.GetParentItem(hItem); if(hParent == NULL) { return; // 自身就是根节点 }if(bCheck) { HTREEITEM hSlibing = m_treeRoomType.GetNextSiblingItem(hItem); // 找一下后继兄弟结点 BOOL bFlag = TRUE; // 判断当前Item的前后兄弟节点中是否全都选中 while(hSlibing) { if(!m_treeRoomType.GetCheck(hSlibing)) { bFlag = FALSE; // 后继兄弟节点中有一个没有选中,只要有一个没选中,根节点就不该选中 break; } hSlibing = m_treeRoomType.GetNextSiblingItem(hSlibing); // 找下一个后继兄弟结点 }if(bFlag) { // 所有的后继兄弟结点都选中了 hSlibing = m_treeRoomType.GetPrevSiblingItem(hItem); // 找下一个前驱兄弟结点 while(hSlibing) { if(!m_treeRoomType.GetCheck(hSlibing)) { bFlag = FALSE; // 前驱兄弟节点中有一个没有选中 break; } hSlibing = m_treeRoomType.GetPrevSiblingItem(hSlibing); //GetNextItem(hSlibing, TVGN_PREVIOUS); } }// bFlag为TRUE,表示当前节点的所有前后兄弟节点都已选中,因此设置其父节点也为选中 if(bFlag) { m_treeRoomType.SetCheck(hParent, TRUE); }} else { // 当前节点设为未选中,当然其父节点也要设置为未选中 m_treeRoomType.SetCheck(hParent, FALSE); } // 递归调用 SetParentCheck(hParent, m_treeRoomType.GetCheck(hParent)); }

    推荐阅读