在CTreeCtrl中捕获复选框选中消息,父子节点选中状态联动 .

转自:http://apps.hi.baidu.com/share/detail/22849017

  1. void CMyDlg::OnClickTree1(NMHDR* pNMHDR, LRESULT* pResult)   
  2. {  
  3. // TODO: Add your control notification handler code here  
  4. NM_TREEVIEW* pHdr = (NM_TREEVIEW*)pNMHDR;  
  5. *pResult = 0;  
  6.   
  7. CPoint point;  
  8. UINT uFlag;  
  9. GetCursorPos(&point);  
  10. ScreenToClient(&point);  
  11.   
  12. HTREEITEM item = m_ctrlTree.HitTest(point, &uFlag);  
  13. if((item) && (TVHT_ONITEMSTATEICON & uFlag))     
  14. {     
  15. BOOL bCheck = m_ctrlTree.GetCheck(item);  
  16. SetItemCheckState(item, !bCheck);}     
  17. }  
  18.   
  19. /************************************************************************/  
  20. /* 根据选择的节点选中状态,设置相关节点的选中状态                   */  
  21. /************************************************************************/  
  22. void CHistoryDlg::SetItemCheckState(HTREEITEM item, BOOL bCheck)  
  23. {  
  24. SetChildCheck(item, bCheck);  
  25. SetParentCheck(item, bCheck);  
  26. }  
  27.   
  28. /************************************************************************/  
  29. /* 设置子节点的选中状态                                              */  
  30. /************************************************************************/  
  31. void CHistoryDlg::SetChildCheck(HTREEITEM item, BOOL bCheck)  
  32. {  
  33. HTREEITEM child = m_ctrlTree.GetChildItem(item);  
  34. while(child)  
  35. {  
  36. m_ctrlTree.SetCheck(child, bCheck);  
  37. SetChildCheck(child, bCheck);  
  38. child = m_ctrlTree.GetNextItem(child, TVGN_NEXT);  
  39. }  
  40. }  
  41.   
  42. /************************************************************************/  
  43. /* 设置父节点选中状态                                                 */  
  44. /************************************************************************/  
  45. void CHistoryDlg::SetParentCheck(HTREEITEM item, BOOL bCheck)  
  46. {  
  47. HTREEITEM parent = m_ctrlTree.GetParentItem(item);  
  48. if(parent == NULL)  
  49. return;  
  50.   
  51. if(bCheck)  
  52. m_ctrlTree.SetCheck(parent, bCheck);  
  53. else  
  54. {  
  55. HTREEITEM bro = m_ctrlTree.GetNextItem(item, TVGN_NEXT);  
  56. BOOL bFlag = false;  
  57. while(bro)  
  58. {  
  59. if(m_ctrlTree.GetCheck(bro))  
  60. {  
  61. bFlag = true;  
  62. break;  
  63. }  
  64. bro = m_ctrlTree.GetNextItem(bro, TVGN_NEXT);  
  65. }  
  66. if(!bFlag)  
  67. {  
  68. bro = m_ctrlTree.GetNextItem(item, TVGN_PREVIOUS);  
  69. while(bro)  
  70. {  
  71. if(m_ctrlTree.GetCheck(bro))  
  72. {  
  73. bFlag = true;  
  74. break;  
  75. }  
  76. bro = m_ctrlTree.GetNextItem(bro, TVGN_PREVIOUS);  
  77. }  
  78. }  
  79. if(!bFlag)  
  80. m_ctrlTree.SetCheck(parent, false);  
  81. }  
  82.   
  83. SetParentCheck(parent, GetCheck(parent));  
void CMyDlg::OnClickTree1(NMHDR* pNMHDR, LRESULT* pResult) 
{
// TODO: Add your control notification handler code here
NM_TREEVIEW* pHdr = (NM_TREEVIEW*)pNMHDR;
*pResult = 0;

CPoint point;
UINT uFlag;
GetCursorPos(&point);
ScreenToClient(&point);

HTREEITEM item = m_ctrlTree.HitTest(point, &uFlag);
if((item) && (TVHT_ONITEMSTATEICON & uFlag))   
{   
BOOL bCheck = m_ctrlTree.GetCheck(item);
SetItemCheckState(item, !bCheck);}   
}

/************************************************************************/
/* 根据选择的节点选中状态,设置相关节点的选中状态                   */
/************************************************************************/
void CHistoryDlg::SetItemCheckState(HTREEITEM item, BOOL bCheck)
{
SetChildCheck(item, bCheck);
SetParentCheck(item, bCheck);
}

/************************************************************************/
/* 设置子节点的选中状态                                              */
/************************************************************************/
void CHistoryDlg::SetChildCheck(HTREEITEM item, BOOL bCheck)
{
HTREEITEM child = m_ctrlTree.GetChildItem(item);
while(child)
{
m_ctrlTree.SetCheck(child, bCheck);
SetChildCheck(child, bCheck);
child = m_ctrlTree.GetNextItem(child, TVGN_NEXT);
}
}

/************************************************************************/
/* 设置父节点选中状态                                                 */
/************************************************************************/
void CHistoryDlg::SetParentCheck(HTREEITEM item, BOOL bCheck)
{
HTREEITEM parent = m_ctrlTree.GetParentItem(item);
if(parent == NULL)
return;

if(bCheck)
m_ctrlTree.SetCheck(parent, bCheck);
else
{
HTREEITEM bro = m_ctrlTree.GetNextItem(item, TVGN_NEXT);
BOOL bFlag = false;
while(bro)
{
if(m_ctrlTree.GetCheck(bro))
{
bFlag = true;
break;
}
bro = m_ctrlTree.GetNextItem(bro, TVGN_NEXT);
}
if(!bFlag)
{
bro = m_ctrlTree.GetNextItem(item, TVGN_PREVIOUS);
while(bro)
{
if(m_ctrlTree.GetCheck(bro))
{
bFlag = true;
break;
}
bro = m_ctrlTree.GetNextItem(bro, TVGN_PREVIOUS);
}
}
if(!bFlag)
m_ctrlTree.SetCheck(parent, false);
}

SetParentCheck(parent, GetCheck(parent));
 
 
 
带复选框的CTreeCtrl响应复选消息 
    
    
分类: C++文章 356人阅读 评论(0) 收藏 举报

1.在对话框中添加CTreeCtrl控件并勾选Check Boxes选项,为CTreeCtrl控件添加CTreeCtrl变量m_tree;

2.为CTreeCtrl控件添加NM_CLICK消息响应函数OnClickTree();代码如下:

OnClickTree(NMHDR* pNMHDR, LRESULT* pResult) 

{     CPoint point;     UINT uFlag;   //接收有关点击测试的信息的整数     HTREEITEM hTree;     BOOL bCheck;     GetCursorPos(&point);    //获取屏幕鼠标坐标     m_tree.ScreenToClient(&point);           //转化成客户坐标     hTree = m_tree.HitTest(point,&uFlag);    //返回与CtreeCtrl关联的光标的当前位置和句柄

    if (hTree && (TVHT_ONITEMSTATEICON & uFlag))  //点中复选框      {

          bCheck = m_treeSsid.GetCheck(hTree);      //获取当前复选状态           SetChildCheck(hTree,!bCheck);                  //设置子项复选状态       }        *pResult = 0; }

3.SetChildCheck()函数为自定义的处理函数(响应点击复选框后的具体处理函数):

下面的函数功能为:父项选中或取消选中,子项跟住选中或取消选中;

SetChildCheck(HTREEITEM hTree,BOOL bCheck) {   hTree = m_tree.GetChildItem(hTree);  //获取子项句柄   while (hTree)   {

      m_tree.SetCheck(hTree, bCheck);       SetChildCheck(hTree,bCheck);     //递归调用       hTree = m_tree.GetNextSiblingItem(hTree);    //获取兄弟的句柄   }  }

4.总结:关键是TVHT_ONITEMSTATEICON,它标志鼠标点击的是树形控件的复选框;


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值