IfAssigned(FOnMouseMove) Then FOnMouseMove(Self, Shift, X, Y);

End;

Могут встречаться случаи, когда потребуется необходимость подавления реакции на те или иные действия, например:

• IfAssigned(OnKeyPress) Then OnKeyPress(Self, Key);

• If Key о #0Then <onepamop>;

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

If Assigned(OnClick) Then OnClick(Self) Else <onepamop>;

Рассмотрим пример объявления пользовательского события. Создадим компонент-потомок от TMemo, позволяющий выводить в дополнительном компоненте Label 1 номер строки при перемещении по ним с помощью кла­виш Up и Down.

• Первоначально объявляем указатель на метод и новый класс.

Type

TNumStrEvent=Procedure(Sender: TObject; Num: Integer) Of Object; // Указатель TNumMemo=Class(TMemo) // Объявление нового класса Private

FOnNumStr: TNumStrEvent; // Поле для события FNumStr; Integer; // Поле свойства Protected

Procedure DoNumStr(Num: Integer); Dynamic; // Корреспондирующий метод Public

Property NumStr: Integer Read FNumStr Write FNumStr; // Свойство Property OnNumStr: TNumStrEvent Read FOnNumStr Write FOnNumStr;

End;

Поле FNumStr и свойство NumStr введены для хранения номера текущей строки.

• Поскольку создать обработчик компонента объявленного класса не­возможно, поэтому объявим однотипным метод в классе TFormI, а затем де­легируем его нашему новому компоненту.

TForm' <:lass(TForm) Labell: TLabel;

Procedure FormCreate(Sender: TObject);

Procedure FormKeyDown(Sender: TObject; Var Key: Word;

Shift: TShiftState);

Public

NumMemo: TNumMemo; // Переменная типа класса Procedure EventNumStr(Sender: TObject; Num: Integer); // Обработчик End;

• Реализации корреспондирующего метода и метода EventNumStr могут иметь следующий вид:

Procedure TNumMemo.DoNumStr(Num; Integer);

Begin

IfAssigned(FOnNumStr) Then FOnNumStr(Self, Num); II Вызов обработчика End;

Procedure TForml.EventNumStr(Sender: TObject; Num: Integer);

Begin

NumMemo.NumStr:=NumMemo.NumStr+Num; // Определение номера строки

Labell.Caption:=IntToStr(NumMemo.NumStr); // Вывод номера строки End;

• Инициализацию компонента класса TNumMemo выполним с помощью виртуального конструктора, код которого разместим в событии OnCreate формы.

Procedure TForml.FormCreate(Sender: TObject);

Begin

NumMemo:=TNumMemo.Create(Self); // Инициализация компонента With NumMemo Do Begin Parent:=Self;

SetBounds(10,10,150,150); 11Размер и расположение Name:='NumMemo';

FNumStr:=l; // Начальное значение номера строки Visible:=True;

OnNumStr:=EventNumStr; II Делегирование события End;

Forml.KeyPreview;=True; II Для доступа к кодам клавиш End;

• С помощью события OnKeyDown формы обеспечим "отлавливание" кодов клавиш Up (VK_UP) и Down (VKJDOWN) и вызов корреспондирую­щего метода события объявленного класса TNumMemo. Ввод каждой новой строки увеличивает число строк в компоненте NumMemo и номер текущей строки после нажатия клавиши Enter (VK_RETURN).

Procedure TForml.FormKeyDown(Sender: TObject; Var Key: Word;

Shift: TShiftState);

Begin

Case Key Of

VK_DOWN: If NumMemo.NumStr<NumMemo.Lines.Count+l

Then NumMemo.DoNumStr(l);

VK_UP: IfNumMemo.NumStr>l Then NumMemo.DoNumStr(-l);

VK_RETURN: NumMemo.DoNumStr(l);

End;

End;

После запуска программы и ввода нескольких строк следует поочередно нажать клавиши Up и Down. Компонент Labell будет отображать номер те­кущей строки. Если в виртуальном конструкторе убрать строку OnNumStr:=EventNumStr, то вся работа нарушается. Это означает, что работа­ет именно делегированный обработчик.

г) Использование методов сообщений.

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

Const WM_USER1=WM_APP; // Идентификатор номера сообщения Type

TNumMemo=Class(TMemo) Protected

II Дополнительно объявляем метод сообщения Procedure WMNumStr(Var Msg: TMessage); Message WM_USER1;

Реализация метода сообщения может быть очень проста:

Procedure TNumMemo.WMNumStr(Var Msg: TMessage);

Begin