Возвращается либо , либо .
Возвращается либо , либо .
Создание эффективных Win32-приложений - ДЖ. Рихтер
Прекрасный пример такой последовательности событий — вызов функции Trans- lateMessage, проверяющей, не было ли выбрано из очереди ввода сообщение WM_KEY- DOWN или WM_SYSKEYDOWN. Если одно из этих сообщений выбрано, система проверяет, можно ли преобразовать информацию о виртуальной клавише в символьный эквивалент. Если это возможно, TranslateMessage вызывает PostMessage, чтобы поместить в очередь асинхронных сообщений WM_CHAR или WM_SYSCHAR. При следующем вызове GetMessage система проверяет содержимое очереди асинхронных сообщений и, если в ней есть сообщение, извлекает его и возвращает потоку. Возвращается либо WM_CHAR, либо WM_SYSCHAR. При следующем вызове GetMessage система обнаруживает, что очередь асинхронных сообщений пуста. Тогда она проверяет очередь ввода, где и находит сообщение WM_(SYS)KEYUP; именно оно и возвращается функцией GetMessage.
Поскольку система устроена так, а не иначе, последовательность аппаратных событий:
WM_KEYDOWN
WM_KEYUP
генерирует следующую последовательность сообщений для оконной процедуры (при этом предполагается, что информацию о виртуальной клавише можно преобразовать в ее символьный эквивалент):
WM_KEYDOWN
WM_CHAR
WM_KEYUP
Вернемся к тому, как система решает, что за сообщение должна вернуть функция GetMessage или PeekMessage. Просмотрев очередь асинхронных сообщений, система, прежде чем перейти к проверке очереди виртуального ввода, проверяет флаг QS_QUIT. Вспомните: этот флаг устанавливается, когда поток вызывает PostQuitMessage. Вызов PostQuitMessage дает примерно тот же эффект, что и вызов PostMessage, которая помещает сообщение в конец очереди и тем самым заставляет обрабатывать его до проверки очереди ввода. Так почему же PostQuitMessage устанавливает флаг вместо того, чтобы поместить WM_QUIT в очередь сообщений? На то есть две причины.