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