如何检查两个事件是否指向Delphi中的相同过程?

Kro*_*ica 14 delphi events

假设我有一个Button1.OnClick事件链接到Button1Click程序.我也将Button2.OnClick链接到其他一些程序.如何检查两个事件是否从运行时链接到不同或相同的过程?

我试图测试是否:

  • Button1.OnClick = Button2.OnClick,但这给了我一个错误(实际参数不够)
  • @(Button1.OnClick)= @(Button2.OnClick),再次出错(实际参数不够)

我该如何正确测试?

Nat*_*Nat 29

方法引用可以分为两部分,指向对象的指针和指向方法本身的指针.在System单元中定义了一个方便的记录类型TMethod,允许我们进行分解.

有了这些知识,我们可以写下这样的东西:

function SameMethod(AMethod1, AMethod2: TNotifyEvent): boolean;
begin
  result := (TMethod(AMethod1).Code = TMethod(AMethod2).Code) 
            and (TMethod(AMethod1).Data = TMethod(AMethod2).Data);   
end;
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.:)

编辑:只是以更好的格式布局我想在这里解决的问题(如评论中所提到的).

如果您有两个表单,则从同一个基类实例化:

Form1 := TMyForm.Create(nil);
Form2 := TMyForm.Create(nil);
Run Code Online (Sandbox Code Playgroud)

并将这些表单中的相同方法分配给两个按钮:

Button1.OnClick := Form1.ButtonClick;
Button2.OnClick := Form2.ButtonClick;
Run Code Online (Sandbox Code Playgroud)

并且比较两个OnClick属性,你会发现它Code是相同的,但是Data是不同的.那是因为它是相同的方法,但是在类的两个不同实例中......

现在,如果在同一个对象上有两个方法:

Form1 := TMyForm.Create(nil);

Button1.OnClick := Form1.ButtonClick1;
Button2.OnClick := Form1.ButtonClick2;
Run Code Online (Sandbox Code Playgroud)

然后他们Data将是相同的,但他们Code将是不同的.

  • 如果您有两个从同一个类实例化的对象,它们将具有相同的代码指针,但具有不同的数据指针. (5认同)

Dav*_*nan 18

我用这个功能做到了:

function MethodPointersEqual(const MethodPointer1, MethodPointer2): Boolean;
var
  Method1: System.TMethod absolute MethodPointer1;
  Method2: System.TMethod absolute MethodPointer2;
begin
  Result := (Method1.Code=Method2.Code) and (Method1.Data=Method2.Data)
end;
Run Code Online (Sandbox Code Playgroud)

它的工作原理,但如果有人知道少哈克的方式做到这一点,那么我喜欢听到吧!

  • @Downvoter好的,你怎么做才能证明这是可能的.我不相信它.你已经断言它似乎无法备份. (5认同)
  • 但这仍然是第二个最佳解决方案.最好的解决方案是不要编写需要此检查的代码.:) (4认同)
  • @Downvoter我还在等你的工作代码.你在SO上做的所有事情都是写有毒的评论.如果他们有实质内容,我会更加接受他们. (4认同)
  • @Downvoter如果你想要一个适用于所有方法指针的函数,就不能遵守Typecast规则,就像我一样.并非所有方法都是`TNotifyEvent`.另一方面,也许我错了,如果你能告诉我适用于任意对象方法的代码,那么我会非常高兴. (2认同)
  • @Downvoter我认为这是一个你无法解决这个难题的承认. (2认同)