Цикл обработки сообщений в простейшем случае состоит из одного предложения
while (GetMessage(&msg, NULL, 0, 0))
DispatchMessage(&msg);
В этом бесконечном (если его не разорвать изнутри) цикле вызывается функция Windows GetMessage() и, если она возвращает ненулевое значение, вызывается функция DispatchMessage().
Функция GetMessage() анализирует очередь сообщений приложения. Если в очереди обнаруживается сообщение, GetMessage() изымает его из очереди и передает в структуру msg, после чего завершается с возвратом значения TRUE. Если сообщений в очереди нет, функция GetMessage() вызывает программы Windows, которые передают управление другим работающим приложениям (их циклам обработки сообщений). После опроса остальных приложений управление возвращается в наше приложение в ту же точку анализа сообщений. Таким образом, функция GetMessage() завершится (с возвратом значения TRUE) лишь после того, как очередное сообщение попадет в структуру msg.
Далее в цикле while вызывается функция DispatchMessage(). Ее назначение – вызов оконной функции для того окна, которому предназначено очередное сообщение. После того, как оконная функция обработает очередное сообщение, возврат из нее приводит к возврату из функции DispatchMessage() на продолжение цикла while.
Функция GetMessage()требует 4 параметра. Первый из них – адрес структуры msg, в которую GetMessage() должна передать изъятое из очереди сообщение. Второй параметр типа HWND позволяет определить окно, чьи сообщения будут изыматься функцией GetMessage(). Если этот параметр равен NULL, GetMessage() работает со всеми сообщениями данного приложения.
Два последние параметра определяют диапазон сообщений, которые анализируются функцией GetMessage(). Если, например, в качестве этих параметров указать константы WM_KEYFIRST и WM_KEYLAST, GetMessage() будет забирать из очереди только сообщения, относящиеся к клавиатуре; константы WM_MOUSEFIRST и WM_MOUSELAST позволяют работать только с сообщениями от мыши. Чаще всего надо анализировать все сообщения. Чтобы исключить фильтрацию сообщений, оба параметра должны быть равны 0.
Особая ситуация возникает, если функция GetMessage() обнаруживает в очереди сообщение WM_QUIT с кодом 0x12. В этом случае GetMessage() сразу же завершается с возвратом значения FALSE. Однако цикл while выполняется лишь, если GetMessage() возвращает TRUE. Возврат FALSE приводит к завершения цикла и переходу на предложение
Return msg.wParam;
т. е. к завершению функции WinMain() и всего приложения. Таким образом, условием завершения приложения является появление сообщения WM_QUIT. Как оно возникает, будет рассмотрено ниже.