Можно ли манипулировать меню CMFCMenuBar моего CMDIFrameWndEx? - PullRequest
4 голосов
/ 11 октября 2010

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

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

Одна вещь, которая работает, но которая мне не нравится, это просто отключение пунктов меню в обработчиках 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. У меня такое ощущение, что этот образец не работает, так как я не смог выяснить, выполняется ли или нет этот конкретный код. В этом примере код выполняется только при сбросе строки меню иликогда еще ни одно состояние не было сохранено в реестре.

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

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

1 Ответ

4 голосов
/ 12 октября 2010

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

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

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

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

...