![]() |
Auf Interface basierende MultiCastEvents
Liste der Anhänge anzeigen (Anzahl: 1)
.
Warum MultiEvents? Die nativen Events in Delphi haben zwei große Nachteile:
Außerdem nutzen die MultiEvents geschickt die in D2009+ eingeführten GenericsInhalt
1. Interfaces als Ausgangspunkt 1 zu 1 Verbindung Ganz ohne das alt bekannte procedure ... of object Gerüst geht es nicht. Zusätzlich wird ein EventHandler Interface definiert.
Delphi-Quellcode:
Aus diesen beiden "Bauteilen" entsteht die TINotifyEventHandler Klasse, die das zuvor definierte Interface implementiert. Dies ist eine Art Wrapper für die TNotifyMethod.
TNotifyMethod = procedure(const Sender: IUnknown) of object;
INotifyEventHandler = interface(IUnknown) ['{EE9407DD-2337-4DFC-BC35-A40C4FA0A1A7}'] procedure Invoke(const Sender: IUnknown); safecall; end;
Delphi-Quellcode:
1 zu N Verbindung
TINotifyEventHandler = class(TGenericEventHandler<TNotifyMethod>, INotifyEventHandler)
public procedure Invoke(const Sender: IUnknown); safecall; end; Hat man erstmal einen EventHandler definiert kann man daraus nun ein entsprechendes MultiEvent erstellen. Über Add, Remove können dann Instanzen des INotifyEventHandlers hinzugefügt und wieder entfernt werden. Mit Invoke ruft man das Event auf. Somit werden alle Events die in dem MultiEvent registriert sind benachrichtigt.
Delphi-Quellcode:
Für die Implementierung reicht es eine for-Schleife in der Invoke-Methode zu tippen:
INotifyEvent = interface(IUnknown)
['{14551B63-78C4-4A70-9E54-7656CEF4D6A7}'] procedure Add(const AHandler: INotifyEventHandler); safecall; procedure Remove(const AHandler: INotifyEventHandler); safecall; procedure Invoke(const Sender: IUnknown); safecall; end;
Delphi-Quellcode:
TINotifyEvent = class(TGenericEvent<INotifyEventHandler>, INotifyEvent)
public procedure Invoke(const Sender: IUnknown); safecall; end; 2. Einfache Benutzung Event-Auslöser Betrachtung In der Klasse in der ein MultiEvent eingesetzt werden soll wird eine lokale Variable
Delphi-Quellcode:
definiert. Außerdem muss für den Zugriff von außen gesorgt werden - am Besten durch eine property und einen getter.
FNotifyEvent: INotifyEvent;
Die Erstellung, ein Aufruf und die Zerstörung ist so einfach wie es nur sein kann:
Delphi-Quellcode:
// Im constructor der Klasse
FNotifyEvent := TINotifyEvent.Create; // button1 von Typ TButton // Eine Event Nachricht/Aufruf sieht das bspw. so aus NotifyEvent.Invoke(button1); // Im destructor der Klasse FNotifyEvent := nil; Event-Zuhörer Betrachtung Die Klasse die sich beim MultiEvent registiert. Wie schon erwähnt benötigt diese Zugriff auf das MultiEvent (hier: Main.NotifyEvent).
Delphi-Quellcode:
TOtherForm = class(TForm)
// [...] private FNotifyEventHandler: INotifyEventHandler; protected // Diese Methode wird dann aufgerufen procedure OnNotify(const Sender: IUnknown); // [...] // Im constructor der Klasse FNotifyEventHandler := TINotifyEventHandler.Create(OnNotify); Main.NotifyEvent.Add(FNotifyEventHandler); // Im destructor der Klasse Main.NotifyEvent.Remove(FNotifyEventHandler); FNotifyEventHandler := nil; 3. Quellcodeminimierung durch Generics TGenericEventHandler Klasse
Delphi-Quellcode:
TGenericEvent Klasse
TGenericEventHandler<T: constructor> = class abstract(TInterfacedObject)
protected FHandler: T; public constructor Create(AEventHandler: T); property EventHandler: T read FHandler write FHandler; destructor Destroy; override; end;
Delphi-Quellcode:
TGenericEvent<T: IUnknown> = class abstract(TInterfacedObject)
private FMethods: TList<T>; protected property Methods: TList<T>read FMethods; public constructor Create; virtual; procedure Add(const AHandler: T); safecall; procedure Remove(const AHandler: T); safecall; destructor Destroy; override; end; 4. Verweise Die Arbeit von ![]() Ähnliche Ansätze ![]() ![]() Im Anhang befindet sich der komplette Quellcode und ein kleines Beispiel. Die Events lassen sich natürlich nach eigenen Wünschen beliebig anpassen und unter Verwendung der generischen Klassen, sollte sich die Tipparbeit in Grenzen halten. Viel Spaß damit. . |
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz