CTreeCrtl消息处理

1. 定义变量 CTreeCtrl m_T;
2. 显示样式

3. 消息事件
   (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事件。
4. 消息事件总结
   点击ITEM会引发NM_CLICK事件。若点击CHECKBOX则传递TVHT_ONITEMSTATEICON。
   因此可不处理TVN_SELCHANGED事件而只处理NM_CLICK事件。
5. 消息处理注意事项
   (1)点击CHECKBOX后会自动更新CheckBox的状态,因此在处理代码中不需要使用SetCheck函数设置状态,而GetCheck函数返回也是其原始状态。
   (2)点击新CHECKBOX后不会自动将对应的ITEM设置为选择状态,需要使用SelectItem函数进行设置。
6. 使用方法
   (1)若传递TVHT_ONITEMSTATEICON
          获取选择ITEM的状态并取反
              若有子项则所有子项设置为一致
              若没有子项则
                  若当前状态为TRUE则设置父项为TRUE;否则遍历所有兄弟项,若全为FALSE则设置父项为FALSE。
         若选择了新ITEM则设置新ITEM为选择项
   (2)若未传递TVHT_ONITEMSTATEICON
          设置更新ITEM状态,获取选择ITEM的状态
              若有子项则所有子项设置为一致
              若没有子项则
                  若当前状态为TRUE则设置父项为TRUE;否则遍历所有兄弟项,若全为FALSE则设置父项为FALSE。
7. 响应NM_CLICK事件的函数代码

void myDialog::OnClickT(NMHDR* pNMHDR,LRESULT* pResult)
{
    //添加代码
    //获取鼠标位置
    CPoint cP;
    UINT uF=0;
    GetCursorPos(&cP);
    m_T.ScreenToClient(&cP);

    //获取位置对应的ITEM
    HTREEITEM hItem=m_T.HitTest(cP,&uF);
    //获取当前选择项ITEM
    HTREEITEM hItemSel=m_T.GetSelectItem();

    //若鼠标在ITEM外则退出
    if(TVHT_NOWHERE & uF)
        return;
    //处理:传递TVHT_ONITEMSTATEICON
    if(TVHT_ONITEMSTATEICON & uF)
    {
        BOOL bChk=!m_T.GetCheck(hItem);
        //父项处理
        if(m_T.ItemHasChildren(hItem))
        {
            HTREEITEM hChildItem=m_T.GetChildItem(hItem);
            while(hChildItem!=NULL)
            {
                m_T.SetCheck(hChildItem,bChk);
                hChildItem=m_T.GetNextItem(hChildItem,TVGN_NEXT);
            }
        }
      
        //兄弟项处理
        BOOL bFalse;
        bFalse=0;
        if(!m_T.ItemHasChildren(hItem))
        {
            HTREEITEM hParentItem=m_T.GetParentItem(hItem);
            if(bChk)
                m_T.SetCheck(hParentItem,bChk);
            if(!bChk)
            {
                HTREEITEM hChildItem=m_T.GetChildItem(hItem);
                while(hChildItem!=NULL & bFalse==0)
                {
                    if(hChildItem!=hItem)
                        bFalse=m_T.GetCheck(hChildItem);
                    hChildItem=m_T.GetNextItem(hChildItem,TVGN_NEXT);
                }
                if(bFalse==0)
                    m_T.SetCheck(hParentItem,bChk);
            }
        }
    }

    //处理:不传递TVHT_ONITEMSTATEICON
    else
    {
        m_T.SetCheck(hItem,!m_T.GetCheck(hItem));
        BOOL bChk=m_T.GetCheck(hItem);
        //父项处理
        if(m_T.ItemHasChildren(hItem))
        {
            HTREEITEM hChildItem=m_T.GetChildItem(hItem);
            while(hChildItem!=NULL)
            {
                m_T.SetCheck(hChildItem,bChk);
                hChildItem=m_T.GetNextItem(hChildItem,TVGN_NEXT);
            }
        }
      
        //兄弟项处理
        BOOL bFalse;
        bFalse=0;
        if(!m_T.ItemHasChildren(hItem))
        {
            HTREEITEM hParentItem=m_T.GetParentItem(hItem);
            if(bChk)
                m_T.SetCheck(hParentItem,bChk);
            if(!bChk)
            {
                HTREEITEM hChildItem=m_T.GetChildItem(hItem);
                while(hChildItem!=NULL & bFalse==0)
                {
                    if(hChildItem!=hItem)
                        bFalse=m_T.GetCheck(hChildItem);
                    hChildItem=m_T.GetNextItem(hChildItem,TVGN_NEXT);
                }
                if(bFalse==0)
                    m_T.SetCheck(hParentItem,bChk);
            }
        }
    }
    //添加代码结束

    *pResult=0
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值