C++ CTreeview的checkbox使用方法

所属分类: 软件编程 / C 语言 阅读数: 79
收藏 0 赞 0 分享

1. 消息事件

   (1)鼠标点击当前ITEM的CHECKBOX:引发NM_CLICK事件并传递TVHT_ONITEMSTATEICON。
   (2)鼠标点击当前ITEM的TEXT:引发NM_CLICK事件。
   (3)鼠标点击新ITEM的CHECKBOX:引发TVN_SELCHANGED事件、NM_CLICK事件并传递TVHT_ONITEMSTATEICON。
   (4)鼠标点击新ITEM的TEXT:引发NM_CLICK事件、TVN_SELCHANGED事件。

2. 消息事件总结

   点击ITEM会引发NM_CLICK事件。若点击CHECKBOX则传递TVHT_ONITEMSTATEICON。
   因此可不处理TVN_SELCHANGED事件而只处理NM_CLICK事件。

3. 消息处理注意事项

   (1)点击CHECKBOX后会自动更新CheckBox的状态,因此在处理代码中不需要使用SetCheck函数设置状态,而GetCheck函数返回也是其原始状态。
   (2)点击新CHECKBOX后不会自动将对应的ITEM设置为选择状态,需要使用SelectItem函数进行设置。

4. 使用方法

   (1)若传递TVHT_ONITEMSTATEICON
          获取选择ITEM的状态并取反
              若有子项则所有子项设置为一致
              若没有子项则
                  若当前状态为TRUE则设置父项为TRUE;否则遍历所有兄弟项,若全为FALSE则设置父项为FALSE。
         若选择了新ITEM则设置新ITEM为选择项
   (2)若未传递TVHT_ONITEMSTATEICON
          设置更新ITEM状态,获取选择ITEM的状态
              若有子项则所有子项设置为一致
              若没有子项则
                  若当前状态为TRUE则设置父项为TRUE;否则遍历所有兄弟项,若全为FALSE则设置父项为FALSE。

5. 响应NM_CLICK事件的函数代码

void CTestTimerDlg::OnClickTree(NMHDR* pNMHDR, LRESULT* pResult)
{
  // TODO: Add your control notification handler code here
  CPoint point;
  UINT uFlag;                 //接收有关点击测试的信息的整数
  HTREEITEM hTree;
  BOOL bCheck;
  GetCursorPos(&point);            //获取屏幕鼠标坐标
  m_TreeCtrl.ScreenToClient(&point);      //转化成客户坐标
  hTree = m_TreeCtrl.HitTest(point,&uFlag);  //返回与CtreeTtrl关联的光标的当前位置和句柄
  if((TVHT_NOWHERE & uFlag))
  {
    return;
  }
  if (hTree && (TVHT_ONITEMSTATEICON & uFlag)) //点中复选框
  {
    m_TreeCtrl.SelectItem(hTree);
    CString temp = m_TreeCtrl.GetItemText(hTree) + "\r\n";
    TRACE(temp);
    bCheck = m_TreeCtrl.GetCheck(hTree);   //获取当前复选状态
    SetChildCheck(hTree,!bCheck);       //设置子项复选状态
    SetParentCheck(hTree, bCheck);       //设置父项复选状态
  }
  *pResult = 0;
}

void CTestTimerDlg::SetChildCheck(HTREEITEM hTree,BOOL bCheck)
{
  m_TreeCtrl.Expand(hTree,TVE_EXPAND);
  hTree = m_TreeCtrl.GetChildItem(hTree); //获取子项句柄
  while (hTree)
  {
    m_TreeCtrl.SetCheck(hTree, bCheck);   
    SetChildCheck(hTree,bCheck);      //递归调用
    hTree = m_TreeCtrl.GetNextSiblingItem(hTree);  //获取兄弟的句柄
  }
}

void CTestTimerDlg::SetParentCheck(HTREEITEM hTree,BOOL bCheck)
{
  HTREEITEM hParent = m_TreeCtrl.GetParentItem(hTree);
  if (hParent)
  {
    HTREEITEM hChild = m_TreeCtrl.GetChildItem(hParent);
    while (hChild)
    {
      if (hChild == hTree)
      {
        hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
        continue;
      }
      BOOL bflag = m_TreeCtrl.GetCheck(hChild);
      if (bCheck == bflag)         //判断是否还有兄弟项被选择
      {
        return;
      }
      hChild = m_TreeCtrl.GetNextSiblingItem(hChild);
    }
    m_TreeCtrl.SetCheck(hParent,!bCheck);
    SetParentCheck(hParent,bCheck);       //设置父项的状态
  }

更多精彩内容其他人还在看

C++中四种对象生存期和作用域以及static的用法总结分析

以下是对C++中四种对象生存期和作用域以及static的用法进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++嵌套类与局部类详细解析

从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类之外的作用域使用该类名时,需要加名字限定
收藏 0 赞 0 分享

C++空类详解

以下是对C++中的空类进行了详细的介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C++之友元:友元函数和友元类详解

友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元
收藏 0 赞 0 分享

C++中返回指向函数的指针示例

int (*ff(int)) (int *,int);表示:ff(int)是一个函数,带有一个int型的形参,该函数返回int (*) (int *,int),它是一个指向函数的指针,所指向的函数返回int型并带有两个分别是Int*和int型的形参
收藏 0 赞 0 分享

C数据结构之单链表详细示例分析

以下是对C语言中的单链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

C数据结构之双链表详细示例分析

以下是对c语言中的双链表进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅析如何在c语言中调用Linux脚本

如何在c语言中调用Linux脚本呢?下面小编就为大家详细的介绍一下吧!需要的朋友可以过来参考下
收藏 0 赞 0 分享

深入解析unsigned int 和 int

以下是对unsigned int和int进行了详细的分析介绍,需要的朋友可以过来参考下
收藏 0 赞 0 分享

浅谈C++中的string 类型占几个字节

本篇文章小编并不是为大家讲解string类型的用法,而是讲解我个人比较好奇的问题,就是string 类型占几个字节
收藏 0 赞 0 分享
查看更多