问题
Is it possible to use interface method as event handlers in Delphi 2007? The simple versions don't work:
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.
Adding @
or Addr
changes the error to E2036 (variable required).
Update: This
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.
works. However I'm not too fond of the magic 3 in there.
回答1:
A cleaner solution is to implement IInterfaceComponentReference, or something similar for your base class, and uses that to get the class ref.
The above code will not work on e.g. FPC and other compatibles. Their VMT structure is slightly different. And even on Delphi a future language extension might cause this.
A perfect solution would be to have a completely separate "interface" methodvar type for this, but I wonder if that is worth the trouble.
来源:https://stackoverflow.com/questions/3422142/interface-method-as-event-handler