Мне было интересно, в чем разница между сообщениями WM_QUIT, WM_CLOSE и WM_DESTROY в программе Windows, по сути: когда они отправляются и имеют ли они какие-либо автоматические эффекты, кроме того, что определено программой?
В чем разница между WM_QUIT, WM_CLOSE и WM_DESTROY в программе Windows?
Ответы (5)
Они совершенно разные.
WM_CLOSE
отправляется в окно, когда оно закрывается - когда нажата его кнопка X, или когда выбрано Close из меню окна, или Alt-F4 нажата, когда окно находится в фокусе, и т. Д. вы поймали это сообщение, это ваше решение, как с ним обращаться - игнорировать его или действительно закрыть окно. По умолчанию 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
(см. типичный фрагмент оконной процедуры).
WM_ENDSESSION
. Это автоматически вызывает WM_CLOSE / QUIT / DESTROY?
- person Basj; 22.07.2017
WM_(QUERY)ENDSESSION
. В конце концов, все ставки сняты. См. Windows не закрывает окна, когда пользователь выходит из системы; это ваш звонок
- person Remy Lebeau; 17.12.2020
Прежде всего, WM_CLOSE и WM_DESTROY сообщения связаны с определенными окнами, тогда как WM_QUIT применимо ко всему приложению (поток скважины), и сообщение никогда не принимается через оконную процедуру (процедура WndProc
), а только с помощью функций GetMessage
или PeekMessage
.
В вашей WndProc
программе функция DefWindowProc
заботится о поведении этих сообщений по умолчанию. Сообщения WM_CLOSE запрашивают, что приложение должно быть закрыто, и поведение по умолчанию для этого заключается в вызове функции DestroyWindow
. Когда вызывается эта DestroyWindow
функция, отправляется сообщение WM_DESTROY. Обратите внимание, что WM_CLOSE - это всего лишь сообщение с просьбой закрыть (например, WM_QUIT) - на самом деле вам не нужно выходить / выходить. Но сообщение WM_DESTROY сообщает вам, что ваше окно IS strong> закрывается и уничтожается, поэтому вы должны очистить все ресурсы, дескрипторы и т. д.
Чтобы в комментариях не потерялось ... не забываем про WM_CANCEL
. Когда вы нажимаете кнопку закрытия (x) в диалоговом окне MFC, он обязательно отправляет WM_CLOSE
. Затем функция по умолчанию OnClose()
вызовет функцию по умолчанию (базовый класс) OnCancel()
.
Однако, если вы просто наберете клавишу ESC
, это приведет к закрытию диалога, но (насколько я могу судить) без генерации события WM_CLOSE
- он перейдет непосредственно к механизму WM_CANCEL/OnCancel()
.
Настоящим я предлагаю сообществу подробно остановиться на этом ... или отредактировать это уточнение в принятом ответе.
Сначала обсудим WM_QUIT - отличие от других сообщений в том, что это не связано с окном. Используется приложением. Например, это может обрабатываться невидимым автономным сервером OLE (.exe, но не внутрипроцессным, как .dll)
WM_CLOSE - на msdn: «Приложение может запрашивать у пользователя подтверждение перед разрушением окна» - оно используется как уведомление о намерении закрыть (вы можете отклонить это намерение).
WM_DESTROY - это факт, что окно закрывается и все ресурсы должны (!) Быть освобождены.
Я знаю, что это устарело, но просто пытаюсь дать более ясный ответ для всех.
// What causes each message?
WM_CLOSE: // Pressed Close Button (X) / Alt+F4 / "Close" in context menu
WM_DESTROY: // Called DestroyWindow(hwnd)
WM_QUIT: // Called PostQuitMessage(exit)
// What do they do by default?
case WM_CLOSE: DestroyWindow(hwnd); return 0; // pressed close? destroy window.
case WM_DESTROY: PostQuitMessage(0); return 0; // destroyed window? quit message loop.
// WM_QUIT isn't associated with a window, so isn't sent to the window procedure
Итак, WM_CLOSE
просто для того, чтобы мы могли запросить уничтожение окна. Однако вы можете захотеть, чтобы в вашей игре отображалось всплывающее окно с вопросом, уверены ли вы. (и если вы хотите сначала сэкономить)
И WM_DESTROY
фактически не отправляет сообщение о выходе по умолчанию, поскольку у вас может быть несколько окон. Это обычное событие, после которого мы бросаем курить. Вы могли бы WM_CLOSE
вызвать PostQuitMessage(exit)
и уничтожить ваши окна после цикла сообщений, если хотите.
Если вам нужна пользовательская кнопка закрытия в вашей игре, она должна делать то, что делает WM_CLOSE
.
Также есть функция CloseWindow(hwnd)
, но она просто минимизирует окно.
Надеюсь, это кому-нибудь поможет.