int I - DefWindowProcChWnd, WMJCHITTEST, lParam.wParam): if (MenuOff && I--5) return 1;

Следует заметить, что я часто после обработки сообщения вместо выполнения обработчика по умолчанию DefWindowProcC) легкомысленно выходил из оконной процедуры командой return 0. Обычно этого достаточно, но иногда, например при Порядок обмена сообщениями при работе с меню обработке WMCREATE, следует возвращать ненулевое значение. Данный пример показывает, как возвращение оконной процедурой некорректного значения может влиять на работоспособность приложения.

Пункт меню может быть продублирован акселератором - сочетанием клавиш, нажатие которых также порождает сообщение WMCOMMAND. Акселераторы тоже могут создаваться в редакторе ресурсов. При этом задаются сочетание клавиш и код, которым будет заполнено поле wParam сообщения WM_COMMAND. Загрузка из ресурса таблицы акселераторов (массива структур типа ACCEL) выполняется следующей функцией:

HACCEL hAccelTable - LoadAccelerators(hInstance. (LPCTSTR)IDCJTT)

Таблицу акселераторов можно также создать в программе при помощи функции HACCEL CreateAcceleratorTable(*ACCEL. int), которая получает адрес массива структур типа ACCEL и количество элементов массива.

Для обработки акселераторов в основной цикл включается функция Transi ate-AcceleratorO, которая преобразует сообщение WM_KEYDOWN в WM_COMMAND, заполняя младшее слово поля wParam созданного сообщения командой, прочитанной из таблицы акселераторов.

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

Причина такого поведения системы заключается в том, что созданное сообщение WM_COMMAND не помещается в очередь и не выбирается из нее операционной системой. Если клавиши акселератора были нажаты, то функция Transi ateAccel erator ( ) сама вызывает оконную процедуру и возвращает ненулевое значение. В этом случае в основном цикле пропускают вызов функции DispatchMessage(&msg), так как сообщение уже обработано. Это иллюстрирует фрагмент кода, приведенный в листинге 5.5.


⇐ Предыдущая| |Следующая ⇒