Что _реально_ происходит с диалогом при нажатии Enter/Esc?
От: programmater  
Дата: 06.10.10 10:46
Оценка: :)
Здравствуйте коллеги.
Наверняка многие из вас сталкивались с ситуацией, когда при нажатии на ESC в дочернем диалоге он исчезал. Т.е: есть родительский диалог. На нем создается один или несколько дочерних диалогов. Потом, когда фокус находится на одном из контролов одного из дочерних диалогов, нажать ESC, то дочерний диалог, на чьем контроле находился фокус, исчезнет. Вещь эта давно известная, и многие наверняка как-то эту проблему обходили. Я, например, всегда решал ее следующей строчкой в классе дочернего диалога:
void OnCancel() {}

При этом я был абсолютно уверен, что дочерний диалог в этот момент уничтожается, и что попытка сделать что-то с запомненным HWND этого диалога ни к чему не приведет (ведь этого WINAPI-объекта уже нет!). А вот не тут-то было. Сейчас, возясь с самодельным PropertySheet-ом (только не спрашивайте, зачем мне это надо ), обнаружил, что странички при нажатии на ESC вовсе не помирают (хотя с экрана успешно пропадают), и что при повторном переключении на эту страницу вызов
::ShowWindow(m_Pages[CurSelIndex], SW_SHOW);   // m_Pages хранит HWND!

успешно срабатывает и страничка появляется как ни в чем не бывало. Не поверил глазам, специально написал обработчик WM_DESTROY для странички (хотя на самом деле этот обработчик мне не нужен, но было уж больно интересно). Нажал на ESC. Страничка пропала. WM_DESTROY не было! Так куда же девается диалог?
Вот и возник вопрос: что же на самом деле происходит с диалогом, когда юзер нажимает на Enter/ESC?
Re: Что _реально_ происходит с диалогом при нажатии Enter/Es
От: kero Россия  
Дата: 06.10.10 11:11
Оценка:
Здравствуйте, programmater, Вы писали:

P>Вот и возник вопрос: что же на самом деле происходит с диалогом, когда юзер нажимает на Enter/ESC?


Послушайте, можно наворотить кодов, когда и не такое получишь. Диалоги-то чем создавали (*Box? Create*?) и чем в DlgProc закрывали? Т.е. все тот же вечный вопрос: а код ваш иде?
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[2]: Что _реально_ происходит с диалогом при нажатии Enter
От: programmater  
Дата: 06.10.10 13:16
Оценка:
Здравствуйте, kero, Вы писали:
K>Послушайте, можно наворотить кодов, когда и не такое получишь. Диалоги-то чем создавали (*Box? Create*?) и чем в DlgProc закрывали? Т.е. все тот же вечный вопрос: а код ваш иде?
В своем коде я ничем диалог не закрывал, в том-то все и дело. Обычный MFC CDialog (кстати правда, может вопрос надо было в форуме по MFC задавать... ). Насколько я знаю закрытие модального диалога по Enter/Esc — это дефолтное поведение класса CDialog и для этого ничего переопределять или писать не надо. Наоборот, надо делать какие-то телодвижения, чтобы это предотвратить. Пропадание дочернего диалога — из той же оперы.
Re[3]: Что _реально_ происходит с диалогом при нажатии Enter
От: kero Россия  
Дата: 06.10.10 13:47
Оценка:
Здравствуйте, programmater, Вы писали:

P>В своем коде я ничем диалог не закрывал, в том-то все и дело. Обычный MFC CDialog (кстати правда, может вопрос надо было в форуме по MFC задавать... ). Насколько я знаю закрытие модального диалога по Enter/Esc — это дефолтное поведение класса CDialog и для этого ничего переопределять или писать не надо. Наоборот, надо делать какие-то телодвижения, чтобы это предотвратить. Пропадание дочернего диалога — из той же оперы.


Минуточку. В MFC, говорите? Так, возможно, для дочернего — не пропадание, а скрытие (hide), как в дельфи? проверить бы.
С другой стороны — если созданный через CreateDialog (кстати, в MFC ведь модальные сделаны через не-модальные?) "закрывать" путем EndDialog, то как раз и получится hide вместо close... Может, выложите минимальную демку с вашей ситуацией?
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re: Что _реально_ происходит с диалогом при нажатии Enter/Es
От: rus blood Россия  
Дата: 06.10.10 13:57
Оценка:
Здравствуйте, programmater, Вы писали:

P>Вот и возник вопрос: что же на самом деле происходит с диалогом, когда юзер нажимает на Enter/ESC?


Функция IsDialogMessage шлет в диалоговую процедуру сообщение WM_COMMAND с параметром wParam = IDOK для Enter и IDCANCEL для Esc.

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

В MFC для IDOK и IDCANCEL есть виртуальные обработчики OnOK и OnCancel.
Их реализация в классе CDialog вызывает EndDialog с соответствующим кодом.
Класс CPropertyPage переопределяет эти функции своими пустыми версиями.
Имею скафандр — готов путешествовать!
Re[4]: Что _реально_ происходит с диалогом при нажатии Enter
От: programmater  
Дата: 06.10.10 14:32
Оценка:
Здравствуйте, kero, Вы писали:
K>Минуточку. В MFC, говорите?
Да, в MFC [как же я ненавижу эту библиотеку! ]
K> Так, возможно, для дочернего — не пропадание, а скрытие (hide), как в дельфи? проверить бы.
Возможно, собственно этот вопрос я и задаю — что же происходит.
K> (кстати, в MFC ведь модальные сделаны через не-модальные?)
Да, MFC никогда не вызывает функцию DialogBox. Даже модальные диалоги там реализованы через CreateDialogIndirect и собственным циклом выборки/обработки сообщений (видимо чтобы приклеить туда все Pretranslate-ы)
K>С другой стороны — если созданный через CreateDialog "закрывать" путем EndDialog, то как раз и получится hide вместо close... Может, выложите минимальную демку с вашей ситуацией?
Подробнее плиз. Т.е. если я создам диалог через Create, потом где-то внутри диалоговой процедуры вызову EndDialog, то диалог не будет автоматически уничтожен? Вот этого не знал... Думал что вызов EndDialog приводит к уничтожению диалога (не сразу, а после выхода из диалоговой процедуры). Я ошибаюсь?
Демку пока сделать не могу — код слишком перемешан с рабочим проектом.
Re[2]: Что _реально_ происходит с диалогом при нажатии Enter
От: programmater  
Дата: 06.10.10 14:42
Оценка:
Здравствуйте, rus blood, Вы писали:
RB>Класс CPropertyPage переопределяет эти функции своими пустыми версиями.
Оставим в покое CPropertyPage. Они предназначены для работы в составе реального CPropertySheet-а. Поскольку Sheet у меня самопальный, то и Page-ы тоже будут самопальные, на базе CDialog-а.

P>>Вот и возник вопрос: что же на самом деле происходит с диалогом, когда юзер нажимает на Enter/ESC?


RB>Функция IsDialogMessage шлет в диалоговую процедуру сообщение WM_COMMAND с параметром wParam = IDOK для Enter и IDCANCEL для Esc.


RB>Для модальных диалогов функция DialogBox вызывает IsDialogMessage в своем цикле сообщений.

RB>Для немодальных диалогов функция IsDialogMessage может быть встроена в цикл сообщений потока, а может и не быть.
RB>В последнем случае, ничего не будет происходить.

RB>В MFC для IDOK и IDCANCEL есть виртуальные обработчики OnOK и OnCancel.

RB>Их реализация в классе CDialog вызывает EndDialog с соответствующим кодом.
Все вышесказанное отлично согласуется с тем, что я знаю про диалоги и про MFC. Но разве вызов EndDialog не убивает диалог, а только скрывает его?
Re[5]: Что _реально_ происходит с диалогом при нажатии Enter
От: kero Россия  
Дата: 06.10.10 14:59
Оценка:
Здравствуйте, programmater, Вы писали:

K>>С другой стороны — если созданный через CreateDialog "закрывать" путем EndDialog, то как раз и получится hide вместо close... Может, выложите минимальную демку с вашей ситуацией?

P>Подробнее плиз. Т.е. если я создам диалог через Create, потом где-то внутри диалоговой процедуры вызову EndDialog, то диалог не будет автоматически уничтожен? Вот этого не знал... Думал что вызов EndDialog приводит к уничтожению диалога (не сразу, а после выхода из диалоговой процедуры). Я ошибаюсь?

Когда-то запостил в другой форум Проект Комментария к "Win32 API Tutorial" by Iczelion, там в самом начале (tut11.1) как раз об этом.
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[3]: Что _реально_ происходит с диалогом при нажатии Enter
От: ononim  
Дата: 06.10.10 15:17
Оценка: 3 (1)
RB>>В MFC для IDOK и IDCANCEL есть виртуальные обработчики OnOK и OnCancel.
RB>>Их реализация в классе CDialog вызывает EndDialog с соответствующим кодом.
P>Все вышесказанное отлично согласуется с тем, что я знаю про диалоги и про MFC. Но разве вызов EndDialog не убивает диалог, а только скрывает его?
А вам ктото когда то обещал что убивает? Убивание происходит когда происходит выход из DialogBox. А все, что делае EndDialog это просто выставляет флажок гдето у себя там что диалог "завершен", прячет его окно и затем постит сама себе WM_NULL дабы вызвать прокрутку цикла выборки сообщений внутри DialogBox, чтобы она увидела этот флажок и вышла, разрушив окно.

А если бы вместо того чтобы ахать и ох..ть почитали бы мсдн дальше первой страницы, то увидели бы следующее:

EndDialog does not destroy the dialog box immediately. Instead, it sets a flag and allows the dialog box procedure to return control to the system. The system checks the flag before attempting to retrieve the next message from the application queue. If the flag is set, the system ends the message loop, destroys the dialog box, and uses the value in nResult as the return value from the function that created the dialog box.

Как много веселых ребят, и все делают велосипед...
Re[3]: Что _реально_ происходит с диалогом при нажатии Enter
От: rus blood Россия  
Дата: 06.10.10 15:19
Оценка: 2 (1)
Здравствуйте, programmater, Вы писали:

P>Но разве вызов EndDialog не убивает диалог, а только скрывает его?


Нет, не убивает.

EndDialog выставляет флаг, который заставляет поток выйти из цикла сообщений модального диалога.
Далее код функции DialogBox убивает диалог, разблокирует родителя и т.п.
Было бы странно окну убивать себя прямо из обработчика своего же сообщения.
Из других место EndDialog вызывать нельзя.
Имею скафандр — готов путешествовать!
Re[4]: Что _реально_ происходит с диалогом при нажатии Enter
От: kero Россия  
Дата: 06.10.10 15:23
Оценка:
Здравствуйте, ononim, Вы писали:

O>А вам ктото когда то обещал что убивает? Убивание происходит когда происходит выход из DialogBox. [...]


Все так, только выше речь шла о CreateDialog
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[5]: Что _реально_ происходит с диалогом при нажатии Enter
От: ononim  
Дата: 06.10.10 15:25
Оценка:
O>>А вам ктото когда то обещал что убивает? Убивание происходит когда происходит выход из DialogBox. [...]
K>Все так, только выше речь шла о CreateDialog
Отлично. Читаем MSDN про CreateDialog:

After CreateDialog returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function

Как много веселых ребят, и все делают велосипед...
Re[6]: Что _реально_ происходит с диалогом при нажатии Enter
От: kero Россия  
Дата: 06.10.10 15:29
Оценка:
Здравствуйте, ononim, Вы писали:

K>>Все так, только выше речь шла о CreateDialog

O>Отлично. Читаем MSDN про CreateDialog:

O>

O>After CreateDialog returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function

А в топике-то речь об EndDialog
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[7]: Что _реально_ происходит с диалогом при нажатии Enter
От: rus blood Россия  
Дата: 06.10.10 15:32
Оценка:
Здравствуйте, kero, Вы писали:

K>А в топике-то речь об EndDialog


В топике речь о том, что у ТС было неверное представление, будто EndDialog физически уничтожает окно диалога.
Имею скафандр — готов путешествовать!
Re[8]: Что _реально_ происходит с диалогом при нажатии Enter
От: kero Россия  
Дата: 06.10.10 15:45
Оценка:
Здравствуйте, rus blood, Вы писали:

RB>В топике речь о том, что у ТС было неверное представление, будто EndDialog физически уничтожает окно диалога.


Вот точные слова ТС (пост #6):
> Думал что вызов EndDialog приводит к уничтожению диалога (не сразу, а после выхода из диалоговой процедуры),

откуда видно, что MSDN/EndDialog ТС читал и что вы слегка сутрировали его представление
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[7]: Что _реально_ происходит с диалогом при нажатии Enter
От: ononim  
Дата: 06.10.10 15:47
Оценка:
K>>>Все так, только выше речь шла о CreateDialog
O>>Отлично. Читаем MSDN про CreateDialog:
O>>

O>>After CreateDialog returns, the application displays the dialog box (if it is not already displayed) by using the ShowWindow function. The application destroys the dialog box by using the DestroyWindow function

K>А в топике-то речь об EndDialog

Так ты определись,
Впрочем неважно.
Про EndDialog я написал тут: http://rsdn.ru/forum/winapi/3987081.1.aspx
Автор: ononim
Дата: 06.10.10

Про CreateDialog тут: http://rsdn.ru/forum/winapi/3987100.1.aspx
Автор: kero
Дата: 06.10.10


И предвосхищая следующий вопрос — диалоги созданные CreateDialog'ом — EndDialog'ом завершаться не должны. Потому что см статью про CReateDialog и смотри статью про EndDialog еще раз, вдумчиво читая:
Dialog boxes created by the DialogBox, DialogBoxParam, DialogBoxIndirect, and DialogBoxIndirectParam functions must be destroyed using the EndDialog function. An application calls EndDialog from within the dialog box procedure; the function must not be used for any other purpose.
Как много веселых ребят, и все делают велосипед...
Re[8]: Что _реально_ происходит с диалогом при нажатии Enter
От: kero Россия  
Дата: 06.10.10 15:54
Оценка:
Здравствуйте, ononim, Вы писали:

O>Так ты определись,

O>Впрочем неважно.
O>Про EndDialog я написал тут: http://rsdn.ru/forum/winapi/3987081.1.aspx
Автор: ononim
Дата: 06.10.10

O>Про CreateDialog тут: http://rsdn.ru/forum/winapi/3987100.1.aspx
Автор: kero
Дата: 06.10.10


O>И предвосхищая следующий вопрос — диалоги созданные CreateDialog'ом — EndDialog'ом завершаться не должны. Потому что см статью про CReateDialog и смотри статью про EndDialog еще раз, вдумчиво читая:[...]


Если вдумчиво перечитаешь этот наш совместный топик, то в конце концов заметишь, что а вот я обо всем об этом — написал тут:

> Проект Комментария к "Win32 API Tutorial" by Iczelion

По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Re[9]: Что _реально_ происходит с диалогом при нажатии Enter
От: ononim  
Дата: 06.10.10 15:56
Оценка:
O>>Так ты определись,
O>>Впрочем неважно.
O>>Про EndDialog я написал тут: http://rsdn.ru/forum/winapi/3987081.1.aspx
Автор: ononim
Дата: 06.10.10

O>>Про CreateDialog тут: http://rsdn.ru/forum/winapi/3987100.1.aspx
Автор: kero
Дата: 06.10.10


O>>И предвосхищая следующий вопрос — диалоги созданные CreateDialog'ом — EndDialog'ом завершаться не должны. Потому что см статью про CReateDialog и смотри статью про EndDialog еще раз, вдумчиво читая:[...]


K>Если вдумчиво перечитаешь этот наш совместный топик, то в конце концов заметишь, что а вот я обо всем об этом — написал тут:

>> Проект Комментария к "Win32 API Tutorial" by Iczelion
K>
ну тогда, мьсе, почему вы ко мне навязчиво пристаете?
Как много веселых ребят, и все делают велосипед...
Re[9]: Что _реально_ происходит с диалогом при нажатии Enter
От: rus blood Россия  
Дата: 06.10.10 15:59
Оценка:
Здравствуйте, kero, Вы писали:

K>откуда видно, что MSDN/EndDialog ТС читал и что вы слегка сутрировали его представление


В любом случае, оно неверное.
EndDialog не всегда приводит к уничтожению окна.
Имею скафандр — готов путешествовать!
Re[10]: Что _реально_ происходит с диалогом при нажатии Ente
От: kero Россия  
Дата: 06.10.10 16:00
Оценка:
Здравствуйте, ononim, Вы писали:

O>ну тогда, мьсе, почему вы ко мне навязчиво пристаете?


ТАК меня еще никто не обижал
По всему, пашиным хозяевам позарез нужна война в Европе
(уверены — к ним не залетит, в предыдущих двух не залетало жеж)
Автор: kero
Дата: 21.07.14
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.