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

Из системной очереди сообщения распределяются по приложениям. Для каждого приложения Windows организует отдельную очередь сообщений прикладной программы, которая по умолчанию вмещает до 8 сообщений. В процессе распределения сообщений по приложениям Windows извлекает очередное сообщение из системной очереди, определяет, с каким окном оно связано, и помещает в очередь того приложения, которому принадлежит окно.

Обработку прикладной очереди сообщений осуществляет уже само приложение. Для этого программа организует так называемый цикл обработки сообщений. В нем осуществляется выбор нового сообщения из очереди прикладной программы и вызов диспетчера для его обработки оконной функцией.

Для извлечения сообщений из очереди приложения существуют функция:

BOOL PeekMessage(LPMSG lpMsg, HWND hWnd, UINT wMsgFilterMin, UINT wMsgFilterMax, UINT wRemoveMsg );

LpMsg – возвращаемое программе сообщение. Оно имеет следующую структуру

typedef struct tagMSG { HWND hwnd; // окно, для которого предназначено сообщение UINT message; // собственно сообщение WPARAM wParam; // дополнительная информация LPARAM lParam; // к сообщению DWORD time; // время посылки сообщения POINT pt; // положение курсора мыши} MSG, *PMSG;

В поле hwnd структуры MSG записывается дескриптор окна, которому адресовано сообщение; тип сообщения записывается в 32-разрядное поле message, а дополнительная информация (параметры сообщения) – в поля wParam и lParam. Типы WPARAM и LPARAM определены при помощи typedef соответственно как UINT и LONG.

hWnd – дескриптор окна, для которого ожидается сообщение (передача в этом параметре нуля указывает на то, что извлекается сообщение, предназначенное любому окну прикладной программы).

wMsgFilterMin, wMsgFilterMax – минимальное и максимальное допустимые значения поля message в записи Msg (для получения всех сообщений оба параметра нужно установить в нуль).

wRemoveMsg – режим работы функции PeekMessage: pm_NoRemove – принятое сообщение остается в очереди, pm_Remove – сообщение удаляется из очереди. Флаг pm_NoYield используется в комбинации с одним из этих значений, чтобы предотвратить передачу управления другим задачам.

Функция GetMessage является частным случаем PeekMessage. В ней отсутствует параметр wRemoveMsg, она всегда удаляет сообщения из очереди и возвращает True, если принятое сообщение не является сообщением wm_Quit.

Сообщения, поступающие от клавиатуры, требуют дополнительной обработки – трансляции. Поэтому после приема сообщения нужно вызвать функцию

BOOL TranslateMessage(CONST MSG* lpMsg // информация сообщения );

Она преобразовывает сообщение о нажатии клавиши в сообщение о приходе символа. Дело в том, что сообщения, генерируемые драйвером клавиатуры, содержат виртуальный key-code, который определяет, какая клавиша была нажата, но не определяет символьное значение этой клавиши. Функция TranslateMessage, не изменяя переданное ей сообщение, помещает еще одно сообщение с соответствующим символьным значением в очередь приложения. Функция возвращает True, если переданное ей сообщение оказалось клавиатурным.

После трансляции сообщение диспетчиризируется оконной процедуре:

LRESULT DispatchMessage(CONST MSG* lpmsg // информация сообщения );

Результат обработки сообщения возвращается как значение функции. Его смысл зависит от типа обработанного сообщения и чаще всего игнорируется прикладной программой.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: