CTreeCtrl 父结点联动子结点CheckBox

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

程序功能实现:在按下父结点的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)