Окт 13

Обработка сообщений

После вывода окна на экран программа должна подготовить себя для получения информации от пользователя. Эта информация обычно вводится с помощью клавиатуры или мыши. Windows поддерживает «очередь сообщений» (message queue) для каждой программы, работающей в системе. Любое действие пользователя система Windows преобразует в «сообщение», которое помещается в указанную очередь.
Функция GetMessage возвращает значение TRUE при извлечении любого сообщения, кроме одного — WM_QUIT. Получив сообщение WM_QUIT, функция возвращает значение FALSE. В результате этого происходит немедленный выход из цикла, и приложение завершает работу, возвращая операционной системе код возврата msg.wParam.
Но какова дальнейшая судьба принятого сообщения?
В теле цикла обработки сообщений можно увидеть вызов двух функций: TranslateMessage и DispatchMessage.
Строго говоря, вызов TranslateMessage нужен только в тех приложениях, которые должны обрабатывать ввод данных с клавиатуры. Дело в том, что для обеспечения независимости от аппаратных платформ и различных национальных раскладок клавиатуры в Windows реализована двухуровневая схема обработки сообщений от символьных клавиш. Сначала система генерирует сообщения о так называемых виртуальных клавишах, например: сообщение WM_KEYDOWN — когда клавиша нажимается, и сообщение WM_KEYUP — когда клавиша отпускается. В сообщении WM_KEYDOWN содержится также информация о так называемом скан-коде1 нажатой клавиши.
Функция TranslateMessage преобразует пару сообщений, WM_KEYDOWN и WM_KEYUP, в сообщение WM_CHAR, которое содержит код символа (wParam) в виде значения типа TCHAR2. Сообщение WM_CHAR помещается в очередь, а на следующей итерации цикла функция GetMessage извлекает его для последующей обработки.
Наконец, функция DispatchMessage передает структуру msg обратно в Windows. Очередной ход — за Windows. Windows отправляет сообщение для его обработки соответствующей оконной процедуре, вызывая ее как функцию обратного вызова.
Следует обратить внимание на то, что сообщение передается оконной процедуре именно того окна, которому оно было адресовано. Это может быть или WndProc (если сообщение адресовано главному окну), или оконная процедура некоторого диалогового окна, или оконная процедура одного из стандартных элементов управления, спрятанная в недрах Windows (то есть в DLL).
После возврата из оконной процедуры Windows передает управление оператору, указанному за вызовом DispatchMessage, то есть на начало цикла while, и работа цикла продолжается.
Как уже говорилось ранее, цикл обработки сообщений функционирует до тех пор, пока из очереди не поступит сообщение WM_QUIT. Появление этого сообщения вызывает немедленный выход из цикла и прекращение работы программы.