Einzelnen Beitrag anzeigen

XiaN

Registriert seit: 14. Jul 2006
19 Beiträge
 
Delphi 2009 Professional
 
#3

Re: Event Multicast Problem : Howto "Sender.Methodname&

  Alt 17. Nov 2009, 13:15
Danke für den Stubs in die richtige Richtung Apollonius.

Da es zu Multicast Events in Delphi Win32 so gut wie nichts im Web gibt, poste ich hier mal meine Lösung.

Delphi-Quellcode:
  //
  // TEventHandler Class
  //
  // Note : Class MUST be inherited from TPersistent
  // Note : The procedure "Fire" MUST be published
  //

  TEventHandler = class(TPersistent)
  private

    LEvent: TMethod;
    LOwner: pointer;
    LEventName: string;

    OriginalMethod: TMethod;
    ScriptMethod: TMethod;

  public

    procedure Init(LDataSet: TComponent; Event: string; PMethod: pointer);

    constructor Create;
    destructor Destroy; override;

  published

    procedure Fire(Sender: TObject);

  end;

//
// Eventhandler
//

constructor TEventHandler.Create;
begin

  LEvent.Code := Self.MethodAddress('Fire');
  LEvent.Data := Pointer(Self);

end;

destructor TEventHandler.Destroy;
begin

  SetMethodProp(TObject(LOwner), LEventName, OriginalMethod);

  inherited;

end;

procedure TEventHandler.Init(LDataSet: TComponent; Event: string; PMethod: Pointer);
begin

  LOwner := Pointer(LDataSet);
  LEventName := Event;

  OriginalMethod := GetMethodProp(LDataset, Event);

  ScriptMethod.Code := PMethod;
  ScriptMethod.Data := self;

  SetMethodProp(LDataset, Event, LEvent);

end;

procedure TEventHandler.Fire(Sender: TObject);
begin
  TNotifyEvent(OriginalMethod)(Sender);
  TNotifyEvent(ScriptMethod)(Sender);
end;
Dieses Beispiel funktioniert natürlich nur mit einem Event. Wenn man beliebig viele Events auslösen will, ersetzt man

-> PMethod mit einem "array of pointer"
-> ScriptMethod mit "array of TMethod"
-> Den letzten Teil von "Init" mit einer Schleife die für length(PMethod) das "ScriptMethod" array füllt

Aufruf erfolgt dann wie folgt

Delphi-Quellcode:
var
  DataSetEventHandler: array of TEventHandler;

...

  SetLength(DataSetEventHandler, Length(DataSetEventHandler) + 1);
  DataSetEventHandler[Length(DataSetEventHandler) - 1] := TEventHandler.Create;
  DataSetEventHandler[Length(DataSetEventHandler) - 1].Init(LObject, 'OnChange', LPointer);
-> LObject ist das Objekt, von dem man ein Event hooken möchte
-> Danach folgt der Name des zu hookenden Events
-> LPointer ist hier der Pointer zu einer Methode/Funktion/Procedure die man nach dem org. Event auslösen möchte

Wird nun das gehookte Event ausgelöst, werden automatisch und ohne weiteres zutun das originale und dann das "gehookte" Event nacheinander ausgelöst.

Und nat. brav irgendwo wieder freigeben

Delphi-Quellcode:
  for i := 0 to Length(DataSetEventHandler) - 1 do
  begin
    FreeAndNil(DataSetEventHandler[i]);
  end;
Ich hoffe das hilft so manchem sich die 3-4 Tage suchen in der zu ersparen. Zumal google da ja wirklich nich viel hergibt.
  Mit Zitat antworten Zitat