修复duilib-MenuWnd无法响应子项事件

本文介绍如何在Duilib中实现菜单点击事件响应,包括修改源码以获取点击的菜单项名称,并在自定义窗口类中正确处理WM_MENUCLICK消息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

官方duilib的下载地址:https://github.com/duilib/duilib

1.首先使用一个按钮 或者其他控件点击能够加载 一个MenuWnd.

CMenuWnd *pWnd = new CMenuWnd();
        CDuiPoint point = msg.ptMouse;
        ClientToScreen(m_hWnd, &point);

        pWnd->Init(NULL, _T("user_menu.xml"), point, &m_pm, &m_MenuCheckInfo, true);

user_menu.xml 文件

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

<Window >
  <Font name="微软雅黑" size="16" bold="false" default="true" />
  <Font name="微软雅黑" size="12" bold="true"/>
   <Default name="Menu" value="bordersize=&quot;1&quot; bordercolor=&quot;#FFB5B5B5&quot; inset=&quot;3,4,3,4&quot; itemtextpadding=&quot;35,0,0,0&quot; bkcolor=&quot;#FFFFFFFE&quot; itemselectedbkcolor=&quot;#FFB5B5B5&quot;" />
    <Menu >
        <MenuElement name="user_menu_safe" text="账户安全" width="100" icon="" iconsize="23,23" />
        <!--<MenuElement type="line" />-->
        <MenuElement name="user_menu_switch" text="切换账户" width="100" icon="" iconsize="23,23" />
    </Menu>
</Window>

2.在官方的duilib里是有WM_MENUCLICK,这个消息是响应菜单的消息,但是直接使用是无法响应,原因在于点击子项的时候,得不到点击子项的Name,然后就无法找到MenuElement的Name,然后无法做出响应。
如果你使用的duilib中没有WM_MENUCLICK,说明你不是官方的duilib ,下载官方的。

解决办法:
1.找到UIMenu.h 添加两个方法:

static CDuiString GetClickedMenuName();   //得到点击的菜单子项的名字
    static void SetClickedMenuName(const CDuiString& sMenuName);   //设置点击菜单子项的名字

2.在CMenuWnd类中添加一个变量用于存储菜单子项的Name

static CDuiString   s_clickedMenuItem;  //被单击的菜单项名字

在UIMenu.cpp文件中也添加这个变量

CDuiString CMenuWnd::s_clickedMenuItem;

3.实现上面的两个方法

void CMenuWnd::SetClickedMenuName(const CDuiString& sMenuName)
    {
        s_clickedMenuItem = sMenuName;
    }

CDuiString CMenuWnd::GetClickedMenuName()
    {
        return s_clickedMenuItem;
    }

4.这时候要在UIMenu.cpp中发送点击消息的地方,设置点击菜单子项的名字,就可以正常的发送了

CMenuWnd::SetClickedMenuName(GetName());   //设置菜单子目录的Name 
                    if (!PostMessage(CMenuWnd::GetGlobalContextMenuObserver().GetManager()->GetPaintWindow(), WM_MENUCLICK, (WPARAM)pMenuCmd, (LPARAM)this))
                    {
                        delete pMenuCmd;
                        pMenuCmd = NULL;
                    }

找到不到地方的,自己搜索一下。

5.在你的界面类中,响应WM_MENUCLICK消息,放在HandleCustomMessage或者HandleMessage中,都行。

CDuiString strMenuName = CMenuWnd::GetClickedMenuName();

使用上面代码得到菜单子项的Name,就可以正常匹配MenuElement的Name了。

效果:
这里写图片描述

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值