В чем разница между WM_QUIT, WM_CLOSE и WM_DESTROY в программе для Windows? - PullRequest
62 голосов
/ 01 июля 2010

Мне было интересно, в чем разница между сообщениями WM_QUIT, WM_CLOSE и WM_DESTROY в программе Windows, по существу: когда они отправляются и имеют ли они какие-либо автоматические эффекты, помимо того, что определено программой?

Ответы [ 4 ]

80 голосов
/ 01 июля 2010

Они совершенно разные.

WM_CLOSE отправляется в окно, когда нажимается «X» или выбирается «Закрыть» из меню окна. Если вы поймете это сообщение, это ваш призыв, как его обработать - игнорируйте его или действительно закройте окно. По умолчанию, WM_CLOSE, переданный DefWindowProc, вызывает разрушение окна. Когда окно разрушается, WM_DESTROY отправляется сообщение. На этом этапе, в отличие от WM_CLOSE, вы не можете остановить процесс, вы можете только сделать необходимую очистку. Но помните, что когда вы ловите WM_DESTROY как раз перед тем, как все дочерние окна уже уничтожены. WM_NCDESTROY отправляется сразу после уничтожения всех дочерних окон.

Сообщение

WM_QUIT не относится ни к какому окну (hwnd, полученное из GetMessage, равно NULL, и оконная процедура не вызывается) Это сообщение указывает, что цикл сообщений должен быть остановлен, а приложение должно быть закрыто. Когда GetMessage читает WM_QUIT, он возвращает 0, чтобы указать это. Взгляните на типичный фрагмент цикла сообщения - цикл продолжается, пока GetMessage возвращает ненулевое значение. WM_QUIT можно отправить с помощью функции PostQuitMessage. Эта функция обычно вызывается, когда главное окно получает WM_DESTROY (см. типичный фрагмент процедуры окна ).

10 голосов
/ 01 июля 2010

Прежде всего, сообщения WM_CLOSE и WM_DESTROY связаны с конкретными окнами, тогда как сообщение WM_QUIT применимо ко всему приложению (скважинная нить) и сообщение никогда не принимается через оконную процедуру (WndProc рутина), а только через функции GetMessage или PeekMessage.

В вашей подпрограмме WndProc функция DefWindowProc заботится о поведении этих сообщений по умолчанию. Сообщения WM_CLOSE требуют, чтобы приложение закрылось, и поведение по умолчанию для этого заключается в вызове функции DestroyWindow. Когда эта функция DestroyWindow вызывается, отправляется сообщение WM_DESTROY . Обратите внимание, что WM_CLOSE является только сообщением, требующим вашего закрытия (например, WM_QUIT ) - вам на самом деле не нужно выходить / выходить. Но сообщение WM_DESTROY сообщает, что ваше окно IS закрыто и уничтожено, поэтому вы должны очистить все ресурсы, дескрипторы и т. Д.

4 голосов
/ 11 июня 2015

Только чтобы в комментариях не потерялись ... не забудьте про WM_CANCEL. Когда вы нажимаете кнопку закрытия (x) в диалоговом окне MFC, оно обязательно отправит WM_CLOSE. Функция по умолчанию OnClose() вызовет функцию по умолчанию (базовый класс) OnCancel().

Однако, если вы просто наберете клавишу ESC, это приведет к закрытию диалога, но (насколько я могу судить) без генерации события WM_CLOSE - оно перейдет непосредственно к WM_CANCEL/OnCancel() механизм.

Настоящим я предлагаю сообществу уточнить это ... или отредактировать эту разработку в принятый ответ.

2 голосов
/ 01 июля 2010

Сначала давайте обсудим WM_QUIT - отличие от других сообщений в том, что это не связано с окном. Используется приложением. Например, это может быть обработано невидимым автономным сервером OLE (.exe, но не in-proc, как .dll)

WM_CLOSE - для msdn: « Приложение может запросить у пользователя подтверждение перед разрушением окна » - оно используется как уведомление о намерении закрыть (вы можете отклонить это намерение).

WM_DESTROY - это факт, что окно закрывается и все ресурсы должны (!) Быть освобождены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...