CTreeCtrl 父结点联动子结点CheckBox
2011-06-22 10:25 chainchan 阅读(1475) 评论(0) 编辑 收藏 举报网上搜索了一番,发现没有一个符合我的要求的,于是自己写。
程序功能实现:在按下父结点的CheckBox后,其子结点全部跟随父结点的CheckBox属性设置。
实现步骤:
1.重载CTreeCtrl的单击事件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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);
}
}