Как правильно программно выйти из приложения MFC? - PullRequest
17 голосов
/ 27 сентября 2011

Использование windows MFC C ++.У меня есть стороннее приложение, которое вызывает пользовательский метод в моем производном классе CWinApp.Этот метод вызывается после InitInstance ().Если в этом методе есть ошибка, такая, что исключение выдается и перехватывается в блоке try / catch, я хотел бы выйти из приложения из блока catch.Каков канонический и правильный способ выхода?

ОБНОВЛЕНИЕ:

Серж Я считаю правильным, что в InitInstance () возвращение false является правильным способом выхода из приложения,Однако теперь предположим, что я хочу выйти из обработчика OnInitDialog () производного класса CDialog, как это правильно сделать.

UPDATE 2

Для меня яобнаружил, что вызов PostMessage (WM_CLOSE) является лучшим способом из моего немодального класса, производного от CDialog.Все другие методы выхода, которые я пробовал, в некоторых обстоятельствах вызывали бы то или иное исключение.

Вот пример того, как я его использую:

BOOL SomeDialog::OnInitDialog()
{
    CDialog::OnInitDialog();

    ::OleInitialize(nullptr);

    try
    {
        // ...load settings file here
    }
    catch(...)
    {
        PostMessage(WM_CLOSE);
        return TRUE;
    }

    // return TRUE  unless you set the focus to a control
    return TRUE;
}

Ответы [ 3 ]

27 голосов
/ 27 сентября 2011

In InitInstance ()

Выход из приложения, пока вы находитесь в InitInstance(): просто верните FALSE из InitInstance().

В главном цикле сообщений

Это еще одна история, если вы уже находитесь в цикле сообщений: стандартный способ закрыть приложение - выйти из цикла сообщений:

PostQuitMessage(0), как следует из названия, отправляет сообщение WM_QUIT. Цикл сообщений реагирует, выходя из цикла и закрывая программу.

Но вы не должны просто делать это: вы должны закрыть открытые окна в вашем приложении. Предполагая, что у вас есть только ваше главное окно, вы должны уничтожить его, позвонив по номеру

m_pMainWindow->DestroyWindow();

MFC отреагирует на вас PostQuitMessage(), поэтому выйдите из основного цикла сообщений и закройте ваше приложение.

Еще лучше, вы должны опубликовать WM_CLOSE, чтобы ваше главное окно изящно закрылось. Например, он может решить сохранить текущий документ. Но будьте осторожны: стандартный обработчик OnClose() может предложить пользователю сохранить грязные документы. Пользователь может даже отменить действие закрытия, используя это приглашение (Сохранить документ? Да, Нет, Отмена).

Уничтожив главное окно, вы отправите ему сообщение WM_DESTROY. MFC реагирует, вызывая PostQuitMessage(0) для выхода из насоса сообщений. (На самом деле MFC выполняет вызов в OnNcDestroy(), поскольку WM_NCDESTROY, что является абсолютным последним сообщением, полученным окном)

Диалоговое приложение

Позвонить EndDialog(-1); // Или заменить -1 на IDCANCEL, что угодно

Этот вызов, как вы, наверное, знаете, закроет диалог.

Обратите внимание, что главное диалоговое окно диалогового приложения выполняется в InitInstance (). Закрытие диалогового окна просто завершит работу InitInstance(), который всегда возвращает FALSE в таких проектах.

9 голосов
/ 27 сентября 2011

Просто используйте:

PostQuitMessage(0);

Имейте в виду, что ваша программа не завершит работу сразу после этого вызова, окно / программа получит сообщение WM_QUIT, а затем ваша программа закроется.

2 голосов
/ 28 сентября 2011

Серж - ваш ответ, к сожалению, не лучший способ сделать это. PostQuitMessage (0) - это путь, и MFC разрушит окна для вас. Вам следует избегать прямого вызова m_pMainWindow-> DestroyWindow ().

...