MFC: кнопка X на одном окне также закрывает второе окно

Мое приложение имеет несколько окон, каждое из CDialogкласс.

Нажатие кнопки «X» в верхнем правом углу оконной рамы закрывает окно и вызывает PostNcDestroy,

Для одного из четырех окон, однако, он также вызывает другое окно PostNcDestroy() и делает это окно невидимым.

Есть идеи?

-1

Решение

Вы не дали много информации. Мы можем только догадываться … Поскольку вы утверждаете, что все ваши окна являются диалогами, я предполагаю, что внутри метода InitInstance () вашего приложения у вас есть вызов DoModal () основного производного класса CDialog. После закрытия главного диалога он выходит из цикла DoModal (), а затем выходит из InitInstance () и закрывает приложение. Завершение работы приложения приводит к разрушению других диалогов, в результате чего отправляется WM_NCDESTROY, а затем вызывается PostNcDestroy ().

0

Другие решения

КРАТКИЙ ОТВЕТ: поведение было вызвано настройкой m_pMainWnd ПОСЛЕ создания всех четырех окон. Если он установлен до создания второго окна, проблема выше не возникает.

ДЛИННЫЙ ОТВЕТ: проблема в том, что окна НЕ ИМЕЮТ друг на друга. Каждый из них — РЕБЕНОК ПРЕДЫДУЩЕГО.

Родителем окна 1 является значение «0» (рабочий стол).
Родителем окна 2 является окно 1.
Родителем окна 3 является окно 2.
Родителем окна 4 является окно 3.

В моем первоначальном отчете о проблеме отмечалось, что окно 4 загадочно закрывается, когда окно 3 закрывается Так что теперь причина, почему это очевидно. (Закрытие окна также закрывает все его дочерние элементы.) Впоследствии я обнаружил, что закрытие окна 2 также приводит к закрытию 3 и 4, что также учитывается. (3 является дочерним 2, поэтому закрывается, и это делает 4, который является дочерним 3, закрыт.) Наконец, закрытие окна 1 проверяет несохраненную работу, и если ни один не вызывает exit(), Я предполагаю, что если бы это окно не выходило, другие окна тоже были бы закрыты.

CDialog::Create() имеет параметр по умолчанию NULL за второй аргумент pParentWnd, а также NULL означает «родитель» установлен в главном окне приложения. Шагая в CDialog::Create(), который вызывает CDialog::CreateIndirect(), который вызывает AfxGetMainWnd() Я в конечном итоге CWinThread::GetMainWnd(), Этот метод, если m_pMainWnd еще не установлено, просто возвращается CWnd::GetActiveWindow() который является самым недавно созданным окном.

Итак: источник проблемы в том, что мое приложение создало четыре окна, ТО m_pMainWnd, Вот почему окно 3 было дочерним по отношению к окну 2 (активное окно в этой точке) 4 является дочерним по отношению к 3, и так далее.

Установив m_pMainWnd после создания окна 1 окна 2, 3 и 4 являются дочерними элементами 1. Таким образом, это избавляет от проблемы «закрытие окна 3 делает окно 4 слишком закрытым».

Это все еще не совсем то, что мне было нужно, так как оно предотвращает появление окна 1 перед остальными тремя окнами. Это выходит за рамки моего первоначального вопроса, но здесь есть исправление. Изменение Create() позвонить, чтобы пройти GetDesktopWindow() очевидно, что приложение работает так, как я хотел, с четырьмя окнами, которые могут закрываться независимо друг от друга и свободно настраиваться в стеке окон:

  Create( resource_ID, GetDesktopWindow() );

Я удивлен, что это не известная проблема, так как документация (по состоянию на VS2008Pro) для НИХ из этих функций фактически объясняет, что они на самом деле делают, когда m_pMainWnd не установлен, и перемещение этого простого назначения m_pMainWnd до конца создания окна, вероятно, испортит ЛЮБОЕ приложение, которое создало более двух окон …

0

По вопросам рекламы [email protected]