Путь прохождения сообщений от клавиатуры



Рисунок 3.1. Путь прохождения сообщений от клавиатуры



Здесь буфер клавиатуры служит связующим звеном между прикладной программой и одним из сервисов ОС. Точно так же формируют (или могут формировать) свои специфические данные обработчики других событий. При этом используется универсальная структура данных MSG (сообщение), описывающая любое событие. Она содержит сопровождающую информацию, достаточную для того, чтобы сообщением можно было воспользоваться. Например, для сообщения от клавиатуры это должен быть код нажатой клавиши, для сообщения от мыши — координаты ее указателя, для сообщения WM_SIZE — размеры окна. Тип структур MSG определен в одном из файлов заголовков следующим образом:

//======= Ярлык типа

typedef struct tagMSG

{

//===== Описатель окна, чья оконная процедура

//===== получает сообщение

HWND hwnd;

UINT message; // Код сообщения

// Дополнительная информация, зависящая от сообщения

WPARAM wParam;

LPARAM iParam; // Тоже

DWORD time; // Время посылки сообщения

//==== Точка экрана, где был курсор

//==== в момент посылки сообщения

POINT pt;

}

MSG; //===== Тип структур, эквивалентный ярлыку

Универсальные параметры wParam и IParam используются различным образом в различных сообщениях. Например, в сообщении WM_LBUTTONDOWN первый из них содержит идентификатор одновременно нажатой клавиши (Ctrl, Shift и т.д.), а второй (IParam) — упакованные экранные координаты (х, у) курсора мыши. Чтобы выделить координаты, программист должен расщепить «длинный параметр» (4 байта) на два коротких (по 2 байта). В нижнем слове, которое можно выделить с помощью макроподстановки, например,

int х = LOWORD(IParam);

хранится координата х, а в верхнем — координата у, которую вы можете выделить с помощью макроса:

int у = HIWORD(IParam);

Отметьте, что классы библиотеки MFC избавляют вас от необходимости распаковывать параметры сообщения.

Следующая схема (Рисунок 3.2) в общих чертах иллюстрирует путь прохождения сообщений. Она любезно предоставлена Мариной Полубенцевой, вместе с которой мы ведем курс Visual C++ в Microsoft Certified Educational Center при Санкт-Петербургском государственном техническом университете.

Каждый обработчик события (драйвер) помещает сформированное сообщение в определенную динамическую структуру данных в памяти. Другие аппаратные и программные обработчики точно так же формируют свои сообщения, ставя их в очередь за уже существующими. Так формируется системная очередь сообщений.

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



- Начало - - Назад - - Вперед -