Учебное пособие: Сообщения и их обработка

Посылка сообщений

Мы это сделаем на примере нажатия на клавишу. Когда вы нажимаете на клавишу, генерируется аппаратное прерывание. Клавиатурный драйвер Windows обрабатывает это прерывание и помещает соответствующее сообщение в общую очередь сообщений Windows.

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

Этот процесс называется посылкой (post) сообщений, так как посылка сообщения напоминает посылку письма: посылающий сообщение указывает адресата, отправляет сообщение и больше о нем не беспокоится. Отправитель не знает, когда точно его сообщение получит адресат. Процесс посылки может показаться излишне сложным, однако для этого существует несколько причин:

Во–первых, аппаратные прерывания надо обрабатывать со всей возможной скоростью. Поэтому при приеме аппаратного прерывания драйвер не тратит время на передачу сообщения в очередь приложения, а ставит его в очередь сообщений Windows. Аппаратные прерывания являются асинхронными по отношению к выполняющемуся приложению, а обработка сообщений обязательно должна быть синхронной. Поэтому механизм посылки сообщений нельзя смешивать с аппаратными прерываниями.

А во–вторых, накопление событий в очереди приложения помогает уменьшить количество переключений между приложениями, так как Windows обычно дает приложению полностью обработать события из его очереди и лишь после этого переключается на другие приложения. Кроме того, некоторые события могут группироваться в одно во время нахождения в очереди.

Рисунок 1 Маршрутизация сообщений в Windows 3.x

Извлечение сообщений из очереди приложения и направление их соответствующим окнам осуществляет функция WinMain. Этот процесс выполняется в несколько приемов:

сообщение выбирается из очереди с помощью функции GetMessage или PeekMessage

затем сообщение транслируется с помощью функции TranslateMessage[0] (одно сообщение может порождать последовательность других или заменяться, как, например, происходит для сообщений клавиатуры WM_KEYDOWN). Часто трансляция состоит из вызова более чем одной функции, сюда могут добавляться специальные средства трансляции акселераторов и немодальных диалогов (об этом позже).

И только после этого оно направляется окну с помощью функции DispatchMessage (это называется диспетчеризацией)

Для выполнения этих операций существуют специальные функции. Эти функции образуют цикл обработки сообщений, так как после завершения обработки одного сообщения приложение должно приготовиться к обработке следующего. Цикл заканчивается только при завершении работы приложения.

MSG msg;

while (GetMessage(&msg, NULL, NULL, NULL)) {

TranslateMessage(&msg);

DispatchMessage(&msg);}

Это самый простой вид цикла обработки сообщений. В реальных приложениях он более сложный. Все три функции, вызываемые здесь, принадлежат Windows. Назначение их должно быть понятно. Требуется добавить несколько замечаний о функции GetMessage. Эта функция имеет следующие аргументы:

BOOL GetMessage(lpMsg, hWnd, uMsgFilterMin, uMsgFilterMax);

lpMsg указывает на структуру MSG, в которую будет записано полученное сообщение. Если очередь сообщений пуста, то GetMessage передает управление оболочке, так что та может начать обработку сообщений другого приложения.

Какие же данные передаются сообщением?

typedef struct tagMSG {

HWND hwnd; // хендл окна-получателя

UINT message; // номер сообщения WM_...

WPARAM wParam; // параметр сообщения

LPARAM lParam; // параметр сообщения

DWORD time; // время поступления сообщения

POINT pt; // координаты сообщения (для сообщений мыши)

--> ЧИТАТЬ ПОЛНОСТЬЮ <--

К-во Просмотров: 279
Бесплатно скачать Учебное пособие: Сообщения и их обработка