четверг, 3 мая 2012 г.

События

Перевод из справочной системы Delphi. Оригинал: Events

О Событиях

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


События-свойства и обработчики событий

Компоненты, которые разработаны в Delphi, используют свойства для указания обработчика события, который должен быть выполнен в определенном случае. По договоренности имя события-свойства начинается с "On", а свойство реализуется полем, а не методами чтения/записи. Значение, хранящееся в свойстве – это указатель на метод, ссылающийся на процедуру-обработчик события.

В следующем примере класс TObservedObject включает в себя объявление события OnPing, которое имеет тип TPingEvent. Поле FOnPing используется для хранения обработчика события. Обработчик события в этом примере - TListener.Ping, выводит надпись 'TListener has been pinged!'.

 program EventDemo;
 
 {$APPTYPE CONSOLE}
 type
   { Объявление процедурного типа }
   TPingEvent = procedure of object;
 
   { "Изучаемый" объект }
   TObservedObject = class
   private
     FPing: TPingEvent;
 
   public
     property OnPing: TPingEvent read FPing write FPing;
 
     { Запуск события, если что-либо зарегистрировано }
     procedure TriggerEvent();
   end;
 
   { Класс-слушатель }
   TListener = class
     procedure Ping;
   end;
 
 
 procedure TObservedObject.TriggerEvent;
 begin
   { вызов зарегистрированного события только если существует слушатель }
   if Assigned(FPing) then
     FPing();
 end;
 
 procedure TListener.Ping;
 begin
   Writeln('TListener has been pinged.');
 end;
 
 var
   ObservedObject: TObservedObject;
   Listener: TListener;
 
 begin
   { Создание экземпляров объектов }
   ObservedObject := TObservedObject.Create();
   Listener := TListener.Create();
 
   { Регистрация обработчика события}
   ObservedObject.OnPing := Listener.Ping;
 
   { Запуск события }
   ObservedObject.TriggerEvent();//выведет  'TListener has been pinged'
   Readln;                       // пауза консоли перед завершением
 end.


Запуск нескольких обработчиков событий

В Delphi для Win32 с событием может быть связан только один обработчик. Если несколько обработчиков должны быть запущены для реакции на событие, связанный с событием обработчик должен выполнить вызов остальных обработчиков. В следующем примере класс, порожденный от TListener, с именем TListenerSubclass имеет собственный обработчик события с именем Ping2. Обработчик события Ping2 должен явно вызвать обработчик TListener.Ping для того, чтобы он среагировал на событие OnPing:

 program EventDemo2;
 
 {$APPTYPE CONSOLE}
 
 type
   { Объявление процедурного типа }
   TPingEvent = procedure of object;
 
   { "Изучаемый" объект }
   TObservedObject = class
   private
     FPing: TPingEvent;
 
   public
     property OnPing: TPingEvent read FPing write FPing;
 
     { запуск события, если что-либо зарегистрировано }
     procedure TriggerEvent();
   end;
 
   { Класс-слушатель }
   TListener = class
     procedure Ping;
   end;
 
   { Потомок класса-слушателя }
   TListenerSubclass = class(TListener)
     procedure Ping2;
   end;
 
 procedure TObservedObject.TriggerEvent;
 begin
   { вызов зарегистрированного события только если существует слушатель }
   if Assigned(FPing) then
     FPing();
 end;
 
 procedure TListener.Ping;
 begin
   Writeln('TListener has been pinged.');
 end;
 
 procedure TListenerSubclass.Ping2;
 begin
   { Вызов метода базового класса }
   Self.Ping();
   Writeln('TListenerSubclass has been pinged.');
 end;
 
 var
   ObservedObject: TObservedObject;
   Listener: TListenerSubclass;
 
 begin
   { Создание экземпляров объектов }
   ObservedObject := TObservedObject.Create();
   Listener := TListenerSubclass.Create();
 
   { Регистрация обработчика события }
   ObservedObject.OnPing := Listener.Ping2;
 
   { Запуск события }
   ObservedObject.TriggerEvent();//выведет 'TListener has been pinged'
                              //затем 'TListenerSubclass has been pinged'
   Readln;                    // пауза консоли перед завершением

Комментариев нет:

Отправить комментарий