2010-10-11 3 views
4

В моем основном фрейме есть элемент CMFCMenuBar, который содержит меню текущего типа документа. Я хотел бы добавить/удалить подменю динамически. Например, если пользователь хочет отобразить панель карты, я хочу добавить подменю карты рядом с меню «Файл».Можно ли манипулировать меню моего CMFCMenuBar CMDIFrameWndEx?

И наоборот, если панель карты закрыта, я также хочу удалить пункты меню карты.

Одна вещь, которая работает, но которая мне не нравится, - это просто отключить пункты меню в обработчиках ON_UPDATE_COMMAND_UI.
Рамка имеет метод, называемый GetMenuBar(), но тот возвращает мне const CMFCMenuBar *, поэтому я не могу изменить его снаружи. Я добавил поглотитель так что я получаю неконстантную ссылку в строке меню, но это не сработало:

CMenu menu; 
VERIFY(menu.LoadMenu(IDR_MAP)); 
CMFCMenuBar & menuBar = pFrm->GetNonConstMenuBar(); // Custom getter 
menuBar.InsertButton(CMFCToolBarMenuButton(0, menu, -1)); 
menuBar.AdjustLayout(); 
menuBar.AdjustSizeImmediate(); 

Приведенный выше код является адаптация void CMyMenuBar::AddSubMenu() в DynamicMenu образце. У меня есть ощущение, что этот образец сломан, так как я не мог узнать, выполняется ли или когда этот конкретный код выполняется. В образце код выполняется только при сбросе строки меню или когда в реестр еще не сохранено состояние.

Это просто невозможно или я делаю что-то неправильно?

Будет ли хорошая альтернатива добавлению/удалению подменю?

ответ

4

Один из способов сделать это - обработать сообщение WM_INITMENUPOPUP. Перед отображением меню OnInitMenuPopup вызывается с указателем на меню.

Обратите внимание, что это вызвано каждый раз, когда меню собирается всплывать, и любые сделанные вами изменения теряются между вызовами (вы должны добавлять свои пункты меню каждый раз, когда вызывается OnInitMenuPopup).

Уловка для использования этого заключается в определении способа вызова вызываемого меню. Один из способов - сравнить идентификатор элемента меню с известным элементом. Например, если первый элемент в меню - ID_FILE_OPEN, вы можете его найти. Если найдено, вы можете предположить, что ваше меню «Файл» - это тот, который открывается, и вы можете добавить свое настраиваемое подменю.

Возможно, вы также можете использовать элемент dwMenuData структуры MENUINFO, хотя, похоже, у меня возникают проблемы с этим из-за способа, которым CMFCMenuBar создает меню.

+0

Если вы правильно поняли, это позволит мне удалить все подпункты «Карта», но не «Карта». Панель меню будет выглядеть так: «Файл | Карта | Правка | ...» с «Картой», не имеющей подпунктов; правильно? Я думаю, что это больше похоже на ошибку, чем на функцию ... – foraidt

+0

Вы можете обработать это сообщение в меню «Файл» и использовать его для удаления подменю «Карта» (при необходимости). Но, скорее всего, у вас не будет * предварительно заданного подменю «Карта»; вы просто вставляете его в меню «Файл», когда это необходимо. Каждый раз, когда вы получаете 'OnInitMenuPopup', решаете, нужно ли вам подменю« Карта »и добавьте его, если это необходимо. Поскольку меню всегда возвращается к исходной версии каждый раз, вам никогда не нужно беспокоиться об удалении чего-либо. Вам нужно только * добавить * элементы, которые подходят для контекста. – Nate

+1

Использование OnInitMenuPopup() (обработчик msg. Для WM_INITMENUPOPUP) - это классный и лучший способ настройки меню. Главное преимущество заключается в том, что любая настройка «живет» только в текущем вызове, в любом последующем не будет настройки, если вы не будете обрабатывать ее снова. – 23W

Смежные вопросы