Есть ли способ создания динамических пунктов меню в строке меню приложений MFC, созданных в стиле Visual Studio 2008 с меню, а не с лентой, у меня есть плагины, которые динамически добавляют их меню, как я могу добавить их в это меню ??? я вижу
//this is the menubar that i want to update
CMFCMenuBar m_wndMenuBar;
Сначала вы должны создать новое подменю. Его можно заполнить вручную или загрузить из ресурсов.
Затем создайте новую кнопку меню и присоедините к ней подменю. После этого обновите строку меню. Вот и все.
CMenu menu;
if(menu.LoadMenu(IDR_MY_MENU))
{
m_wndMenuBar.InsertButton(CMFCToolBarMenuButton(0, menu, -1, _T("&MyMenu")), -1);
m_wndMenuBar.AdjustLayout();
m_wndMenuBar.AdjustSizeImmediate();
}
Постскриптум menu
может быть местным, потому что CMFCToolBarMenuButton
конструктор скопировать содержимое из него.
Вы, вероятно, должны переопределить:
CMDIFrameWndEx::OnShowPopupMenu(CMFCPopupMenu* pMenuPopup)
и поместите элемент меню заполнителя в нужное вам динамическое меню, затем замените элемент меню заполнителя своим динамическим меню.
Для примера рассмотрим доставку исходного кода с помощью MFC:
afxframeimpl.cpp
BOOL CFrameImpl::OnShowPopupMenu(CMFCPopupMenu* pMenuPopup, CFrameWnd* /*pWndFrame*/)
Идеальный способ, вероятно, состоит в том, чтобы полностью построить CMenu
объекта, а затем назначьте его строке меню: это делает код практически совместимым с предыдущими версиями VisualStudio.
Объявите указатель на экземпляр CMenu
в CMainFrame
определение:
CMenu *m_pMainMenu
Установите это NULL
в CMainFrame
конструктор:
m_pMainMenu = NULL;
В CMainFrame::OnCreate()
создать экземпляр CMenu
при условии, что это было NULL
до:
SAFE_DELETE(m_pMainMenu);
m_pMainMenu = new CMenu;
Изменить это по желанию с:
pMainMenu->LoadMenu(),
pMainMenu->RemoveMenu(),
pMainMenu->AppendMenu(),
pMainMenu->InsertMenu(),
...
Наконец, свяжите панель инструментов меню с этим новым меню, используя CreateFromMenu:
m_wndMenuBar.CreateFromMenu(m_pMainMenu->m_hMenu);
Не забудь выпустить m_pMainMenu
в CMainFrame
деструктор, чтобы избежать утечек:
SAFE_DELETE(m_pMainMenu)
Примечание: это очень удобный и безопасный макрос:
#define SAFE_DELETE(a) { if (a) { delete(a); a=NULL; } }
Ты можешь использовать UPDATE_COMMAND_UI
в окне просмотра свойств.
Допустим, вы поместили меню «Захват текста» с помощью «ID_TEXTCAPTURE», а затем хотите изменить меню с помощью «Остановки захвата».
-в карте сообщений
BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWndEx)
ON_WM_CREATE()
ON_UPDATE_COMMAND_UI(ID_TEXTCAPTURE, &CChildFrame::OnUpdateTextcapture)
END_MESSAGE_MAP()
-обработчик события
void CChildFrame::OnUpdateTextcapture(CCmdUI *pCmdUI)
{
if(pCmdUI->m_pMenu)
{
int pos;
CMenu* mmenu = pCmdUI->m_pMenu;
pos = FindMenuItem(mmenu, _T("Text Capture(&C)"));
if (pos > -1 && IsCapture == TRUE)
{
UINT id = mmenu->GetMenuItemID(pos);
//change menu text as 'Stop Capture'
mmenu->ModifyMenu(id, MF_BYCOMMAND, id, _T("Stop Capture(&S)"));
IsCapture = TRUE;
}
}
}CChildFrame::FindMenuItem(CMenu* Menu, LPCTSTR MenuString)
{
ASSERT(Menu);
ASSERT(::IsMenu(Menu->GetSafeHmenu()));
int count = Menu->GetMenuItemCount();
for (int i = 0; i < count; i++)
{
CString str;
if (Menu->GetMenuString(i, str, MF_BYPOSITION) && str.Compare(MenuString) == 0)
return i;
}
return -1;
}