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を書くメッセージ関数
#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);
    }
}