Исходный текст метода


function TApplication.ProcessMessage: Boolean; var Handled: Boolean; Msg: TMsg; begin Result := False; if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then begin Result := True; if Msg.Message <>
WM_QUIT then begin Handled := False; if Assigned(FOnMessage) then FOnMessage (Msg, Handled);
if not IsHintMsg(Msg) and not Handled and not IsMDIMsg(Msg) and not IsKeyMsg(Msg) and not IsDlgMsg(Msg) then begin TranslateMessage(Msg);
DispatchMessage(Msg);
end; end else FTerminate := True; end; end;

Из листинга 14.9 становится ясно, откуда взялась переменная Handled. Как нетрудно убедиться, метод ProcessMessage вызывается для обнаружения и обработки сообщений, находящихся в очереди. Обнаруженное сообщение удаляется из очереди. Если это сообщение WM_QUIT, переменной FTerminate присваивается значение True; в противном случае Handled присваивается False и вызывается обработчик OnMessage (если он был определен). Если при возвращении из него переменная Handled остается равной False и сообщение не относится к некоторым категориям (сообщения подсказок, сообщения MDI, уведомляющее сообщение от элемента или диалоговое сообщение), для обработки вызываются стандартные процедуры TranslateMessage и DispatchMessage. Очевидно, если переменной Handled в обработчике события OnMessage присвоить значение True, дальнейшая обработка сообщения прекращается. Я хочу заменить одну нажатую клавишу другой и продолжить обработку. Следовательно, значение переменной Handled не должно изменяться.

Мой обработчик OnMessage устроен достаточно просто. Если установлен переключатель Filtered, оператор case отбирает нужные сообщения и заменяет клавиши, при этом для управляющих символов используются константы виртуальных клавиш, определенные в Windows. Следует обратить внимание на один момент: клавиши, нажимаемые в сочетании с Alt, Ctrl и Shift, опознаются в два этапа. Поскольку процедура получает всего одну клавишу, она не знает, какие из управляющих клавиш были при этом нажаты. Мне пришлось отдельно обрабатывать нажатия и отпускания управляющих клавиш. Для этого я ищу константу VK_SHIFT в параметре wParam, передаваемом с сообщениями WM_KEYDOWN и WM_KEYUP, и в случае ее обнаружения — сохраняю информацию о регистре в логической переменной.

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

Конец записи (21 марта).



Содержание раздела