Реальный ответ немного сложнее, чем логические абстракции , предлагаемые MSDN . Я могу ответить более подробно, чем было подтверждено в комментариях к принятому ответу.
Да, есть два набора сообщений. Существует «очередь сообщений» и «очередь входных сообщений». Последний содержит список необработанных событий сообщений мыши и клавиатуры. Первый содержит опубликованные и обобщенные сообщения.
Внутренне, они оба просто списки, но список входных сообщений содержится в более крупной структуре, называемой внутренне как «очередь ввода». Структура содержит данные о логической очереди плюс указатель на необработанный список входных сообщений.
Их также взаимозаменяемо называют "очередь приложений" и "системная очередь" соответственно.
GetMessage()
обрабатывает их отдельно.
THREADINFO
содержит указатель непосредственно на список / очередь сообщений. Это сканируется, если установлен QS_POSTMESSAGE
.
Если установлены статуи очереди QS_INPUT
или QS_EVENT
, список / очередь входных данных сканируется путем получения исходного указателя структуры очереди из THREADINFO
, а затем указателя на список ввода из этой структуры очереди. Странно, я знаю.
Если установлен флаг состояния очереди QS_TIMER
, GetMessage()
(или PeekMessage()
) фактически придется запустить сканирование полного списка неядерных таймеров, чтобы найти самый ранний таймер с предупрежденным статусом, который " принадлежит "тому, кого называют GetMessage()
. Очереди на самом деле ничего не хранят о том, какой таймер сработал. Они хранят только связанную информацию, которую они хранят, это флаг QS_TIMER
и счетчик количества сработавших таймеров (так что GetMessage()
знает, когда следует очищать состояние очереди QS_TIMER
, как только он синтезировал сообщение для последнего доступного сработавшего таймера. )
Другие синтезированные сообщения работают аналогично в том смысле, что они основаны на данных, хранящихся вне фактических списков сообщений очереди, но все еще «в» других данных в самих структурах очереди.