CTreeCtrl 父结点联动子结点CheckBox

来自http://www.cnblogs.com/chain2012/archive/2011/06/22/2086647.html

网上搜索了一番,发现没有一个符合我的要求的,于是自己写。



程序功能实现:在按下父结点的CheckBox后,其子结点全部跟随父结点的CheckBox属性设置。


实现步骤:


1.重载CTreeCtrl的单击事件

void CXMLTree::OnNMClickTree(NMHDR *pNMHDR, LRESULT *pResult)
{
    NM_TREEVIEW* pHdr = (NM_TREEVIEW*)pNMHDR;
    CPoint point;
    UINT uFlag;
    GetCursorPos(&point);
    ScreenToClient(&point);
    HTREEITEM hItem = m_TreeCtrl.HitTest(point, &uFlag);
    if((hItem) && (TVHT_ONITEMSTATEICON & uFlag))   
    {   
        // 发送消息,在进行父节点和子节点关联之前判断CheckBox前后的状态
        PostMessage(UM_CHECKSTATECHANGE, 0, (LPARAM)hItem);
    }
    else
    {
        *pResult = 0;
    }
}

2.重载双击时间,屏蔽掉因双击展开结点而改变CheckBox的状态

void CXMLTree::OnNMDblclkTree(NMHDR *pNMHDR, LRESULT *pResult)
{
          *pResult = TRUE;
}

3.写自己Post的Message函数

#define UM_CHECKSTATECHANGE (WM_USER + 100)

//Message Map里面加这句
ON_MESSAGE(UM_CHECKSTATECHANGE, &CXMLTree::OnMyMessage)

afx_msg LRESULT CXMLTree::OnMyMessage(WPARAM wParam, LPARAM lParam)
{
    HTREEITEM hItem = (HTREEITEM)lParam;

    DWORD data = m_TreeCtrl.GetItemData(hItem);
    BOOL bCheck = m_TreeCtrl.GetCheck(hItem);
    CString cStrTemp = m_TreeCtrl.GetItemText(hItem);
    //AfxMessageBox(cStrTemp);

    if(data==1 && !bCheck) 
    {
        //AfxMessageBox(_T("Check状态从check到uncheck"));
        //SetChildCheck(hItem, 0); 
        SetParentChildNodeCheck(hItem, 0);  //按下CheckBox后触发的动作
        m_TreeCtrl.SetItemData(hItem, 0);
    }
    if(data==0 && bCheck) {
        //AfxMessageBox(_T("Check状态从uncheck到check"));
        //SetChildCheck(hItem, 1); 
        SetParentChildNodeCheck(hItem, 1); //按下CheckBox后触发的动作

        m_TreeCtrl.SetItemData(hItem, 1);
    }
    return 0L;
}

4.写递归函数,实现父结点关联子结点

BOOL CXMLTree::SetParentChildNodeCheck(HTREEITEM hItem, BOOL bCheck)
{
    if (hItem==NULL)
        return FALSE;

    HTREEITEM hChild = m_TreeCtrl.GetChildItem(hItem);
    SetChildCheck(hChild, bCheck); 
    m_TreeCtrl.SetCheck(hItem, bCheck);
    return TRUE;
}



//递归函数
void CXMLTree::SetChildCheck(HTREEITEM hItem, BOOL bCheck)
{
    if (hItem == NULL) return;

    m_TreeCtrl.SetCheck(hItem, bCheck); 

    HTREEITEM hSibling = m_TreeCtrl.GetNextItem(hItem, TVGN_NEXT);
    while (hSibling)
    {
        m_TreeCtrl.SetCheck(hSibling, bCheck); 
        HTREEITEM hSibChild = m_TreeCtrl.GetChildItem(hSibling);

        if (hSibChild)
        {
            SetChildCheck(hSibChild, bCheck);
        }

        hSibling = m_TreeCtrl.GetNextItem(hSibling, TVGN_NEXT);
    }
    HTREEITEM hChild = m_TreeCtrl.GetChildItem(hItem);
    if (hChild!=NULL)
    {
        SetChildCheck(hChild, bCheck);
    }
}


你可能感兴趣的:(递归,checkbox,treeview,CTreeCtrl)