Ereignisse (Delphi)
Nach oben zu Klassen und Objekte - Index
Dieses Thema enthält Informationen zu folgenden Bereichen:
- Ereigniseigenschaften und Ereignisbehandlungsroutinen
- Mehrere Ereignisbehandlungsroutinen auslösen
Inhaltsverzeichnis
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.