Флаги состояния очереди
Во время выполнения поток может опросить состояние своих очерсдсй вызовом GetQueueStatus:
DWORD GetQueueStatus(UINT fuFlags);
Параметру fuFlags — флаг или группа флагов, объединенных побитовой операци ей OR, он позволяет проверить значения отдельных битов пробуждения (wake bits) Допустимые значения флагов и их смысл описаны в следующей таблице.
Флаг |
Сообщение в очереди |
QS_KEY |
WM_KEYUP,WM_KEYDOWN, WM_SYSKEYUP или WM_SYSKEYDOWN |
QS_MOUSEMOVE |
WM_MOUSEMOVE |
QS_MOUSEBTITTON |
WM_?BUTTON* (где знак вопроса заменяет букву L, М или R, а звездочка — DOWN, UP или DBLCLK) |
QS_MOUSE |
То же, что QS_MOUSEMOVE | QS_MOUSEBUTTON |
QS_INPUT |
То же, что QS_MOUSE | QS_KEY |
QS_PAINT |
WM_PAINT |
QS_TIMER |
WM_TIMER |
QS_HOTKEY |
WM_HOTKEY |
QS_POSTMESSAGE |
Асинхронное сообщение (отличное от события аппаратного ввода), этот флаг идентичен QS_ALLPOSTMESSAGE с тем исклю чением, что сбрасывается при отсутствии асинхронных сообще ний в диапазоне действия фильтра сообщений |
QS_ALLPOSTMESSAGE |
Асинхронное сообщение (отличное от события аппаратного вво да); этот флаг идентичен QS_POSTMESSAGE с тем исключением, что сбрасывается лишь при полном отсутствии каких-либо асин хронных сообщений (вне зависимости от фильтра сообщений) |
QS ALLEVENTS |
Тоже, что QS_INPUT | QS_POSTMESSAGE | QS_TIMER | QS_PAINT | QS_HOTKEY |
QS_QUIT |
Сообщает о вызове PostQuitMessage, этот флаг не задокументиро ван, его нет в WinUser.h, и он используется самой системой |
QS_SENUMESSAGE |
Синхронное сообщение, посланное другим потоком |
QS_ALLINPUT |
То же, что QS_ALLEVENTS | QS_SENDMESSAGF |
При вызове GetQueueStatus параметр fuFlags сообщает функции, наличие каких типов сообщений в очереди следует проверить. Чем меньше идентификаторов QS_* объединено побитовой операцией OR, тем быстрее отрабатывается вызов Результат сообщается в старшем слове значения, возвращаемого функцией. Возвращаемый на бор флагов всегда представляет собой подмножество того набора, который Вы зап росили от функции. Например, если Вы делаете такой вызов.
BOOL fPaintMsgWaiting = HIWORD(GetQueueStatus(QS TIMER)) & OS_PAINT;
ю значение fPaintMsgWaiting всегда будет равно FALSE независимо от наличия в оче реди сообщения WM_PAINT, так как флаг QS_PAINT функции не передан
Младшсс слово возвращаемого значения содержит типы сообщений, которые помещены в очередь, но не обработаны с момента последнего вызова GetQueueStatus, GetMessage или PeekMessage.
Не все флаги пробуждения обрабатываются системой одинаково Флаг QS_MOUSE MOVE устанавливается, если в очереди есть необработанное сообщение WM_MOUSE
MOVE. Когда GetMessage или PeekMessage (с флагом PM_REMOVE) извлекают последнее сообщение WM_MOUSEMOVE, флаг сбрасывается и остается в таком состоянии, пока в очереди ввода снова не окажется сообщение WM_MOUSEMOVE. Флаги QS_KEY, QS_MOUSEBUTTON и QS_HOTKEY действуют при соответствующих сообщениях ана логичным образом.
Флаг QS_PAINT обрабатывается иначе. Он устанавливается, если в окне, созданном данным потоком, имеется недействительная, требующая псрсрисовки область Когда область, занятая всеми окнами, созданными одним потоком, становится действитель ной (обычно в результате вызова ValidateRect, ValidateRegion или BeginPaint), флаг QS_PAINT сбрасывается. Еще pay подчеркну: данный флаг сбрасывается, только если становятся действительными все окна, принадлежащие потоку. Вызов GetMessage или PeekMessage на этот флаг пробуждения пе влияет.
Флаг QS_POSTMESSAGE устанавливается, когда в очереди асинхронных сообщений потока есть минимум одно сообщение. При этом не учитываются аппаратные сооб щения, находящиеся в очереди виртуального ввода потока. Этот флаг сбрасывается после обработки всех сообщений из очереди асинхронных сообщений
Флаг QS_TIMER устанавливается после срабатывания таймера (созданного пото ком). После того как функция GetMessage или PeekMessage вернет WM_TIMER, флаг сбрасывается и остается в таком состоянии, пока таймер вновь не сработает
Флаг QS_SENDMESSAGE указывает, что сообщение появилось в очереди синхрон ных сообщений. Он используется системой для идентификации и обработки межпо точных синхронных сообщений, а для внутрипоточных синхронных сообщений не применяется. Вы можете указывать флаг QS_SENDMESSAGE, но необходимость в нем возникает крайне редко. Я ни разу не видел его ни в одном приложении.
Есть еще один (недокументированный) флаг состояния очереди — QS_QUIT. Он устанавливается при вызове потоком PostQuitMessage. Сообщение WM_QUIT при этом не добавляется к очереди сообщений И учтите, что GetQueueStatus не возвращает состояние этого флага