2015-12-27 3 views
1

Я заметил, что некоторые сообщения в WinAPI может быть получены только в «основном цикле обработки сообщений» с PeekMessage() (как WM_QUIT), другие могут быть получены только в определенном пользователе winProc() функции (например, WM_CLOSE и WM_SIZE), и некоторые сообщения, такие как WM_MOUSEMOVE, извлекаются с обоими.WinProc() против петли основного сообщения

В чем разница? Как узнать, куда будет отправляться сообщение WM?

+1

Некоторые сообщения фактически не вставляются в очередь, но генерируются по требованию, когда это необходимо [Дополнительная информация здесь: Раймонд Чен. Даже при том, что сообщения по перемещению мыши, покраске и таймера генерируются по требованию, все еще возможно для одного чтобы попасть в очередь] (https://blogs.msdn.microsoft.com/oldnewthing/20130523-00/?p=4273/). Это может объяснить это. –

+0

Под «queue» вы подразумеваете цикл сообщений? (PeekMessage()) – Pilpel

+0

PeekMessage и аналогичные извлекают сообщения из очереди, но они также могут генерировать сообщения, которые на самом деле никогда не помещались в очередь. Типичными сообщениями являются такие вещи, как движение мыши и т. Д. Если бы у вас был очень быстрый компьютер, вы получили бы тонны сообщений о движении мыши, если бы вы переместили мышь очень быстро над компонентом, а цикл сообщения фактически не обрабатывался, вместо этого они откладывали, пока кто-то на самом деле попробуйте вытащить сообщение из очереди и генерирует 1 такое сообщение. –

ответ

2

Сообщения, которые были отправлены с помощью дескриптора окна NULL, могут быть получены только в контуре сообщения. Обязательно, DispatchMessage() не может выполнять свою работу. Это довольно редко.

Но да, WM_QUIT, обратите внимание, как PostQuitMessage() не принимает ручку окна. Это довольно неизбежно, когда вы вызываете PostQuitMessage(), у вас (как правило) нет окна, поэтому только дескриптор окна NULL разумен. Конечно, его реальное намерение состоит в том, чтобы заставить GetMessage() возвращать FALSE и тем самым прекратить цикл сообщения.

Единственный другой случай, о котором я могу думать, это сообщения, созданные с помощью PostThreadMessage(). Обратите внимание, что это довольно опасная функция, она никогда не должна использоваться для публикации сообщений в потоке, который когда-либо отображает любое окно. Такие сообщения попадают в бит-ведро, когда накапливается другой цикл сообщений. Как и тот, который позволяет пользователю перемещать/изменять размер окна. Или тот, который поддерживает MessageBox(). Он полезен только при обработке процесса и прерывания потоков.

Так что просто игнорируйте это, это угловой футляр.

Смежные вопросы