Delphi how to determine which procedure called the another procedure?
How can i determine who called the Showme Procedure?
开发者_如何学编程procedure Showme(str:string);
begin
ShowMessage(str);
end;
procedure btnclick(sender:TObject);
begin
Showme("test");
end;
procedure btn2click(sender:TObject);
begin
Showme("test");
end;
Edit : The Confusion
Showme(654, '654'); // procedure name, string
Showme(654, '564');
There's no built-in way for one procedure to know which procedure called it. You can use stack tracing if you really need to know, but that sort of data is really only needed for debugging. For actual execution, what matters is the data that's passed to the routines, not where it came from. That's one of the basic principles of structured programming. If two different routines call the same procedure with the same data, it should treat them both the same.
What exactly are you doing where you need to be able to tell the difference? There might be a simpler way to accomplish it.
Why don't you pass a different constant or even the name of the procedure calling it as a parameter of Showme? It is possible to analyze the stack in order to determine the name of the calling function but it is much more complicated and you need to add information about linking (map file). Jedi's JCL has some functions that can help you but I would use an additional parameter.
I will assume you're running the application in the debugger, so you can put a breakpoint inside the Showme procedure and when the program stops, activate the stack view (view/debug windows/Call stack).
It will show you who called it and actually if you double click on any stack entry the IDE will walk you to the exact line of code that makes the call (in case showme is called more than once per calling routine).
BTW: I think you have to make a better effort to express your question.
TVirtualMethodInterceptor allows to execute code before and after the actual method, and there is a Method parameter which contain the method name:
Example code:
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;
Note this is new in Delphi XE so I can not test and verify it on my system.
精彩评论