Ereignisse (Delphi)

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Klassen und Objekte - Index


Dieses Thema enthält Informationen zu folgenden Bereichen:

  • Ereigniseigenschaften und Ereignisbehandlungsroutinen
  • Mehrere Ereignisbehandlungsroutinen auslösen

Allgemeines zu Ereignissen

Ein Ereignis verknüpft ein Vorkommnis im System mit dem Quelltext, der auf dieses Vorkommnis antwortet. Das Vorkommnis löst die Ausführung einer Prozedur, Ereignisbehandlungsroutine genannt, aus. Die Ereignisbehandlungsroutine führt die Aufgaben aus, die als Antwort auf das Vorkommnis erforderlich sind. Ereignisse ermöglichen die Anpassung des Verhaltens einer Komponente während des Entwurfs oder zur Laufzeit. Zum Ändern des Verhaltens einer Komponente ersetzen Sie die Ereignisbehandlungsroutine durch eine eigene Ereignisbehandlungsroutine, die das gewünschte Verhalten enthält.

Ereigniseigenschaften und Ereignisbehandlungsroutinen

Komponenten, die in Delphi geschrieben sind, verwenden Eigenschaften zur Festlegung der Ereignisbehandlungsroutine, die ausgeführt werden soll, wenn das Ereignis eintritt. Per Konvention beginnt der Name einer Ereigniseigenschaft mit "On", und die Eigenschaft wird mit einem Feld anstelle von Lesen-/Schreibenmethoden implementiert. Der von der Eigenschaft gespeicherte Wert ist ein Methodenzeiger, der auf die Ereignisbehandlungsroutine zeigt.

Im folgenden Beispiel beinhaltet die Klasse TObservedObject ein OnPing-Ereignis des Typs TPingEvent. Im Feld FOnPing wird die Ereignisbehandlungsroutine gespeichert. Die Ereignisbehandlungsroutine TListener.Ping dieses Beispiels gibt 'TListener has been pinged!' aus.

 program EventDemo;
 
 {$APPTYPE CONSOLE}
 type
   { Prozeduralen Typ definieren }
   TPingEvent = procedure of object;
 
   { Das überwachte Objekt }
   TObservedObject = class
   private
     FPing: TPingEvent;
 
   public
     property OnPing: TPingEvent read FPing write FPing;
 
     { Löst das Ereignis aus, wenn etwas registriert ist }
     procedure TriggerEvent();
   end;
 
   { Der Empfänger }
   TListener = class
     procedure Ping;
   end;
 
 
 procedure TObservedObject.TriggerEvent;
 begin
   { Das registrierte Ereignis nur aufrufen, wenn ein Empfänger vorhanden ist }
   if Assigned(FPing) then
     FPing();
 end;
 
 procedure TListener.Ping;
 begin
   WriteLn('TListener has been pinged.');
 end;
 
 var
   ObservedObject: TObservedObject;
   Listener: TListener;
 
 begin
   { Objektinstanzen erstellen }
   ObservedObject := TObservedObject.Create();
   Listener := TListener.Create();
 
   { Ereignisbehandlungsroutine registrieren }
   ObservedObject.OnPing := Listener.Ping;
 
   { Das Ereignis auslösen }
   ObservedObject.TriggerEvent(); // Soll 'TListener has been pinged.' ausgeben
   ReadLn;                        // Vor dem Schließen Konsole auf Pause setzen
 end.

Mehrere Ereignisbehandlungsroutinen auslösen

In Delphi für Win32 können Ereignisse nur einer einzigen Ereignisbehandlungsroutine zugeordnet werden. Wenn mehrere Ereignisbehandlungsroutinen als Reaktion auf ein Ereignis ausgeführt werden müssen, muss die dem Ereignis zugeordnete Ereignisbehandlungsroutine alle weiteren Ereignisbehandlungsroutinen aufrufen. Im folgenden Quelltext hat eine Unterklasse von TListener, TListenerSubclass, ihre eigene Ereignisbehandlungsroutine namens Ping2. In diesem Beispiel muss die Ereignisbehandlungsroutine Ping2 die Ereignisbehandlungsroutine TListener.Ping explizit aufrufen, um sie als Reaktion auf das Ereignis OnPing auszulösen.

 program EventDemo2;
 
 {$APPTYPE CONSOLE}
 
 type
   { Prozeduralen Typ definieren }
   TPingEvent = procedure of object;
 
   { Das überwachte Objekt }
   TObservedObject = class
   private
     FPing: TPingEvent;
 
   public
     property OnPing: TPingEvent read FPing write FPing;
 
     { Löst das Ereignis aus, wenn etwas registriert ist }
     procedure TriggerEvent();
   end;
 
   { Der Empfänger }
   TListener = class
     procedure Ping;
   end;
 
   { Die Unterklasse von Listener }
   TListenerSubclass = class (TListener)
     procedure Ping2;
   end;
 
 procedure TObservedObject.TriggerEvent;
 begin
   { Das registrierte Ereignis nur aufrufen, wenn ein Empfänger vorhanden ist }
   if Assigned(FPing) then
     FPing();
 end;
 
 procedure TListener.Ping;
 begin
   WriteLn('TListener has been pinged.');
 end;
 
 procedure TListenerSubclass.Ping2;
 begin
   { Die Basisklasse ping aufrufen }
   Self.Ping();
   WriteLn('TListenerSubclass has been pinged.');
 end;
 
 var
   ObservedObject: TObservedObject;
   Listener: TListenerSubclass;
 
 begin
   { Objektinstanzen erstellen }
   ObservedObject := TObservedObject.Create();
   Listener := TListenerSubclass.Create();
 
   { Ereignisbehandlungsroutine registrieren }
   ObservedObject.OnPing := Listener.Ping2;
 
   { Das Ereignis auslösen }
   ObservedObject.TriggerEvent(); // Soll 'TListener has been pinged.' ausgeben
                                  // und dann 'TListenerSubclass has been pinged.'
   ReadLn;                        // Vor dem Schließen Konsole auf Pause setzen
 end.

Siehe auch