我知道如何使用以下代码为按钮生成静态菜单项:
CBCGPRibbonCategory *pCategory = ...;
CBCGPRibbonPanel *pPanel = pCategory->AddPanel(_T("Panel Name"), hPanelIcon);
HMENU hMenu = CreateMenu();
AppendMenu(hMenu, MF_STRING, ID_ITEM_1, _T("Item 1"));
AppendMenu(hMenu, MF_STRING, ID_ITEM_2, _T("Item 2"));
CBCGPRibbonButton * pButton = new CBCGPRibbonButton(ID_BUTTON_WITH_MENU, _T(""))
pButton->SetMenu(hMenu, TRUE); // for dynamic
pPanel->Add(pButton);
但如果我想要菜单是动态的,我该怎么办?我尝试通过覆盖HMENU
并更改我附加到该按钮的OnShowPopupMenu()
来修改原始HMENU
,但这不起作用。
我可以通过创建菜单并使用TrackPopupMenu()
功能强制按钮下的菜单,但样式错误。 (看起来是灰色而不是白色和其他一些差异)。
修改
为了解决这个问题,我做了以下几点:
class CDynamicMenuButton : public CBCGPRibbonButton
{
public:
CDynamicMenuButton(
UINT nID,
LPCTSTR lpszText,
int nSmallImageIndex = -1,
int nLargeImageIndex = -1,
BOOL bAlwaysShowDescription = FALSE)
: CBCGPRibbonButton(nID, lpszText, nSmallImageIndex, nLargeImageIndex, bAlwaysShowDescription)
{
SetMenu(CreatePopupMenu());
}
void OnShowPopupMenu() override
{
// legacy code to generate menu
CMenu newMenu;
populateMenu(&newMenu);
// sets the new menu
SetMenu(newMenu);
// Pops up the new menu
CBCGPRibbonButton::OnShowPopupMenu();
}
};
将此按钮添加到面板将生成我想要的动态菜单。
答案 0 :(得分:1)
功能区似乎只使用hMenu
作为模板来构建它自己的结构,因此修改hMenu
是徒劳的。使用现有功能区菜单按钮更好地工作:
pBtn->RemoveAllSubItems(); // add a dummy hMenu when creating the menu button in CMainFrame!
std::auto_ptr<CMFCRibbonButtonEx> apBtn3(new CMFCRibbonButtonEx(ID_DYNAMIC_MENU_ITEM_3, "Item 3", -1, -1, true));
pBtn->AddSubItem(apBtn.release());
std::auto_ptr<CMFCRibbonButtonEx> apBtn4(new CMFCRibbonButtonEx(ID_DYNAMIC_MENU_ITEM_4, "Item 4", -1, -1, true));
pBtn->AddSubItem(apBtn.release());
但请务必在代码中的正确位置更新菜单。改变CMyView::OnUpdate()
中的菜单被证明不是一个好主意(see here)。如果您在打开mdi文档时需要修改菜单,请考虑OnInitialUpdate()
。我还没有尝试OnCmdMsg()
。
也许它足以通过CMFCRibbonBar::FindByID()
获取pBtn,但也许通过CMFCRibbonBar::GetElementsByID
迭代并更改您找到的每个菜单按钮(即还要修改快速访问工具栏?)是正确的。我发现文档对此并不十分具体,但在我的代码中通过'.FindByID'进行修改似乎就足够了。
如果您对动态功能区菜单有任何进一步的启示,请给我留言。