tags:

views:

281

answers:

4

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');
+8  A: 

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.

Eduardo Mauro
my friend asked me about that and i told them what you say. but he will only send one parameter because the confusion
drorhan
There really are only two answers: pass a parameter; or look at the call stack. The call stack is complex and it's not a good idea to use that to control program flow (if you call Showme() from somewhere else what happens?) You could look at the parameter you have but that's not reliable either.
moz
+7  A: 

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.

Mason Wheeler
my friend is an old-head programmer and he will do this without an extra parameter and I am just curious about that, is there any other way for do this.
drorhan
No, as Mason told you there is only stack trace but that is not advised. You friend has a wrong approach. Tell him to just use an extra parameter. Why he refuses that? If he is afraid that parameter list will be to long, he can use a record and pass that as a single parameter.
Runner
@drorhan: Aha, an old-head programmer which doesn't use the internet, could ask this question and explain it by himself. Such kind of old-head programmer? ;-)
splash
+1 for the proper reasoning as to why this is not a good idea.
Smasher
+1  A: 

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.

jachguate
+1  A: 

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.

mjustin