14 Stimmen

Delphi VCL für Win32 - mehrere Ereignisbehandler

Ich bin auf der Suche nach einem Code, der es ermöglicht, einem einzigen Ereignis eines Objekts mehrere Event-Handler zuzuweisen... Ich brauchte es sehr viel für meine Plugin-Architektur, so dass ich einige Ersatz für das implementiert, aber ich mag nicht meine Lösung für das, so würde ich gerne wissen, was ist Ihre Idee/Lösung/Tipp ... Meine Lösung ist einfach eine Liste mit Elementen wie eventName: string; proc: TMyEventProc; wobei TMyEventProc zwei Argumente entgegennimmt, Absender und eventData: Zeiger. Je nach Name des Ereignisses zeigt eventData auf einen anderen Datensatz / ein anderes Objekt.

Leider erfordert dies die Deklaration von vielen, vielen Datensätzen, die als Argument übergeben werden. Die Methode ist außerdem sehr langsam und erfordert die Implementierung des Aufrufs der erforderlichen "Callbacks", während das "echte" Ereignis ausgelöst wird.

11voto

Deltics Punkte 21121

Ich habe eine Lösung für dieses Problem implementiert, die in so gut wie jeder Version von Delphi funktioniert - sie wurde ursprünglich in Delphi 7 implementiert, obwohl ich sie nicht in früheren Versionen getestet habe (aber wenn Sie selbst Delphi 7 verwenden, dann ist das alles, was Sie wissen müssen, nicht wahr?) :)

iirc war dies zumindest teilweise die Inspiration für Allen Bauers Beitrag. Sie können meine Implementierung in einigen Videos sehen und den Code herunterladen aus meinem Blog :

Die Beiträge, die Sie interessieren, sind mit "Multicast" gekennzeichnet. Der Download-Link für den endgültigen Code lautet verfügbar in dieser Stelle .

Bei meinem Ansatz leiten Sie eine Klasse von TMultiCastEvent ab. Ihre abgeleitete Klasse muss lediglich einen einfachen Typsicherheitsschutz für das Hinzufügen, Entfernen und Aufrufen eines Ereignisses mit einer bestimmten Signatur implementieren.

Eine Implementierung für TNotifyEvent - procedure(Sender: TObject) - wird zusammen mit der Implementierung zur Verfügung gestellt, sowohl "um Sie in Gang zu bringen" (die meisten "nützlichen" Multicast-Ereignisse sind einfache Benachrichtigungen) als auch als Beispiel dafür, wie man Multicast-Ereignisklassen für bestimmte Ereignissignaturen ableiten kann.

Sobald Sie Ihre Multicast-Ereignisklasse haben, können Sie reguläre "Event-Handler" austauschbar mit der Multicast-Version verwenden, z.B. bei einer imaginären Schaltflächenklasse mit einem Multicast-On_Click-Ereignis (ich habe die Konvention übernommen, einen Unterstrich in den Ereignisnamen einzufügen, um ihn als Multicast zu kennzeichnen, im Gegensatz zu regulären "Unicast"-Ereignissen):

Code, der einem Unicast-Klickereignis einen Handler zuweist:

  Button.OnClick := MyClickHandler;

Sie können denselben Handler direkt zu einem mehrfach gesendeten Benachrichtigungsereignis hinzufügen:

  MultiCastButton.On_Click.Add(MyClickHandler);

Meine Implementierung enthält auch eine Reihe von Verfeinerungen, wie z. B. die Möglichkeit, Ereignisse zu deaktivieren und Handler automatisch aus Handlern zu entfernen, wenn das implementierende Objekt zerstört wird (dies beinhaltet eine kleine Menge an Hausarbeit, die bei Bedarf ignoriert werden kann, die aber unter bestimmten Umständen nützlich sein kann).

All dies wird in meinen Blogbeiträgen beschrieben und demonstriert.

Genießen Sie. :)

2voto

Mason Wheeler Punkte 79858

Allen Bauer hat ein Blogbeitrag über Multicast-Ereignisse die hilfreich sein könnten. Es funktioniert allerdings nur für Delphi 2009 oder später.

EDIT: Wenn Sie immer noch auf D7 sind, können Sie vielleicht immer noch in der Lage sein, dies zu tun, wenn Sie nicht zu viele verschiedene Ereignis-Signaturen benötigen. Versuchen Sie, Allen's Code und sehen, ob Sie es zu einer nicht-generischen Lösung anpassen können.

1voto

utku_karatas Punkte 5798

Wenn man ein Plugin-System implementiert, kann man meiner Meinung nach nicht einfach mit Event-Handlern auskommen - egal ob Multicast oder nicht. Ich schlage vor, einen Blick zu werfen auf Beobachtungsmuster . Das mag bei Multicast-Ereignissen etwas zu langatmig klingen, aber zumindest ist es flexibler, wenn Sie es brauchen.

0voto

Hierfür können Sie das Beobachterentwurfsmuster verwenden. Hier ist ein Beispiel einer Delphi-Implementierung: http://blogs.teamb.com/joannacarter/2004/06/30/690

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X