我如何确定谁给Showme程序打电话?
procedure Showme(str:string);
begin
ShowMessage(str);
end;
procedure btnclick(sender:TObject);
begin
Showme("test");
end;
procedure btn2click(sender:TObject);
begin
Showme("test");
end;
编辑:混乱
Showme(654, '654'); // procedure name, string
Showme(654, '564');
答案 0 :(得分:9)
一个程序没有内置的方法来知道哪个程序调用它。如果您真的需要知道,可以使用堆栈跟踪,但实际上只需要调试那种数据。对于实际执行,重要的是传递给例程的数据,而不是传递给它的地方。这是结构化编程的基本原则之一。如果两个不同的例程使用相同的数据调用相同的过程,则它们应该对它们进行相同的处理。
你究竟在做什么,你需要能够分辨出什么?可能有一种更简单的方法来实现它。
答案 1 :(得分:8)
为什么不传递一个不同的常量甚至是调用它作为Showme参数的过程的名称?可以分析堆栈以确定调用函数的名称,但它要复杂得多,您需要添加有关链接的信息(映射文件)。 Jedi的JCL有一些功能可以帮助你,但我会使用一个额外的参数。
答案 2 :(得分:2)
我假设您在调试器中运行应用程序,因此您可以在Showme过程中放置一个断点,当程序停止时,激活堆栈视图(查看/调试窗口/调用堆栈)。
它将向您显示谁调用它,实际上如果您双击任何堆栈条目,IDE将引导您进入调用的确切代码行(如果showme在每个调用例程中被调用多次)。 / p> 顺便说一句:我认为你必须更加努力地表达你的问题。
答案 3 :(得分:2)
TVirtualMethodInterceptor允许在实际方法之前和之后执行代码,并且有一个Method参数,其中包含方法名称:
示例代码:
type
TFoo = class
public
procedure Bar; virtual;
end;
procedure InterceptorBefore(Instance: TObject; Method: TRttiMethod;
const Args: TArray<TValue>; out DoInvoke: Boolean; out Result: TValue);
begin
ShowMessage('Before: ' + Instance.ClassName + '.' + Method.Name);
end;
procedure InterceptorAfter(Instance: TObject; Method: TRttiMethod;
const Args: TArray<TValue>; var Result: TValue);
begin
ShowMessage('After: ' + Instance.ClassName + '.' + Method.Name);
end;
{ TFoo }
procedure TFoo.Bar;
begin
ShowMessage('TFoo.Bar');
end;
procedure TForm1.Button1Click(Sender: TObject);
var
interceptor: TVirtualMethodInterceptor;
foo: TFoo;
begin
foo := TFoo.Create;
interceptor := TVirtualMethodInterceptor.Create(TFoo);
interceptor.Proxify(foo);
interceptor.OnBefore := InterceptorBefore;
interceptor.OnAfter := InterceptorAfter;
foo.Bar;
end;
请注意,这是Delphi XE中的新功能,因此我无法在系统上进行测试和验证。