【问题标题】:Interface method as event handler接口方法作为事件处理程序
【发布时间】:2010-08-06 08:34:08
【问题描述】:

是否可以在 Delphi 2007 中使用接口方法作为事件处理程序?简单版本不起作用:

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.

添加 @Addr 会将错误更改为 E2036(需要变量)。

更新:这个

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.

有效。不过我不太喜欢里面的魔法3。

【问题讨论】:

标签: delphi interface delphi-2007 event-handling


【解决方案1】:

更简洁的解决方案是为您的基类实现 IInterfaceComponentReference 或类似的东西,并使用它来获取类引用。

上述代码不适用于例如FPC 和其他兼容设备。它们的 VMT 结构略有不同。甚至在 Delphi 上,未来的语言扩展也可能导致这种情况。

一个完美的解决方案是为此使用一个完全独立的“接口”方法变量类型,但我想知道这是否值得。

【讨论】:

  • 听起来很合理。也许我会将其修改为 GetHandler 方法而不是 GetSelf。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多