Рассмотрим, как взаимодействуют Windows и приложение при обработке, например, нажатие клавиши:
Рис.3. Обработка нажатия клавиши.
При поступлении сигналов от мыши или клавиатуры аппаратура IBM PC формирует асинхронные прерывания, которые обрабатываются драйверами keyboard.drv и mouse.drv соответственно. При поступлении сигнала драйвер вызывает процедуру в модуле user.exe, формирующую соответствующе сообщение. Это сообщение, содержащее полную информацию о событии, помещается в системную очередь.
Системная очередь Windows одна. Сообщения, которые помещаются в системную очередь, распределяются затем по приложениям. Для каждого приложения Windows организует и поддерживает отдельную очередь приложения.
Распределение сообщений по приложениям заключается в том, что сообщения извлекаются из системной очереди, определяется, какому окну предназначено данное сообщение, и это сообщение помещается в очередь приложения, которому принадлежит окно.
Эту работу осуществляет модуль user.exe. Обработку очереди приложения осуществляет уже само приложение. Для этого существует так называемый цикл сообщений приложения, который извлекает сообщения из очереди, переводит их в сообщение ANSI (например WM_CHAR) и направляет их в соответствующую функцию окна приложения. Конкретные действия по сообщению предпринимаются уже функцией окна; например, если требуется отобразить символ в пользовательской области окна приложения, то это делает функция окна приложения при помощи функции API TextOut().
Системная очередь сообщений является, таким образом, средством распределения сообщений по приложениям.
Если заранее известно, какому приложению предназначено то или иное сообщение, то оно помещается в очередь приложения, минуя системную очередь. Так при работе с таймером мы явно указываем, какому приложению направлять сообщение по истечении определенного времени интервала. Поэтому сообщение таймера не нужно помещать в системную очередь; они передаются непосредственно в очередь приложения.
Приложение Windows, создав окно и подготовив среду приложения, передает управление Windows и в дальнейшем, вплоть до завершения работы, приложение получает от Windows только по приходе сообщений, предназначенных для данного приложения.
Создав окно приложения, главная функция WinMain() организует цикл сообщений. Основное назначение этого цикла - обработка очереди сообщений данного приложения, которая создается и поддерживается Windows. Сообщения, помещаемые Windows в очередь приложения, извлекаются из нее циклом сообщений и направляются (не напрямую, а через Windows) в функцию управления соответствующим окном приложения.
Рис.4 Запуск приложения Windows и вызов функции окна по приходе сообщения.
С технической точки зрения, получение окном сообщения реализовано как вызов функции окна из Windows, которую принято называть WndProc(). При этом само сообщение выступает как передаваемый функции окна набор параметров специального формата.
Таким образом, цикл сообщений (message loop) только извлекает сообщения из очереди сообщений и направляет в функцию окна. Именно она содержит команды, выполняющие реальные действия, выполнение команд меню, осуществление вывода в окно графики, текста и прочие действия, относящиеся собственно к приложению.