cbuchart
cbuchart

Reputation: 11575

How to programmatically show dropdown-menu of ribbon button?

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?
  }
}

Upvotes: 1

Views: 1056

Answers (2)

Robert Schultz
Robert Schultz

Reputation: 11

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());

Upvotes: 1

cbuchart
cbuchart

Reputation: 11575

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();
  }
}

Upvotes: 0

Related Questions