Interface method as event handler

假装没事ソ 提交于 2019-12-23 13:06:43

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!