Системные меню исчезают, когда я увеличиваю дочернее окно
Кто-нибудь сталкивался с этой проблемой?
Я использую MFC в приложении MDI. Я переключаюсь между меню с помощью SetMenu(), но побочный эффект системных меню (кнопки "Развернуть", "Свернуть", "Закрыть") исчезает при развертывании дочерних окон.
CMenu* pMenu = GetMenu();
if (pMenu == NULL) return;
pMenu->Detach();
// Reset application menu
CMenu newMenu;
newMenu.LoadMenu(menuID);
SetMenu(&newMenu);
Если я не вызываю SetMenu(), проблема не возникает.
2 ответа
CMenu newMenu; newMenu.LoadMenu(menuID); SetMenu(&newMenu);
newMenu
это временный объект. Он будет уничтожен, как только выйдет функция. Результатом является неопределенное поведение.
CMenu* pMenu = GetMenu(); if (pMenu == NULL) return; pMenu->Detach();
Я не уверен, что этот код будет выполнять. Обратите внимание, что CWnd::SetMenu
заменит старое меню. Это не уничтожит старый дескриптор меню, но MFC будет обрабатывать очистку в конце (Detach
не разрушит ручку, если это была цель)
Попробуйте этот код вместо этого:
Объявите объекты меню как члены класса:
class CMainFrame : public CMDIFrameWnd
{
CMenu m_menu1, m_menu2;
...
};
Загрузите меню один раз:
CMainFrame::CMainFrame()
{
m_menu1.LoadMenu(IDR_MENU1);
m_menu2.LoadMenu(IDR_MENU2);
...
}
Изменить меню:
void CMainFrame::OnChangeMenu()
{
if(want_menu1)
{
SetMenu(&m_menu1);
}
else if (want_menu2)
{
SetMenu(&m_menu2);
}
}
Я бы порекомендовал что-то другое: просто используйте функциональность управления меню, как первоначально предполагалось MFC. Для типичного приложения MDI MFC вам не нужно ничего делать с меню (и я имею в виду эти вызовы SetMenu()
). Только определите их, и MFC сделает все остальное за вас.
В частности, приложение MDI, созданное мастером, содержит следующие меню:
IDR_MAINFRAME
, который будет отображаться при отсутствии дочернего окна MDI (открытый документ). Обычно содержит подменю File, View и Help.IDR_DocType
по одному для каждого типа документа, который вы определили. Это отображается, когда дочернее окно MDI, отображающее документ этого типа, является активным. Обычно содержит подменю File, Edit, View, Window и Help.
Обратите внимание, что:
- Вам нужно только определить / отредактировать эти меню, например, добавить больше команд или даже больше подменю. Вам не нужно переключать меню, фреймворк сделает это за вас.
- Фреймворк НЕ объединит подменю или пункты меню, вместо этого он просто выберет
IDR_MAINFRAME
или один изIDR_DocType
в зависимости от активного дочернего окна MDI. - Следовательно, некоторые из подменю или пунктов могут быть дубликатами (хотя и не обязательно точными копиями), а некоторые нет. Например, подменю Просмотр для
IDR_MAINFRAME
обычно содержит два элемента меню, Панель инструментов (или Панели инструментов) и Строка состояния (переключение отображения панели инструментов и строки состояния), в то время как специфичные для doctype, как правило, содержат вышеперечисленное, а также некоторые дополнительные, определяющие способ отображения документа; Например, если документ представляет собой изображение, вы обычно добавляете некоторые варианты отображения, такие как 1: 1, Подогнать по ширине, Подогнать по высоте и Подогнать по размеру (в настройках переключателя), показанные над панелью инструментов и строкой состояния, разделенные разделитель меню-пункт.
Я разработал много таких приложений, и мне никогда не приходилось использовать SetMenu()
, Я хотел бы предложить вам сначала восстановить IDR_MAINFRAME
а также IDR_DocType
меню в исходное состояние, а затем вставьте любые дополнительные / пользовательские. Если вы уничтожили или значительно изменили меню, изначально созданные мастером, вы можете создать новый проект / решение MFC с теми же настройками, что и у вас, и скопировать и вставить меню в файл ресурсов.