接口方法作为事件处理程序 [英] Interface method as event handler

查看:180
本文介绍了接口方法作为事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

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

Adding @ or Addr changes the error to E2036 (variable required).

更新:

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。

works. However I'm not too fond of the magic 3 in there.

推荐答案

一个更清洁的解决方案是实现IInterfaceComponentReference,或类似的东西对于你的基类,并使用它来获取类ref。

A cleaner solution is to implement IInterfaceComponentReference, or something similar for your base class, and uses that to get the class ref.

上面的代码将不会在例如FPC等兼容性。他们的VMT结构略有不同。即使在Delphi上,未来的语言扩展可能会导致这种情况。

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.

完美的解决方案是为这个完全独立的接口methodvar类型,但是我不知道是值得的。

A perfect solution would be to have a completely separate "interface" methodvar type for this, but I wonder if that is worth the trouble.

这篇关于接口方法作为事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆