Главный диалог уничтожается до возврата обработчика командного сообщения

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

BOOL OnInitDialog()
{
    init data...
}

void OnDestroy()
{
    destroy data...
}

void OnSomeButton()
{
    CFileDialog dlg;
    ...
    dlg.DoModal(m_hWnd));
    access data...
    ...
}

void OnMenuExit()
{
    DestroyWindow();
}

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

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


person toki    schedule 13.08.2012    source источник
comment
Почему рассматриваемые данные недействительны? Если приложение все равно завершается, нет необходимости (например) освобождать выделенную память. Реструктуризация, чтобы рассматриваемая память не освобождалась при выходе, может решить вашу проблему.   -  person Harry Johnston    schedule 13.08.2012
comment
Даже если я не освобождаю память, некоторое содержимое данных состояния становится недействительным, так как окно было уничтожено, что приводит к непредсказуемому поведению приложения...   -  person toki    schedule 14.08.2012


Ответы (2)


Ага. Когда вы выходите из меню в трее, вы можете отправить WM_CLOSE или подобное сообщение в свой модальный диалог, который заставит его закрыться. Даже если ваше главное окно будет уничтожено до того, как OnSomeButton вернется, все будет в порядке, если оставшаяся часть этой функции не будет обращаться к каким-либо внутренним элементам класса (переменным-членам и т. д.). Вы можете убедиться в этом, если оконный процесс вашего модального диалога вернет код «отмены» или что-то еще, когда он будет закрыт таким образом.

person paddy    schedule 13.08.2012
comment
То есть вы имеете в виду, что добавьте код прерывания в модальное диалоговое окно, а когда он вернется, просто проверьте этот код, а затем прекратите дальнейшую обработку? - person toki; 14.08.2012
comment
Да, потому что область кода для вашего класса находится в одном месте — вы можете завершить выполнение этого кода даже после того, как ваш объект класса исчезнет, ​​если вы не получите доступ к объекту. Другой способ, которым вы могли бы пойти, - установить значение в самом классе модального диалогового окна и протестировать его. Но для этого вы должны разместить объект в куче, а не создавать его в стеке. В любом случае главное окно должно поддерживать некоторую информацию о существовании модального диалога. Либо сохраните HWND, либо сохраните указатель CDialog. И следите за разногласиями в нитях. - person paddy; 14.08.2012

Вам нужно добавить свой собственный код уровня приложения. Системной поддержки для этого вопроса нет, прежде всего потому, что может быть так много особенностей, что общий подход невозможен.

person Kirill Kobelev    schedule 13.08.2012