如何以编程方式显示功能区按钮的下拉菜单?

How to programmatically show dropdown-menu of ribbon button?

本文关键字:按钮 下拉菜单 功能区 显示 编程 方式      更新时间:2023-10-16

我有一个功能区按钮,添加了一组子项目。当用户单击按钮下方的小箭头时,将显示此类项目。我想在单击按钮本身时显示这样的下拉菜单。我该怎么做?

我最初的想法是在用户单击按钮时以编程方式显示菜单。我已经能够在工具栏上做同样的事情(这里(,但是在功能区上使用类似的解决方案会产生无限递归:

// ...
ON_COMMAND(ID_RIBBON_BUTTON, &MainFrame::OnButtonClicked)
// ...
CMFCRibbonPanel *panel = /* initialization */
CMFCRibbonButton *button = new CMFCRibbonButton(ID_RIBBON_BUTTON, "Caption");
panel->Add(button);
CMFCRibbonButton *item1 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "Item 1");
button->AddSubItem(item1);
CMFCRibbonButton *item2 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "Item 2");
button->AddSubItem(item2);
// ...
void MainFrame::OnButtonClicked()
{
if (auto button = static_cast<CMFCRibbonButton *>(m_ribbons.wndRibbonBar.FindByID(ID_RIBBON_BUTTON))) {
// button->OnClick({}); // <- causes infinite recursion
// What to do here?
}
}

如果创建一个空白的弹出子菜单并附加到该按钮,则该按钮将按您的要求工作,同时显示之前添加为子项的按钮。

CMenu map_menu;
map_menu.CreateMenu();
button->SetHMenu(map_menu.GetSafeHmenu());

到目前为止,我发现的最简单方法是使用受保护的方法CMFCRibbonButton::OnShowPopupMenu。这意味着派生CMFCRibbonButton类并更改方法的可见性:

#include <afxribbonbutton.h>
class CMyMFCRibbonButton : public CMFCRibbonButton {
public:
using CMFCRibbonButton::CMFCRibbonButton;
virtual void OnShowPopupMenu() override {
CMFCRibbonButton::OnShowPopupMenu();
}
};
// ...
ON_COMMAND(ID_RIBBON_BUTTON, &MainFrame::OnButtonClicked)
// ...
CMFCRibbonPanel *panel = /* initialization */
CMyMFCRibbonButton *button = new CMyMFCRibbonButton(ID_RIBBON_BUTTON, "Caption");
panel->Add(button);
CMFCRibbonButton *item1 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "Item 1");
button->AddSubItem(item1);
CMFCRibbonButton *item2 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "Item 2");
button->AddSubItem(item2);
// ...
void MainFrame::OnButtonClicked()
{
if (auto button = static_cast<CMyMFCRibbonButton*>(m_ribbons.wndRibbonBar.FindByID(ID_RIBBON_BUTTON))) {
button->OnShowPopupMenu();
}
}