Библиотека программиста

«Любой дурак может написать программу, которую поймет компилятор. Хорошие программисты пишут программы, которые смогут понять другие программисты»

Мартин Фаулер

Главная страница > Язык Object Pascal > 28. Обработчики сообщений

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

Обработчики сообщений(message handlers) являются методами, которые выполняют обработку динамически поступающих сообщений. Библиотека VCL использует обработчики сообщений для ответов на сообщения Windows.

Формат обработчика сообщений.

Обработчик сообщений – это (динамический) метод, в заголовок которого добавляется директива message, сопровождаемая идентификатором сообщения. Идентификатор сообщения должен быть целочисленной константой со значением из диапазона 1..49151 или константой вида WM_XXX, например, WM_MOUSEMOVE. Кроме того, константы сообщений Delphi могут начинаться и с других (первых) символов.

Номера сообщений до 1024 ($400) используются Windows, и, следовательно, их нельзя использовать для идентификации собственных сообщений. Номера свыше 1024 можно использовать для идентификации собственных сообщений. Константы сообщений, используемые Windows и Delphi, описаны в модуле Messages, исходный текст которого поставляется с Delphi (каталог ..\Delphi\Source\Rtl\Win). Кроме того, Windows использует некоторые с номерами более 1024, поэтому перед выбором номера для своего собственного сообщения надо просмотреть Messages. В модуле Messages описана также константа WM_USER=1024, которой надо пользоваться для назначения номера собственному сообщению.

Пример описания метода обработки сообщения:

type

TTextBox = class(TCustomControl)

private

procedure MyMouseHandler (var Message: TWMMOUSE); message WM_MOUSEMOVE;

. . .

end;

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

Разработка обработчиков сообщений (Implementing message handlers).

Реализация обработчика сообщений может, и, как правило, должна включать вызов унаследованного обработчика, как в следующем примере:

procedure MyMouseHandler (var Message: TWMMOUSE);

begin

// собственный код

inherited;

end;

Оператор inherited выполняет поиск в иерархии класса первого попавшегося обработчика с тем же идентификатором, как и текущий метод, и автоматически передает ему сообщение (запись record). Если такой обработчик не будет найден в иерархии класса, то будет вызван обработчик по умолчанию, определенный в TObject. Обработчик по умолчанию DefaultHandler ничего не делает, а просто возвращает управление. Обработчик по умолчанию DefaultHandler для управляющих элементов VCL (controls) вызывает функцию DefWindowProc Windows.

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

TWMMouse = record

Msg: Cardinal; // стандартное начало – идентификатор сообщения

Keys: Longint;

case Integer of

0: ( XPos: Smallint; YPos: Smallint);

1: ( Pos: TSmallPoint; Result: Longint);

end;

Из справочной системы Delphi 6.0.

TWMMouse = record

Msg: TMsgParam; ( first is the message ID )

Keys: Word; ( this is the wParam )

case Integer of ( two ways to look at the lParam )

0: {

XPos: Integer; ( either as x- and y-coordinates...)

YPos: Integer);

1: {

Pos: TPoint; ( ... or as a single point )

Result: Longint); ( and finally, the result field )

end;

Диспетчеризация сообщений (мessage dispatching).

Обработчики сообщений обычно вызываются косвенным образом, а не непосредственно. Для диспетчеризации (отправки) сообщений используется метод Dispatch, унаследованный от TObject и имеющий такой заголовок:

procedure Dispatch(var Message);

Параметр Message должен быть записью такого же формата, как и для обработчика сообщений.

Этот метод является статическим, при необходимости его можно перекрыть, просто описав свой метод с таким же именем. В реализации своего метода надо предусмотреть вызов унаследованного метода.

Обработка сообщений компонентами, сгенерированными на этапе выполнения приложения.

Для обработки стандартного сообщения компонентом, созданным на этапе выполнения, необходимо описать соответствующий метод в каком-либо классе и затем "привязать" к требуемому свойству. Например, если мы создали кнопку, то для обработки события OnClick для нее надо описать в классе метод с единственным параметром TObject, т.е. имеющий тип

type TNotifyEvent = procedure (Sender: TObject) of object;

и присвоить его имя свойству OnClick для кнопки

RunTimeButton.OnClick:=MyClickHandler;





<< Предыдущая статья
«27. Введение в обработку сообщений»
Следующая статья >>
29. Свойства