应恢弘之约,写了一个对其发布的匿名函数动态绑定到事件的封装,代码如下:



type TAnonEvent=class public class function Wrap<T1,T2>(OnEvent:T1):T2; end; { TAnonEvent } class function TAnonEvent.Wrap<T1,T2>(OnEvent: T1):T2; var Addr:Pointer; AMethod:PMethod; begin Addr:=PPointer(@OnEvent)^; AMethod:=@Result; AMethod.Code:=PPointer(IntPtr(PPointer(Addr)^)+SizeOf(Pointer)*3)^;//QueryInterface/AddRef/Release/Invoke AMethod.Data:=Pointer(Addr); end; type TNotifyEventA=reference to procedure(ASender:TObject); procedure TForm3.Button1Click(Sender: TObject); begin Button2.OnClick:=TAnonEvent.Wrap<TNotifyEventA,TNotifyEvent>(procedure (sender: tObject) begin Button2.Caption:=DateTimeToStr(Now); ShowMessage('OK'); end); Button2.OnClick(Sender); end;




1


2


3


4


5


6


7


8


9


10


11


12


13


14


15


16


17


18


19


20


21


22


23


24


25


26


27


28




type


  TAnonEvent=class


  public


    class function Wrap<T1,T2>(OnEvent:T1):T2;


  end;


{ TAnonEvent }


class function TAnonEvent.Wrap<T1,T2>(OnEvent: T1):T2;


var


  Addr:Pointer;


  AMethod:PMethod;


begin


Addr:=PPointer(@OnEvent)^;


AMethod:=@Result;


AMethod.Code:=PPointer(IntPtr(PPointer(Addr)^)+SizeOf(Pointer)*3)^;//QueryInterface/AddRef/Release/Invoke


AMethod.Data:=Pointer(Addr);


end;


 


type


  TNotifyEventA=reference to procedure(ASender:TObject);


procedure TForm3.Button1Click(Sender: TObject);


begin


Button2.OnClick:=TAnonEvent.Wrap<TNotifyEventA,TNotifyEvent>(procedure (sender: tObject)


     begin


      Button2.Caption:=DateTimeToStr(Now);


       ShowMessage('OK');


     end);


Button2.OnClick(Sender);


end;



【注意】

由于匿名函数中,我将TMethod.Data指向了匿名函数对应的接口对象,所以在匿名函数中,不要使用Self来代表当前对象。如果非要使用的话,那么自己修改下Wrap的代码,将AMethod.Data:=Pointer(Addr)改为指向当前函数所隶属对象的Self即可。