美文网首页
MFC 带有 CheckBox 的 CTreeCtrl 结点

MFC 带有 CheckBox 的 CTreeCtrl 结点

作者: 云胡同学 | 来源:发表于2019-11-08 15:28 被阅读0次

初始化 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));
}

相关文章

  • MFC 带有 CheckBox 的 CTreeCtrl 结点

    初始化 CTreeCtrl 递归展开 CTreeCtrl 勾选根节点同步勾选子节点 勾选所有子节点同步勾选它的根节点

  • 力扣算法 - 链表的中间结点

    链表的中间结点 题目 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。 如果有两个中间结点,则返回...

  • LeetCode 876. 链表的中间结点

    876. 链表的中间结点 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返...

  • LeetCode 链表 > 876. 链表的中间结点

    876.链表的中间结点给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第...

  • 4.4 哈夫曼树和哈夫曼编码

    1.带权路径长度(WPL): 设二叉树有n个叶子结点,每个叶子结点带有权值 wk,从根结点到每个叶子结点的长度为 ...

  • 876. 链表的中间结点

    给定一个带有头结点 head 的非空单链表,返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。输入:...

  • leetCode (js):876.链表的中间结点

    给定一个带有头结点 head 的非空单链表,返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。 示例...

  • 链表的中间结点

    给定一个带有头结点 head 的非空单链表,返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。 示例...

  • 链表--求链表的中间结点

    给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。 输入:...

  • 链表中中间的点

    题目 给定一个带有头结点 head 的非空单链表,返回链表的中间结点。 如果有两个中间结点,则返回第二个中间结点。...

网友评论

      本文标题:MFC 带有 CheckBox 的 CTreeCtrl 结点

      本文链接:https://www.haomeiwen.com/subject/odxwbctx.html