Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции програм_new_последняя версия1.doc
Скачиваний:
14
Добавлен:
14.09.2019
Размер:
697.34 Кб
Скачать

Делегирование событий

Под делегированием понимается то, что некий объект может предоставить другому объекту отвечать на некоторые события.

Поскольку события - это свойства объекта, их значения можно изменять в любой момент во время выполнения программы. Эта возможность называется делегированием. Можно в лю­бой момент взять способы реакции на события у одного объекта и присвоить (делегировать) их другому:

Object1.OnMouseMove:=Object2.0nMouseMove;

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

Значения событий можно изменять, значит обработчики событий могут меняться.

Какой механизм позволяет подменять обработчики событий, ведь это не просто процедуры, а методы?

Здесь как нельзя кстати используется существующее в Object Pascal понятие указателя на метод. Отличие метода от процедуры состоит в том, что помимо явно описанных параметров в заголовке метода, методу всегда неявно передается еще и указатель на вызвавший его экземпляр; он хранится в переменной Self. Таким образом, можно описать процедурный тип, который будет совместим по присваиванию с методом, т.е. предусмотреть получение Self. Для этого при описании процедурного типа необходимо добавить зарезервированные слова of оbject. Указатель на метод – это указатель на такую процедуру.

Ниже приведен пример задания и использования события OnMyEvent типа TMyEvent, определенного пользователем. Для описания события некоторого процедурного типа TMyEvent в объекте надо описать поле fOnMyEvent того же типа, что и свойство: OnMyEvent:TMyEvent;

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

property OnMyEvent:TMyEvent read fOnMyEvent

write fOnMyEvent;

Тут поле fOnMyEvent является ссылкой на процедуру, с помощью которой осуществляется обработка события. Это поле доступно по чтению и записи! Присваивание свойству значения — это присваивание полю fOnMyEvent указателя на метод, который будет вызываться при на­ступлении события.

Пример делегирования событий:

Тype

//описание процедурного типа:

TMyEvent = procedure(Sender:TObject;var a:integer) of object;

TObj1 = class //описание класса TObj1

fOnMyEvent:TMyEvent; //описание поля класса

property OnMyEvent:TMyEvent //свойство процедурного типа

read fOnMyEvent

write fOnMyEvent;

end;

TObj2 = class //описание класса TObj2

procedure EventProc1(Sender:TObject; var a: integer);

procedure EventProc2(Sender:TObject; var a: integer);

end;

. . . . . .

var Obj1: TObj1 ;

Obj2: TObj2;

begin

Obj1:=TObjl. Create;

Obj2:=TObj2.Create;

Obj1.OnMyEvent:=Obj2. EventProc1;

. . . . . .

Obj1.OnMyEvent:=Obj2. EventProc2;

. . . . . .

end.

Этот пример показывает, что при делегировании можно присваивать методы других классов! Здесь обработчиком события OnMyEvent объекта Obj1 по очереди выступают методы EventProc1 и EventProc2 объекта Obj2.

Но при этом должно быть полное соответствие списков параметров обработчиков событий со списком параметров про­цедурного типа события.