假设我有一个Button1.OnClick事件链接到Button1Click程序。我也将Button2.OnClick链接到其他一些程序。如何检查两个事件是否与运行时的不同或相同过程相关联?
我试图测试是否:
如何正确测试?
答案 0 :(得分:29)
方法引用可以分为两部分,指向对象的指针和指向方法本身的指针。在名为System
的{{1}}单元中定义了一种方便的记录类型,允许我们进行分解。
有了这些知识,我们可以这样写:
TMethod
希望这会有所帮助。 :)
修改:只是以更好的格式布局我想在这里解决的问题(正如评论中所提到的那样)。
如果您有两个表单,则从同一个基类实例化:
function SameMethod(AMethod1, AMethod2: TNotifyEvent): boolean;
begin
result := (TMethod(AMethod1).Code = TMethod(AMethod2).Code)
and (TMethod(AMethod1).Data = TMethod(AMethod2).Data);
end;
并将这些表单中的相同方法分配给两个按钮:
Form1 := TMyForm.Create(nil);
Form2 := TMyForm.Create(nil);
并比较两个Button1.OnClick := Form1.ButtonClick;
Button2.OnClick := Form2.ButtonClick;
属性,您会发现OnClick
是相同的,但Code
是不同的。那是因为它是相同的方法,但是在类的两个不同实例中......
现在,如果在同一个对象上有两个方法:
Data
然后他们的Form1 := TMyForm.Create(nil);
Button1.OnClick := Form1.ButtonClick1;
Button2.OnClick := Form1.ButtonClick2;
会相同,但他们的Data
会有所不同。
答案 1 :(得分:17)
我用这个功能做到了:
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;
它有效,但是如果有人知道一种较少 hacky 的方法,那么我很乐意听到它!
答案 2 :(得分:2)
我知道这是一个老问题......但这是我的2个......
这个答案与Nat的类似,但并不仅限于我们只有TNotifyEvents ...并回答David的问题,如何做到这一点,而不是黑客......
function CompareMethods(aMethod1, aMethod2: TMethod): boolean;
begin
Result := (aMethod1.Code = aMethod2.Code) and
(aMethod1.Data = aMethod2.Data);
end;
我这样使用它
procedure TDefaultLoop.RemoveObserver(aObserver: TObject; aEvent: TNotifyEvent);
var
a_Index: integer;
begin
for a_Index := 0 to FNotifyList.Count - 1 do
if Assigned(FNotifyList[a_Index]) and
(TNotify(FNotifyList[a_Index]).Observer = aObserver) and
CompareMethods(TMethod(TNotify(FNotifyList[a_Index]).Event), TMethod(aEvent)) then
begin
FNotifyList.Delete(a_Index);
FNotifyList[a_Index] := nil;
end;
快速而肮脏的演示
procedure TForm53.Button1Click(Sender: TObject);
var
a_Event1, a_Event2: TMethod;
begin
if Sender is TButton then
begin
a_Event1 := TMethod(Button1.OnClick);
a_Event2 := TMethod(Button2.OnClick);
if CompareMethods(TMethod(TButton(Sender).OnClick), a_Event1) then
ShowMessage('Button1Click Same Method');
if CompareMethods(TMethod(TButton(Sender).OnClick), a_Event2) then
ShowMessage('Button2Click Same Method');
end;
end;
procedure TForm53.Button2Click(Sender: TObject);
var
a_Event1, a_Event2: TMethod;
begin
if Sender is TButton then
begin
a_Event1 := TMethod(Button1.OnClick);
a_Event2 := TMethod(Button2.OnClick);
if CompareMethods(TMethod(TButton(Sender).OnClick), a_Event1) then
ShowMessage('Button1Click Same Method');
if CompareMethods(TMethod(TButton(Sender).OnClick), a_Event2) then
ShowMessage('Button2Click Same Method');
end;
end;