• 计算机图形学与计算几何经典必备书单整理,下载链接可参考:https://www.stubbornhuang.com/1256/

  • 感谢大家访问本站,希望本站的内容可以帮助到大家!

  • 如果觉得本站的内容有帮助,可以考虑打赏博主哦!

  • 本站由于前段时间遭受到大量临时和国外邮箱注册,所以对可注册的邮箱类型进行了限制!

  • 问题反馈可发送邮件到stubbornhuang@qq.com

  • 本站会放置Google广告用于维持域名以及网站服务器费用。

  • 欢迎大家交换友链,可在https://www.stubbornhuang.com/申请友情链接进行友链交换申请!

  • 在本站开通年度VIP,无限制下载本站资源和阅读本站文章

  • 工资「喂饱肚子」,副业「养活灵魂」!

Duilib – 为列表控件UIList添加列表子项右键点击消息响应功能

Duilib 发布于2022-10-18 阅读 4,035次 0次评论 0次点赞 本文共3985个字,阅读需要10分钟。

1 Duilib原有列表子项鼠标点击消息的弊端

Duilib中原有的列表控件UIList中的子项CListContainerElementUICListLabelElementUI的鼠标左键消息和右键消息全部都是发送的DUI_MSGTYPE_ITEMCLICK消息,也就是说我们只能知道列表项被点击,并不能分清是左键点击还是右键点击,这在源码中也有体现,比如

if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_RBUTTONDOWN )
{
    if( IsEnabled() ) {
        m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMCLICK);
        Select();
        Invalidate();
    }
    return;
}

在现实的开发需求中,我们经常需要对列表中的子项进行操作,而这就经常设计为右键点击列表中的子项然后弹出菜单,如果我们不能分清是鼠标左键还是右键点击消息,就没办法进行开发,所以本文将区分列表中子项的鼠标左键和鼠标右键点击消息。

2 源码修改

2.1 修改Core/UIDefine.h

修改Core/UIDefine.h文件,在该文件中增加列表子项点击的右键消息,如下

#define DUI_MSGTYPE_ITEMRCLICK                (_T("itemrclick"))

我们将这个消息定义为DUI_MSGTYPE_ITEMRCLICK

2.2 修改UI/UIList.cpp

修改UI/UIList.cpp,原有的子项CListContainerElementUIDoEvent(TEventUI& event)函数源码如下,

void CListContainerElementUI::DoEvent(TEventUI& event)
{
    if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
        if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
        else CContainerUI::DoEvent(event);
        return;
    }

    if( event.Type == UIEVENT_DBLCLICK )
    {
        if( IsEnabled() ) {
            Activate();
            Invalidate();
        }
        return;
    }
    if( event.Type == UIEVENT_KEYDOWN )
    {
        if (IsKeyboardEnabled() && IsEnabled()) {
            if( event.chKey == VK_RETURN ) {
                Activate();
                Invalidate();
                return;
            }
        }
    }
    if( event.Type == UIEVENT_BUTTONDOWN || event.Type == UIEVENT_RBUTTONDOWN )
    {
        if( IsEnabled() ) {
            m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMCLICK);
            Select();
            Invalidate();
        }
        return;
    }
    if( event.Type == UIEVENT_BUTTONUP ) 
    {
        return;
    }
    if( event.Type == UIEVENT_MOUSEMOVE )
    {
        return;
    }
    if( event.Type == UIEVENT_MOUSEENTER )
    {
        if( ::PtInRect(&m_rcItem, event.ptMouse ) ) {
            if( IsEnabled() ) {
                if( (m_uButtonState & UISTATE_HOT) == 0  ) {
                    m_uButtonState |= UISTATE_HOT;
                    Invalidate();
                }
            }
        }
    }
    if( event.Type == UIEVENT_MOUSELEAVE )
    {
        if( !::PtInRect(&m_rcItem, event.ptMouse ) ) {
            if( IsEnabled() ) {
                if( (m_uButtonState & UISTATE_HOT) != 0  ) {
                    m_uButtonState &= ~UISTATE_HOT;
                    Invalidate();
                }
            }
            if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this);
        }
        else {
            if (m_pManager) m_pManager->AddMouseLeaveNeeded(this);
            return;
        }
    }

    // An important twist: The list-item will send the event not to its immediate
    // parent but to the "attached" list. A list may actually embed several components
    // in its path to the item, but key-presses etc. needs to go to the actual list.
    if( m_pOwner != NULL ) m_pOwner->DoEvent(event); else CControlUI::DoEvent(event);
}

我们将鼠标左键消息与鼠标邮件消息进行分离,修改后的DoEvent(TEventUI& event)函数如下:

void CListContainerElementUI::DoEvent(TEventUI& event)
{
    if( !IsMouseEnabled() && event.Type > UIEVENT__MOUSEBEGIN && event.Type < UIEVENT__MOUSEEND ) {
        if( m_pOwner != NULL ) m_pOwner->DoEvent(event);
        else CContainerUI::DoEvent(event);
        return;
    }

    if( event.Type == UIEVENT_DBLCLICK )
    {
        if( IsEnabled() ) {
            Activate();
            Invalidate();
        }
        return;
    }
    if( event.Type == UIEVENT_KEYDOWN )
    {
        if (IsKeyboardEnabled() && IsEnabled()) {
            if( event.chKey == VK_RETURN ) {
                Activate();
                Invalidate();
                return;
            }
        }
    }
    if( event.Type == UIEVENT_BUTTONDOWN)
    {
        if( IsEnabled() ) {
            m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMCLICK);
            Select();
            Invalidate();
        }
        return;
    }
    if (event.Type == UIEVENT_RBUTTONDOWN)
    {
        if (IsEnabled()) {
            m_pManager->SendNotify(this, DUI_MSGTYPE_ITEMRCLICK);
            Select();
            Invalidate();
        }
        return;
    }
    if( event.Type == UIEVENT_BUTTONUP ) 
    {
        return;
    }
    if( event.Type == UIEVENT_MOUSEMOVE )
    {
        return;
    }
    if( event.Type == UIEVENT_MOUSEENTER )
    {
        if( ::PtInRect(&m_rcItem, event.ptMouse ) ) {
            if( IsEnabled() ) {
                if( (m_uButtonState & UISTATE_HOT) == 0  ) {
                    m_uButtonState |= UISTATE_HOT;
                    Invalidate();
                }
            }
        }
    }
    if( event.Type == UIEVENT_MOUSELEAVE )
    {
        if( !::PtInRect(&m_rcItem, event.ptMouse ) ) {
            if( IsEnabled() ) {
                if( (m_uButtonState & UISTATE_HOT) != 0  ) {
                    m_uButtonState &= ~UISTATE_HOT;
                    Invalidate();
                }
            }
            if (m_pManager) m_pManager->RemoveMouseLeaveNeeded(this);
        }
        else {
            if (m_pManager) m_pManager->AddMouseLeaveNeeded(this);
            return;
        }
    }

    // An important twist: The list-item will send the event not to its immediate
    // parent but to the "attached" list. A list may actually embed several components
    // in its path to the item, but key-presses etc. needs to go to the actual list.
    if( m_pOwner != NULL ) m_pOwner->DoEvent(event); else CControlUI::DoEvent(event);
}

通过上述代码我们为Duilib扩展了列表子项的右键点击消息响应函数。

2.3 如何使用

在List控件的主窗口的Notify(TNotifyUI& msg)函数中增加对消息的响应,

else if (_tcsicmp(msg.sType, _T("itemrclick")) == 0)
{
    ProcessItemrclickMessage(msg);
}

然后在ProcessItemrclickMessage函数中判断msg.pSender的父控件是哪个List控件,然后弹出相应的菜单即可。

参考链接

欢迎扫码关注我的微信公众号,及时获取文章更新

微信公众号二维码

本文作者:StubbornHuang

版权声明:本文为站长原创文章,如果转载请注明原文链接!

原文标题:Duilib – 为列表控件UIList添加列表子项右键点击消息响应功能

原文链接:https://www.stubbornhuang.com/2389/

发布于:2022年10月18日 10:12:36

修改于:2023年06月21日 17:57:37

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

文章末尾
上一篇
C++ - 数组初始化
C++
下一篇
Duilib - Edit编辑控件输入文字时编辑框背景颜色不是所设置的背景颜色的问题
Duilib
当前分类随机文章推荐

发表评论

您必须 [ 登录 ] 才能发表留言!

关注我们的公众号

微信公众号