| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Visual C++/MFC/WTL > обработать CMenu у CView |
| Автор: 17dufa 10.8.2009, 12:32 | ||||
Нужно удалить пункт из вьюшного меню в зависимости от настроек. Как это делается уже нашел. Проблема в другом: никак не могу найти, в какой же обработчик вставить свой код для удаления. Пробовал: CView::OnCreate, CView::OnInitialUpdate, CView::OnUpdate, CView::OnActivate, WM_SETFOCUS и даже WM_TIMER (таймер запускал в OnCreate). Постоянно получаю Assert
Assert вылетает на первом же вызове FindMenuItem. Если не ошибаюсь срабатывает вот этот ASSERT(::IsMenu(m_hMenu)). Если не заморачиваться на FindMenuItem, а самому прописать индексы, то получаю этот же ассерт на строке
|
| Автор: Earnest 10.8.2009, 12:49 |
| А что ты понимаешь под "вьюшным меню"? Может, это меню динамически формируется? В зависимости от этого нужно поступать по разному. Но в общем случае самый удобный момент - это OnInitMenuPopup - т.е. непосредственно перед выпадением меню. Но получает это сообщение только собственник меню, а не кто попало. Т.е. если это меню SDI или MDI фрейма, то собственником является главное окно, а если контекстное меню, то то окно, которое указано в TrackPopupMenu. Как тут можно ошибаться? Либо этот срабатывает, либо не этот, одладчик должен показать. Если это оно, то стало быть не нашел ты меню, невалидно оно. |
| Автор: 17dufa 10.8.2009, 13:01 | ||||
| Earnest, точно ASSERT(::IsMenu(m_hMenu)) вьюшное меню - это меню, которое я вижу при открытии CView, ID которого указывается в CMultiDocTemplate::CMultiDocTemplate(...). Я не знаю кому оно принадлежит, но думал, что CView. с OnInitMenuPopup не вышло, обработчик просто не вызывается, видимо это только для popup, а это меню больше на MainMenu похоже. Вышло так:
это в классе, который указывается третьим аргументом в CMultiDocTemplate::CMultiDocTemplate():
|
| Автор: Earnest 11.8.2009, 06:23 |
| Действительно, это меню вовсе не вью принадлежит, а главному фрейму. У него и надо бы OnInitMenuPopup ловить. Но это не кошерно: фрейм имеет свой обработчик OnInitMenuPopup, где для каждого подменю и каждой команды рассылает апдейты. Вот их и надо обрабатывать, т.е. написать обработчик OnUpdate и поставить в карту - вот его можно и в карту вью, если так удобнее. Если не ошибаюсь, обработчик-апдейт попап меню вешается на идентификатор первой команды подменю. Отличить его от обработчика для собственно команды можно по члену CCmdUI:m_pSubMenu, который не нулевой. Там немного мутно, но не очень, хотя я конкретику подзабыла. Проще всего разобраться так: 1) найти обработчик фрейма OnInitMenuPopup и посмотреть как что рассылается 2) Найти обработчик mdi-фрейма, обновляющий меню Windows (где список открытых окон показывается) - как пример обновления подменю. Попробуй разобраться сам. А не сможешь, я поищу у себя куски кода с примерами. |