Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Прикладное программирование.doc
Скачиваний:
18
Добавлен:
25.12.2018
Размер:
683.01 Кб
Скачать

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

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

<oбъeкmI>.<coбblmue>'.=:<oбьeкm2>.<coбыmlte>;

Когда необходимость в делегировании события отпадает, то достаточно присвоить (делегировать) событию "пустой" указатель:

<обьект>.<событие>:=!^11;

Принцип делегирования позволяет избежать трудоемкого процесса по­рождения новых дочерних классов для каждого конкретного случая, заменяя его простой подстановкой процедур. Для реализации делегирования как нельзя кстати, подходит введенный в Delphi указатель на метод. Поскольку. помимо явно описанных параметров, методу передается еще и указатель на вызывающий его экземпляр (Self), то можно описать тип процедуру, которая будет совместима по присвоению с методом (т.е. будет предусматривать пе­редачу Self).

Type TAnyEvent=Procedure(Sender: TObject; VarAValue; Integer) Of Object;

TlstClass=Class // Объявление нового класса

FOnMyEvent: TAnyEvent;

Property OnMyEvent: TAnyEvent Read FOnMyEvent Write FOnMyEvent;

End;

T2ndClass=CIass // Класс - носитель методов

Procedure SetValuel(Sender: TObject; Var AValue: Integer);

Procedure SetValue2(Sender; TObject; VarAValue: Integer);

End;

Var Objl: tIstClass;

Obj2: T2ndClass;

Begin

Objl:=TlstClass.Create;

Obj2:=T2ndClass.Create;

Obj 1.0nMyEvent:=Obj2.SetValuel; II Делегирование первого метода

Obj 1.0nMyEnent:=Obj2.SetValue2; It Делегирование второго метода

Obj 1 .OnMyEnent:=Nil; // Отключение всех обработчиков

Напомним, что как в этом примере, так и повсюду в Delphi за свойства­ми-событиями стоят поля, являющиеся указателями на метод. Таким образом, при делегировании этим полям можно присвоить указатели на методы других классов. Главное, они должны быть одного типа.

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

Если внутри таких методов, которые используются несколькими объек­тами, необходимо определить, кто его вызвал, то можно воспользоваться оператором проверки типа Is:

If Sender Is <клас0 Then <onepamop>;

Если объекты относятся к одному классу, то можно использовать свой­ство Tag компонентов, присвоив им различные целочисленные значения и используя приведение типов:

If </cnacc>(Sender).Tag==l Then <onepamop>\

If (Sender As <^acc>).Tag=l Then <onepamop>\

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

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

Var AnyEvent, NameEvent: <mun события>;

Begin

AnyVlVeat'.xs:<oбьeкm>.<coбыmue>•, NameEvent:=<ayKfl метода>;

If@AnyEvent=@NameEvent Then <onepamop>\

Можно получить адрес и имя метода следующим простым способом:

Var AnyEvent: <mun события>;

Begin

AnyEvent:=<o6'beKm>.<co6btmue>',

Labell.Caption:=MethodName(@AnyEvent); // Имя метода Label2.Caption:=Format('%p', [@AnyEvent]); // Адрес метода