Системные меню исчезают, когда я увеличиваю дочернее окно - PullRequest
0 голосов
/ 07 февраля 2019

Кто-нибудь сталкивался с этой проблемой?

Я использую MFC в приложении MDI.Я переключаюсь между меню, используя SetMenu (), но побочный эффект системных меню (кнопки «Развернуть», «Свернуть», «Закрыть») исчезает, когда я максимизирую дочерние окна.

CMenu* pMenu = GetMenu();
if (pMenu == NULL) return;
pMenu->Detach();

// Reset application menu
CMenu newMenu;
newMenu.LoadMenu(menuID);
SetMenu(&newMenu);

Если я не вызываю SetMenu (), вопроса не бывает.

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

Я бы порекомендовал что-то другое: просто используйте функциональность управления меню, как первоначально предполагалось MFC.Для типичного приложения MDI MFC вам не нужно ничего делать с меню (я имею в виду эти вызовы SetMenu()).Только определите их, и MFC сделает все остальное за вас.

В частности, приложение MDI, созданное мастером, содержит следующие меню:

  • IDR_MAINFRAME, которые будут отображатьсякогда не существует дочернего окна MDI (открытый документ).Обычно содержит подменю Файл , Просмотр и Справка .
  • IDR_DocType, по одному для каждого типа документа, который вы определили.Это отображается, когда дочернее окно MDI, отображающее документ этого типа, является активным.Обычно содержит Файл , Редактировать , Вид, Окно и Справка подменю.

Обратите внимание, что:

  • Вам нужно только определить / отредактировать эти меню, например, добавить больше команд или еще больше подменю.Вам не нужно переключать меню, фреймворк сделает это за вас.
  • Фреймворк НЕ объединит подменю или пункты меню, вместо этого он просто выберет IDR_MAINFRAME или один из IDR_DocType,в зависимости от текущего дочернего окна MDI.
  • Следовательно, некоторые подменю или элементы могут быть дубликатами (хотя и не обязательно точными копиями), а некоторые - нет.Например, подменю Вид для IDR_MAINFRAME обычно содержит два элемента меню: Панель инструментов (или Панели инструментов ) и Строка состояния (переключениеотображение панели инструментов и строки состояния), в то время как специфичные для типа документа, как правило, содержат вышеперечисленное, а также некоторые дополнительные, определяющие способ отображения документа;например, если документ представляет собой изображение, вы обычно добавляете несколько вариантов отображения, например 1: 1 , По ширине , По высоте и НаилучшееПодогнать (в настройках переключателя), показанных над панелями инструментов и в строке состояния , разделенных элементом меню-разделителем.

Я разработал много таких приложений, и никогда не использовал SetMenu().Я бы посоветовал вам сначала восстановить меню IDR_MAINFRAME и IDR_DocType до их первоначального состояния, а затем ввести любые дополнительные / пользовательские.Если вы уничтожили или значительно изменили меню, изначально созданные мастером, вы можете создать новый проект / решение MFC с теми же настройками, что и у вас, и скопировать и вставить меню в файл ресурсов.

0 голосов
/ 07 февраля 2019
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);
    }
}
...