代码改变世界

CTreeCtrl 父结点联动子结点CheckBox

2011-06-22 10:25  chainchan  阅读(1475)  评论(0编辑  收藏  举报

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

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