Блог GunSmoker-а (переводы)
. when altering one’s mind becomes as easy as programming a computer, what does it mean to be human.
среда, 1 сентября 2010 г.
В чём разница между WM_DESTROY и WM_NCDESTROY?
Существует два оконных сообщения, тесно связанных с уничтожением окна: сообщение WM_DESTROY и сообщение WM_NCDESTROY. В чём между ними разница?
Разница в том, что сообщение WM_DESTROY отправляется в начале последовательности уничтожения окна, а сообщение WM_NCDESTROY — в конце. Это является важным отличием, когда у вас есть дочерние окна (child windows — в смысле системы). Если у вас есть окно-родитель (parent window) с дочерним окном, то трафик сообщений (при отсутствии странностей) будет выглядеть так:
hwnd = parent, uMsg = WM_DESTROY
hwnd = child, uMsg = WM_DESTROY
hwnd = child, uMsg = WM_NCDESTROY
hwnd = parent, uMsg = WM_NCDESTROY
Заметьте, что родитель получает WM_DESTROY до того, как его дочерние окна будут уничтожены, а сообщение WM_NCDESTROY приходит ему после уничтожения дочерних окон.
Course Python In Arabic | Python and Tkinter | 6 Tkinter (iconify-deiconify-destroy)
Наличие двух сообщений очистки (одно отправляется сверху-вниз, второе — снизу-вверх) означает, что вы можете реализовать очистку в соответствии с любой из этих моделей — смотря по тому, на какое сообщение вы вешаете очистку. К примеру, если вам нужно чистить что-то в порядке сверху-вниз, то размещайте его код очистки в обработчике WM_DESTROY.
Более того, сообщение WM_NCDESTROY — это вообще самое последнее сообщение, которое получит ваше окно (при отсутствии странностей), и, поэтому, это отличное место для «последней очистки».
Эти два сообщения удаления окна имеют свои пары-аналоги в виде сообщений создания окна: WM_CREATE и WM_NCCREATE. Как WM_NCDESTROY является последним сообщением для окна, так и сообщение WM_NCCREATE является первым сообщением, которое получит ваше окно, так что это отличное место для начальной инициализации. Также заметьте, что если вы вернёте неудачу из WM_NCCREATE, то всё, что вы получите, будет сообщение WM_NCDESTROY; у вас не будет сообщения WM_DESTROY, поскольку вы не дошли до вызова соответствующего WM_CREATE.
Что это за «при отсутствии странностей», на которое я постоянно ссылаюсь? Мы увидим это в следующий раз.
Источник: www.transl-gunsmoker.ru
Wm destroy что это за программа
Это сообщение посылается когда необходимо уничтожить окно. После удалении его с экрана. Посылается сообщение сначала главному окну, а потом дочерним окнам. После принятия этого сообщения необходимо вызывать функцию PostQuitMessage(). Сообщение о разрушении окна поступит именно оконной процедуре, а не в стандартной очереди сообщения. Общий вид обработки этого сообщения такой:
case WM_DESTROY: PostQuitMessage( 0 ); break;
В ответ на это сообщение мы должны поместить в очередь сообщение WM_QUIT. Это и делает функция PostQuitMessage() посылая в очередь это сообщение и говоря, что процесс должен быть завершен.
Что за процесс dwm.exe в Windows 10
VOID PostQuitMessage ( int nExitCode // код возврата );
Смотрите на рисунок. Сообщение WM_DESTROY поступает сразу в оконную процедуру. Теперь оконная процедура вызывает PostQuitMessage(), которая и помещает сообщение WM_QUIT в очередь сообщений. В последствии его отловит GetMessage() и программа прекратит работу. WM_QUIT может посылать только WinMain() и должна это делать.
И Windows и Вы сами не должны посылать сообщение WM_QUIT. Это сделано для того, чтобы окно могло освободить все использованные им ресурсы.
Источник: firststeps.ru
В чем разница между WM_QUIT, WM_CLOSE и WM_DESTROY в программе для Windows?
Мне было интересно, какая разница между сообщениями WM_QUIT, WM_CLOSE и WM_DESTROY в программе Windows, по существу: когда они отправляются, и есть ли у них какие-либо автоматические эффекты, кроме того, что определено программой?
adf88 01 июль 2010, в 10:01
Поделиться
очень хороший квест
bvs 11 май 2018, в 21:34
Поделиться:
4 ответа
Лучший ответ
Они совершенно разные.
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 (см. типичный фрагмент процедуры окна).
adf88 01 июль 2010, в 09:27
Поделиться
Basj 22 июль 2017, в 13:15
Прежде всего, WM_CLOSE и WM_DESTROY сообщения связаны с конкретными окнами, тогда как сообщение WM_QUIT применимо ко всему приложению (поток скважины), и сообщение никогда не получается через окно процедуры ( WndProc ), но только через функции GetMessage или PeekMessage .
В вашей подпрограмме WndProc функция DefWindowProc выполняет по умолчанию поведение этих сообщений. WM_CLOSE сообщает о том, что приложение должно закрыть, а поведение по умолчанию для этого — вызвать функцию DestroyWindow . Его когда эта функция DestroyWindow вызывается, что отправляется сообщение WM_DESTROY. Обратите внимание, что WM_CLOSE — это только сообщение с просьбой закрыть (например WM_QUIT) — вам действительно не нужно выходить/выходить. Но сообщение WM_DESTROY сообщает, что ваше окно IS закрывается и уничтожается, поэтому вы должны очищать любые ресурсы, обрабатывать и т.д..
user353297 01 июль 2010, в 09:34
Поделиться
Не для всего приложения, а для конкретного цикла сообщений. Каждый поток может иметь свой собственный цикл сообщений, поэтому приложение может иметь несколько циклов сообщений.
0xC0000022L 25 янв. 2018, в 09:57
Просто чтобы он не заблудился в комментариях. не забывайте о WM_CANCEL . Когда вы нажимаете кнопку закрытия (x) в диалоговом окне MFC, она обязательно отправит WM_CLOSE . Функция OnClose() по умолчанию вызовет функцию по умолчанию (базовый класс) OnCancel() .
Однако, если вы просто наберете ключ ESC , это приведет к закрытию диалогового окна, но (насколько я могу судить) без генерации события WM_CLOSE — он переходит непосредственно к WM_CANCEL/OnCancel() механизм.
Настоящим я предлагаю сообществу разобраться в этом. или отредактировать эту разработку в принятом ответе.
Источник: overcoder.net
сообщение WM_DESTROY
Отправляется при уничтожении окна. Он отправляется в процедуру удаления окна после удаления окна с экрана.
Это сообщение сначала отправляется в окно, которое уничтожается, а затем в дочерние окна (если таковые имеются) по мере их уничтожения. Во время обработки сообщения можно предположить, что все дочерние окна по-прежнему существуют.
Окно получает это сообщение через функцию WindowProc .
#define WM_DESTROY 0x0002
Параметры
Этот параметр не используется.
Этот параметр не используется.
Возвращаемое значение
Тип: LRESULT
Если приложение обрабатывает это сообщение, оно должно возвращать ноль.
Remarks
Если уничтоженное окно является частью цепочки просмотра буфера обмена (задается путем вызова функции SetClipboardViewer ), окно должно удалиться из цепочки путем обработки функции ChangeClipboardChain перед возвратом из сообщения WM_DESTROY .
Требования
См. также раздел
Ссылки
Источник: learn.microsoft.com
Сообщение wm_destroy
Это сообщение Windows посылает функции окна сразу же после закрытия окна. При получении его функция окна должна завершить свою работу и, если это функция главного окна приложения, обязательно послать в очередь приложения сообщение WM_QUIT.
Функция окна должна обработать сообщение WM_DESTROY следующим образом:
case WM_DESTROY: PostQuitMessage(NUUL);
Функция PostQuitMessage() помещает сообщение WM_QUIT в очередь приложения. Когда функция GetMessage() извлечет это сообщение из очереди приложения, произойдет выход из цикла обработки сообщений и приложение совершит свою работу.
Функция окна получает сообщения из цикла обработки сообщений и от Windows. Из цикла обработки сообщений поступают сообщения ввода: перемещение и нажатие клавиш мыши (сообщения WM_MOUSEMOVE ,WM_LBUTTONDOWN и др.), нажатие и отпускание клавиш клавиатуры (WM_KEYDOWN и WM_ KEYUP) и, если установлен генератор событий таймера, сообщения от таймера (WM_TIMER).
Windows посылает функции окна сообщения поддержки окна напрямую, минуя очередь приложения и цикл обработки сообщений. Эти сообщения обычно вызваны событиями, требующими немедленной реакции по изменению вида окна, например, перерисовки изображения при изменении размеров окна пользователем или из-за взаимодействия с другими окнами. Эти сообщения могут служить также средством обмена информацией между Windows и приложением, сообщающим об изменении в среде Windows или о том, что Windows сделал с окном приложения. Типичными системными сообщениями окна являются, например, сообщения WM_CREATE, WM_DESTROY и WM_PAINT.
Если функция окна не обрабатывает сообщение, то необходимо передать управление функции DefWindowProc() и вернуть возвращенное ей значение.
О к н а Windows
Существует всего лишь три основных окон Windows.
Перекрывающиеся окна.
Флаг WS_OVERLAPPED. Это основной наиболее универсальный тип окна Windows. Главное, самое старшее, окно приложения, как правило, имеет именно этот тип.
Дочерние окна.
Флаг WS_CHILD. Окна этого типа, как правило, создаются тогда, когда у приложения уже есть главное(а значит, перекрывающееся) окно. Окно этого типа связано некоторыми характеристиками (как бы подчинено) с тем окном, из которого было создано дочернее окно; отсюда их название. Назначение этих окон может быть самое разнообразное, начиная от простого деления родительского окна на области до организации Много Документального Интерфейса (MDI — Multiple Document Interface). Все органы управления также являются дочерними окнами (child window controls).
Вспомогательные окна.
Флаг WS_POPUP. Этот тип окон чаще всего используется для отображения окон диалога. Отличаются они тем, что, если имеют родительское окно, всегда отображаются поверх всех окон на экране, выскакивают как поплавки наверх даже тогда, когда пользователь делает активным другое окно.
Из трех основных типов (классов) окон программист может создать множество самых разнообразных объектов.
Тип окна задается 32-битовым беззнаковым целым числом, которое указывается третьим параметром вызова функции CreateWindow. Этот параметр интерпретируется как комбинация битовых флагов, определяющих тип окна и некоторые его свойства. Допустимые флаги типов окна определены в файле windows.h; при создании окна их можно комбинировать битовой операцией «ИЛИ» («|»).
WS_MAXIMIZEBOX кнопка максимизации окна
WS_MINIMIZEBOX кнопка минимизации окна
WS_THICKFRAME наличие рамки
WS_HSCROLL горизонтальная линейка прокрутки
WS_VSCROLL вертикальная линейка прокрутки
WS_BORDER наличие границы
WS_CAPTION наличие заголовка окна
WS_DISABLED активность окна
WS_VISIBLE видимость окна
WS_OVERLAPPED перекрывающиеся окно
WS_CHILD дочернее окно
WS_POPUP вспомогательное окно
Рис.9. Идентификаторы стилей окон Windows.
Все основные типы окон могут оформляться основными стандартными элементами.
Комбинируя флаги, можно модифицировать внешний вид и некоторые свойства окон.
Создаваемое перекрывающееся окно имеет кнопку максимизации.
Если окно является дочерним органом управления (child window controls) внутри окна диалога, то этот флаг используется под другим именем — WS_TEBTOP; при работе с окном диалога по нажатию клавиши табуляции курсор перемещается к ближайшему окну (органу управления), у которого установлен флаг WS_TABSTOP.
Создаваемое окно является дочерним органом управления (child window controls) внутри окна диалога, то этот флаг используется под другим именем- WS_GROUP. Орган управления, помеченный этим флагом, определяет начало группы органов управления, по которой можно перемещаться клавишами перемещения курсора. Группа оканчивается там, где начинается следующая группа.
Создаваемое окно имеет рамку существенно заметной толщины; эта рамка является более чем украшением, потому что вы можете изменять размер только того окна , у которого этот флаг указан.
Окно имеет системное меню.
Окно имеет горизонтальную полосу просмотра.
Окно имеет вертикальную полосу просмотра.
Окно имеет тонкую рамку без заголовка.
Окно имеет широкую рамку без заголовка. Этот флаг используют при создании диалоговых окон.
Окно имеет рамку и заголовок. Так как окно будет иметь заголовок, то пользователь сможет перемещать его по экрану при помощи мыши. Флаг, как правило, используется для перекрывающихся окон.
Создаваемое окно будет отображено в максимально возможном для него размере.
Исключение областей, занимаемых дочерними окнами при изменении рабочей области родительского окна. Используется только для родительских окон.
Исключение областей, занимаемых другими дочерними окнами из изменяемой области дочернего окна. Другими словами, если дочерние окна перекрываются, а флаг WS_CLIPSIBLINGS не указан, то при изменении рабочей области одного из окон могут быть испорчены рабочие области других дочерних окон. Этот флаг используется только с флагом WS_CHILD.
Создается неактивное окно.
Окно становится видимым сразу после создания. Этот флаг используется для диалоговых окон.
Создаваемое окно будет отображено в виде пиктограммы.
Наиболее часто используемые определения типов окон — WS_OVERLAPPEDWINDOW, WS_POPUPWINDOW и WS_CHILDWINDOW; эти стандартные комбинации флагов определены в файле windows.h:
# define WS_OVERLAPPEDWINDOW (WS_OVERLAPPED |
WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
# define WS_POPUPWINDOW (WS_POPUP | WS_ BORDER | WS_SYSMENU)
# define WS_CHILDWINDOW (WS_CHILD)
Вспомогательные окна
Вспомогательные (popup) окна обычно используются для отображения на короткий промежуток времени какой-либо информации. Диалоговые окна и окна сообщений тоже являются вспомогательными, но для работы с ними используются специальные функции .
Для каждого вспомогательного окна, как правило, организуется своя функция окна.
Вспомогательное окно можно создать, указав флаг WS_POPUP в третьем параметре вызова функции CreateWindow().
Приведем некоторые особенности вспомогательных окон.
- Вспомогательные окна не имеют заголовка. Вы можете использовать флаг WS_BORDER или WS_DLGFRAME вместо WS_CAPTION для отображения рамки окна.
- Вспомогательные окна часто должны иметь фиксированный размер (хотя это не является обязательным). Для этого надо исключить из определения типа окна флаги WS_THICKFRAME и WS_MAXINIZEBOX.
- Вспомогательное окно может иметь, а может и не иметь окно-родителя. Если вспомогательное окно не имеет окна-родителя, то поле «индекс окна родителей» содержит NUUL, и вспомогательное окно совершенно независимо от создавшего его окна и по своим свойствам практически неотличимы от перекрывающихся окон. Поведение вспомогательного окна, имеющего родителя, зависит от того, что происходит с окном-родителем.
- Когда главное окно минимизируется, вспомогательное окно без «родителя» скрывается, а вспомогательное окно с «родителем» остается на экране сверху (как поплавок всегда оказывается сверху). Это справедливо и в том случае, когда вспомогательное окно минимизировано (что производит довольно неприятное впечатление); по этой причине иногда рекомендуется защищать минимизацию окна, не указывая вспомогательному окну флаг WS_MINIMIZEBOX.
Дочерние окна
Дочерние окна могут иметь самые различные функции, принимать всевозможные формы и размеры. Текстовые поля, редакторы, кнопки, окна-списки — все они являются частными случаями класса дочерних окон.
Дочерние окна имеют следующие особенности.
- Дочерние окна никогда не отображаются вне своего родительского окна ни в раскрытом виде, ни в виде пиктограммы: они как бы целиком принадлежат родителю.
- Координаты дочерних окон отсчитываются не от верхнего левого угла экрана дисплея, а от верхнего левого угла рабочей области окна-родителя. При перемещении родительского окна по экрану дочерние окна перемещаются вместе с ним, так что их относительные координаты остаются неизменными.
- Дочернее окно никогда не может стать активным окном.
- Перекрывающееся окна (overlapped window) окно никогда не имеет родителя.
- Дочернее окно (child window) всегда имеет родителя.
- Вспомогательное (popup window) окно может иметь, а может и не иметь родителя, то все равно это не дочернее, а вспомогательное окно.
Источник: studfile.net