2010-08-06 5 views
4

Est-il possible d'utiliser la méthode d'interface en tant que gestionnaire d'événements dans Delphi 2007? Les versions simples ne fonctionnent pas:Méthode d'interface en tant que gestionnaire d'événements

type 
    TMyEvent = procedure of object; 

    IMyInterface = interface 
    procedure Handler; 
    end; 

    TMyClass = class(TInterfacedObject, IMyInterface) 
    public 
    procedure Handler; 
    end; 

var 
    ev: TMyEvent; 
    obj: TMyClass; 
    intf: IMyInterface; 
begin 
    obj := TMyClass.Create; 
    intf := obj; 
    ev := obj.Handler; // compiles 
    ev := intf.Handler; // <== Error E2010 (incompatible types) 
end. 

Ajout @ ou Addr change l'erreur E2036 (variable requise).

Mise à jour: Ce

procedure IntRefToMethPtr(const IntRef; var MethPtr; MethNo: Integer); 
type 
    TVtable = array[0..999] of Pointer; 
    PVtable = ^TVtable; 
    PPVtable = ^PVtable; 
begin 
    //QI=0, AddRef=1, Release=2, etc 
    TMethod(MethPtr).Code := PPVtable(IntRef)^^[MethNo]; 
    TMethod(MethPtr).Data := Pointer(IntRef); 
end; 

var 
    ev: TMyEvent; 
    intf: IMyInterface; 
begin 
    intf := TMyClass.Create; 
    IntRefToMethPtr(intf, ev, 3); 
    ev; 
end. 

œuvres. Cependant, je ne suis pas trop friands de la magie 3 là-bas.

+0

Juste après avoir posté ceci j'ai trouvé http://blog.barrkel.com/2010/01/using-anonymous-methods-in-method.html et http://sergworks.wordpress.com/2010/07/06/delphi-interfaces-on-binary-level/qui semblent prometteurs. –

Répondre

2

Une solution plus propre consiste à implémenter IInterfaceComponentReference, ou quelque chose de similaire pour votre classe de base, et l'utilise pour obtenir la classe ref.

Le code ci-dessus ne fonctionnera pas par ex. FPC et autres compatibles. Leur structure VMT est légèrement différente. Et même sur Delphi, une future extension de langage pourrait provoquer cela.

Une solution parfaite serait d'avoir un type de méthode "interface" complètement séparé pour cela, mais je me demande si cela en vaut la peine.

+0

Cela semble raisonnable. Peut-être que je vais modifier cela à une méthode GetHandler au lieu d'un GetSelf. Merci! –

Questions connexes