CTreeCtrl带CHECKBOX属性,实现联动效果(点击父节点全部子节点被选中)

1.为CTreeCtrl添加NMCLICK响应函数:

void CCTreeCtrlDlg::OnNMClickTree1(NMHDR *pNMHDR, LRESULT *pResult)
{
        CPoint pt;
    
        unsigned int flag;
    
        HTREEITEM hCurrentItem;  
    
        CView* pView = NULL;
    
        GetCursorPos(&pt);
    
        m_treeCtrlTest.ScreenToClient(&pt);//此处很重要,注意是控件对应变量调用的ScreenToClient函数,否则获得的不正确,进而导致下面执行的其他错误   
        hCurrentItem = m_treeCtrlTest.HitTest(pt, &flag);
    
        if ((hCurrentItem) && (flag & TVHT_ONITEMSTATEICON))//是点击CHECK框(TVHT_ONITEMSTATEICON
    
        {
           m_treeCtrlTest.SelectItem(hCurrentItem);
            BOOL bCheck = m_treeCtrlTest.GetCheck(hCurrentItem);
    
            SetItemCheckState(hCurrentItem, !bCheck);
    
        }

    *pResult = 0;
}

其余被调用的函数:

void CCTreeCtrlDlg::SetItemCheckState(HTREEITEM item, BOOL bCheck)

{

    SetChildCheck(item, bCheck);

    SetParentCheck(item, bCheck);

}



void CCTreeCtrlDlg::SetChildCheck(HTREEITEM item, BOOL bCheck)

{
    HTREEITEM child = m_treeCtrlTest.GetChildItem(item);
    while(child)
    {
        m_treeCtrlTest.SetCheck(child, bCheck);
        SetChildCheck(child, bCheck);
        child = m_treeCtrlTest.GetNextItem(child, TVGN_NEXT);
    }
}



void CCTreeCtrlDlg::SetParentCheck(HTREEITEM item, BOOL bCheck)
{
    HTREEITEM parent = m_treeCtrlTest.GetParentItem(item);
    if(parent == NULL)
        return;
    if(bCheck)
    {
        HTREEITEM bro = m_treeCtrlTest.GetNextItem(item, TVGN_NEXT);
        BOOL bFlag = TRUE;
        while(bro)
        {
            if(!m_treeCtrlTest.GetCheck(bro))
            {
                bFlag = FALSE;
                break;
            }
            bro = m_treeCtrlTest.GetNextItem(bro, TVGN_NEXT);
        }
        if(bFlag)
        {
            bro = m_treeCtrlTest.GetNextItem(item, TVGN_PREVIOUS);
            while(bro)
            {
                if(!m_treeCtrlTest.GetCheck(bro))
                {
                    bFlag = FALSE;
                    break;
                }
                bro = m_treeCtrlTest.GetNextItem(bro, TVGN_PREVIOUS);
            }
        }
        if(bFlag)
            m_treeCtrlTest.SetCheck(parent, TRUE);
    }
    else
        m_treeCtrlTest.SetCheck(parent, false);
 SetParentCheck(parent, m_treeCtrlTest.GetCheck(parent));
}

2.获得选中的带CHECKBOX各项文本(仅实现两级目录,即父亲节点最多只有孩子节点,无孙子)

void CCTreeCtrlDlg::OnBnClickedOk()
{
    // TODO: 在此添加控件通知处理程序代码

    HTREEITEM hCurrentItem;
    hCurrentItem = m_treeCtrlTest.GetRootItem();
    std::string strText;
    bool bRoot = false;
    while(hCurrentItem)
    {
        //处理此父节点(选择父节点时只显示父节点(不现实子节点))
      if (m_treeCtrlTest.GetCheck(hCurrentItem))
        {
            strText += m_treeCtrlTest.GetItemText(hCurrentItem) + ";";
            bRoot = true;
        }
      //此父节点下的子节点(未选择父节点)
      if (!bRoot && m_treeCtrlTest.ItemHasChildren(hCurrentItem))
      {
          HTREEITEM h = m_treeCtrlTest.GetChildItem(hCurrentItem);
          std::string str;
          GetSelectedSlibing(h,str);
          if (str != "")
          {
              strText = strText + str + ";";
          }
      }
      bRoot = false;
     hCurrentItem = m_treeCtrlTest.GetNextItem(hCurrentItem, TVGN_NEXT);
    
    }
    
    m_strSelectedLeaf = strText;


    CDialogEx::OnOK();
}

//传入父节点下的第一个子节点即可获得此父节点下被选中的所有子节点内容
void CCTreeCtrlDlg::GetSelectedSlibing(HTREEITEM h,std::string& strTemp)
{
    HTREEITEM h1 = h;
    //std::string str;
    //m_treeCtrlTest.GetItemText(h);  //这样取的,你要显示或保存都可以(自己去实现)
    /*if (m_treeCtrlTest.GetCheck(h1))
    {
    strTemp += str;
    }*/
    while(h1)
    {   
        if (m_treeCtrlTest.GetCheck(h1))
        {
            strTemp += m_treeCtrlTest.GetItemText(h1);
        }
        h1=m_treeCtrlTest.GetNextSiblingItem(h1);
        
    }
}

 

 

你可能感兴趣的:(MFC)