duilib菜单动态添加

这篇博客介绍了如何在Duilib中创建自定义菜单窗口,包括XML布局和动态添加菜单项的方法。作者遇到了网上教程的局限性,如需要重新编译库和静态的菜单结构。最终,他们通过自定义接口解决动态添加菜单项的问题,并提供了代码示例,展示了如何初始化和设置菜单大小。然而,代码缺乏通用性。

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

网上有很多,都特么不好使。
有的直接在xml中使用了Menu
也就是

<menu>
...
</menu>

这样子要重新编译duilib,不然那不识别这种形式。
再就是 动态添加的问题。
网上的demo大部分是通过xml来显示菜单的,菜单的层级结构也是定死的。不好用。
最后我用的是官网的那个暂时解决了问题。
在这里插入图片描述
说暂时,是因为,代码不具有通用性。
这是菜单的xml

<?xml version="1.0" encoding="utf-8"?>
<Window name="menu_window" bktrans="true"  size="100,82">
 <Font id="0" name="宋体" size="13" bold="false"/>
 <Font id="1" name="宋体" size="12"/>
 <Font id ="3" name="微软雅黑" size="13" bold="false" italic="false" />
<VerticalLayout bkimage="file='menu_bk.png' corner='40,8,8,8'" hole="false">
	<List name="menu_list"  header="hidden" inset="8,8,8,8" itemhotimage="file='menu_item_select_hot.png' corner='2,2,2,2'" itemdisabledbkcolor="#FF0000FF">
		<ListContainerElement name="menu_Open" height="22">
			<Label text="打开" align="center" name="open_label" mouse="false"/>
		</ListContainerElement>
	</List>
</VerticalLayout>
</Window>

动态添加item的方式。

			CMenuWnd* pMenu = new CMenuWnd();
			if (pMenu == NULL) { return; }
			//传入item的值
			pMenu->setMenuType("showNumberMenu");
			pMenu->setContentList(ZHRWConfigSettings::GetInstance()->getAllShowNumberList());
			//POINT pt = { msg.ptMouse.x, msg.ptMouse.y };
			//::ClientToScreen(*this, &pt);
			CDuiRect rcWindow;
			GetWindowRect(m_hWnd, &rcWindow);
			rcWindow.top = rcWindow.top + msg.pSender->GetPos().bottom;
			rcWindow.left = rcWindow.left + msg.pSender->GetPos().left;
			POINT pt = { rcWindow.left ,rcWindow.top };

			pMenu->Init(msg.pSender, pt);

其中setContentList()接口是我自定义的。


    LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        m_pm.Init(m_hWnd);
        CDialogBuilder builder;
        CControlUI* pRoot = builder.Create(_T("menu_show_number.xml"), (UINT)0, NULL, &m_pm);
        ASSERT(pRoot && "Failed to parse XML");
        m_pm.AttachDialog(pRoot);

		
        //尝试自定义添加
        CListUI* pUiList = static_cast<CListUI*>(m_pm.FindControl(_T("menu_list")));
        pUiList->RemoveAll();

        for (auto it = m_contentList.begin();it != m_contentList.end(); it++)
        {
            string t_strContent = *it;
			CListContainerElementUI* pContanerUi = new CListContainerElementUI();
			CLabelUI* pLabelUi = new CLabelUI();
			pLabelUi->SetText(t_strContent.c_str());
            pLabelUi->SetFont(3);
			pLabelUi->SetFixedHeight(24);
            pLabelUi->SetTextPadding(CDuiRect(4, 0, 0, 0));

			pContanerUi->Add(pLabelUi);
			pContanerUi->SetFixedHeight(24);
			pContanerUi->SetName(m_menuType.c_str());
			pContanerUi->SetUserData(t_strContent.c_str());

			pUiList->Add(pContanerUi);
        }

        int iHeight = 0;
        if (m_contentList.size() > 0)
        {
            iHeight = m_contentList.size() * 24 + 16; //
        }
        
        ResizeClient(110, iHeight);

        int iCount = pUiList->GetCount();
		CDuiRect rcWnd;
		GetWindowRect(m_hWnd, &rcWnd);
       
        //尝试修改
        CLabelUI* pLabelItem = static_cast<CLabelUI*>(m_pm.FindControl(_T("open_label")));
        pLabelItem->SetText("World");

        
        m_pm.AddNotifier(this);
        m_pm.SetRoundCorner(3, 3);

        AdjustPostion();
        return 0;
    }

这里面循环添加菜单的item。然后手动设置了菜单总的大小。

就这样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值