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

huangapple go评论97阅读模式
英文:

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, &amp;MainFrame::OnButtonClicked)
// ...

CMFCRibbonPanel *panel = /* initialization */
CMFCRibbonButton *button = new CMFCRibbonButton(ID_RIBBON_BUTTON, &quot;Caption&quot;);
panel-&gt;Add(button);

CMFCRibbonButton *item1 = new CMFCRibbonButton(ID_RIBBON_BUTTON, &quot;Item 1&quot;);
button-&gt;AddSubItem(item1);
CMFCRibbonButton *item2 = new CMFCRibbonButton(ID_RIBBON_BUTTON, &quot;Item 2&quot;);
button-&gt;AddSubItem(item2);

// ...
void MainFrame::OnButtonClicked()
{
  if (auto button = static_cast&lt;CMFCRibbonButton *&gt;(m_ribbons.wndRibbonBar.FindByID(ID_RIBBON_BUTTON))) {

    // button-&gt;OnClick({}); // &lt;- 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-&gt;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 &lt;afxribbonbutton.h&gt;

class CMyMFCRibbonButton : public CMFCRibbonButton {
public:
  using CMFCRibbonButton::CMFCRibbonButton;

  virtual void OnShowPopupMenu() override {
    CMFCRibbonButton::OnShowPopupMenu();
  }
};

// ...
ON_COMMAND(ID_RIBBON_BUTTON, &amp;MainFrame::OnButtonClicked)
// ...

CMFCRibbonPanel *panel = /* initialization */
CMyMFCRibbonButton *button = new CMyMFCRibbonButton(ID_RIBBON_BUTTON, &quot;Caption&quot;);
panel-&gt;Add(button);

CMFCRibbonButton *item1 = new CMFCRibbonButton(ID_RIBBON_BUTTON, &quot;Item 1&quot;);
button-&gt;AddSubItem(item1);
CMFCRibbonButton *item2 = new CMFCRibbonButton(ID_RIBBON_BUTTON, &quot;Item 2&quot;);
button-&gt;AddSubItem(item2);

// ...
void MainFrame::OnButtonClicked()
{
  if (auto button = static_cast&lt;CMyMFCRibbonButton*&gt;(m_ribbons.wndRibbonBar.FindByID(ID_RIBBON_BUTTON))) {
    button-&gt;OnShowPopupMenu();
  }
}

huangapple
  • 本文由 发表于 2020年1月3日 22:38:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/59580442.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定