LibUIDK 学习------CSkinTreeCtrl控件中复选框

258 篇文章 9 订阅

实现的功能主要是点击父节点,子节点全部选中;子节点需要全部选中,父节点才可以选中:

 

 

头文件:

BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);

    void SetChildCheck(HTREEITEM hItem, BOOL bCheck);
    void SetParentCheck(HTREEITEM hItem);
    LRESULT OnUserMsg(WPARAM wParam, LPARAM lParam);

实现文件中:

#define UM_CHANGE_PARENT_CHECK_STATUS (WM_USER+1011)
#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((lp & 0xFFFF0000)>>16)

BEGIN_MESSAGE_MAP(MainFrm, CUIWnd)

    ON_MESSAGE(UM_CHANGE_PARENT_CHECK_STATUS, &MainFrm::OnUserMsg)
END_MESSAGE_MAP()

BOOL MainFrm::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{
    // TODO: Add your specialized code here and/or call the base class
    LPNMHDR lpnmh = (LPNMHDR)lParam;
    TVHITTESTINFO ht = { 0 };

    if ((lpnmh->code == NM_CLICK) && (lpnmh->idFrom == IDC_TREECTRL_1))
    {
        DWORD dwpos = GetMessagePos();

        // include <windowsx.h> and <windows.h> header files
        ht.pt.x = GET_X_LPARAM(dwpos);
        ht.pt.y = GET_Y_LPARAM(dwpos);
        ::MapWindowPoints(HWND_DESKTOP, lpnmh->hwndFrom, &ht.pt, 1);

        TreeView_HitTest(lpnmh->hwndFrom, &ht);

        if (TVHT_ONITEMSTATEICON & ht.flags)
        {
            // 获取当前选中状态(点击完成后的状态相反)
            BOOL bChecked = m_pTree1->GetCheck(ht.hItem);

            // 设置子结点选中状态
            SetChildCheck(ht.hItem, !bChecked);

            // 设置父结点的状态
            // 由于是当前点击的状态,而不是点击后的状态, 还未更新, 所以通过消息来设置
            ::PostMessage(m_hWnd, UM_CHANGE_PARENT_CHECK_STATUS, (WPARAM)ht.hItem, 0);
        }
    }

    return CUIWnd::OnNotify(wParam, lParam, pResult);
}

// 设置子结点选中状态
void MainFrm::SetChildCheck(HTREEITEM hItem, BOOL bCheck)
{
    // 得到子结点
    HTREEITEM hChildItem = m_pTree1->GetChildItem(hItem);
    while (hChildItem != NULL)
    {
        // 设置子结点选中状态
        m_pTree1->SetCheck(hChildItem, bCheck);

        // 递归遍历孩子节点
        SetChildCheck(hChildItem, bCheck);

        // 对兄弟结点进行遍历
        hChildItem = m_pTree1->GetNextItem(hChildItem, TVGN_NEXT);
    }
}

// 设置父结点选中状态
void MainFrm::SetParentCheck(HTREEITEM hItem)
{
    // 得到父节点
    HTREEITEM hParent = m_pTree1->GetParentItem(hItem);
    if (NULL != hParent)
    {
        // 记录父结点的状态     
        BOOL bParentIsChecked = TRUE;

        // 检查父结点的所有子结点
        HTREEITEM hChild = m_pTree1->GetNextItem(hParent, TVGN_CHILD);
        while (hChild)
        {
            // 如有任一子结点为非选中状态, 父节点不满足全选条件,置为unchecked
            if (!m_pTree1->GetCheck(hChild))
            {
                bParentIsChecked = FALSE;
                break;
            }
            hChild = m_pTree1->GetNextSiblingItem(hChild);
        }

        // 设置父结点的状态
        m_pTree1->SetCheck(hParent, bParentIsChecked);

        // 递归检查父节点
        SetParentCheck(hParent);
    }
}

// 自定义消息处理
LRESULT MainFrm::OnUserMsg(WPARAM wParam, LPARAM lParam)
{
    HTREEITEM hItem = (HTREEITEM)(wParam);
    if (hItem)
    {
        SetParentCheck(hItem);
    }

    return 0L;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值