英文:
How to programmatically show dropdown-menu of ribbon button?
问题
我有一个带有一组子项的缎带按钮。当用户点击按钮下面的小箭头时,这些项目会显示出来。我想在用户点击按钮本身时显示这样的下拉菜单。我该怎么做?
我的初始想法是在用户点击按钮时以编程方式显示菜单。我已经能够在工具栏上做到这一点(这里),但在缎带上使用类似的解决方案会创建无限递归:
// ...
ON_COMMAND(ID_RIBBON_BUTTON, &MainFrame::OnButtonClicked)
// ...
CMFCRibbonPanel *panel = /* 初始化 */
CMFCRibbonButton *button = new CMFCRibbonButton(ID_RIBBON_BUTTON, "标题");
panel->Add(button);
CMFCRibbonButton *item1 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "项目1");
button->AddSubItem(item1);
CMFCRibbonButton *item2 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "项目2");
button->AddSubItem(item2);
// ...
void MainFrame::OnButtonClicked()
{
if (auto button = static_cast<CMFCRibbonButton *>(m_ribbons.wndRibbonBar.FindByID(ID_RIBBON_BUTTON))) {
// button->OnClick({}); // <- 导致无限递归
// 在这里要做什么?
}
}
希望这对你有所帮助。
英文:
I have ribbon button with a set of sub-items added. Such items are displayed when the user clicks on the tiny arrow below the button. I'd like to display such dropdown-menu when the button itself is clicked. How can I do that?
My initial idea was to programmatically show the menu when the user clicks the button. I've been able to do the same on toolbars (here) but using a similar solution on ribbons creates an infinite recursion:
// ...
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?
}
}
答案1
得分: 1
If you create a blank pop-up submenu and attach it to the button, the button will work as you requested, while displaying the buttons previously added as SubItems.
CMenu map_menu;
map_menu.CreateMenu();
button->SetHMenu(map_menu.GetSafeHmenu());
英文:
If you create a blank pop-up submenu and attached to the button, the button will work as you requested, while displaying the buttons previously added as SubItems.
CMenu map_menu;
map_menu.CreateMenu();
button->SetHMenu(map_menu.GetSafeHmenu());
答案2
得分: 0
以下是翻译好的代码部分:
到目前为止,我找到的最简单方法是使用受保护方法 `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 = /* 初始化 */
CMyMFCRibbonButton *button = new CMyMFCRibbonButton(ID_RIBBON_BUTTON, "标题");
panel->Add(button);
CMFCRibbonButton *item1 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "项目 1");
button->AddSubItem(item1);
CMFCRibbonButton *item2 = new CMFCRibbonButton(ID_RIBBON_BUTTON, "项目 2");
button->AddSubItem(item2);
// ...
void MainFrame::OnButtonClicked()
{
if (auto button = static_cast<CMyMFCRibbonButton*>(m_ribbons.wndRibbonBar.FindByID(ID_RIBBON_BUTTON))) {
button->OnShowPopupMenu();
}
}
请注意,我已经将代码中的英文部分翻译成中文。
英文:
The easiest way I've found so far is to use the protected method CMFCRibbonButton::OnShowPopupMenu
. It implies deriving the CMFCRibbonButton
class and changing the visibility of the method:
#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();
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论