Saturday, May 9, 2009

Execute a Delphi Method (Procedure/Function) by Name

When you need to convert an integer to a string, you would use the IntToStr Delphi function. When you need to display a form modally you would use the ShowModal method of a form object.

In short, functions, procedures and methods are called by their name. Ok, I know you knew that.

What if you need to call a function by its name as a string variable value? What if you need to use a code like:

ExecMethod(Form1, 'ShowModal');



type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject) ;
procedure CallMeByName(Sender: TObject) ;
private
procedure ExecMethod(OnObject: TObject; MethodName: string) ;
end;

var
Form1: TForm1;

type
TExec = procedure of object;

procedure TForm1.ExecMethod(OnObject: TObject; MethodName: string) ;
var
Routine: TMethod;
Exec: TExec;
begin
Routine.Data := Pointer(OnObject) ;
Routine.Code := OnObject.MethodAddress(MethodName) ;
if NOT Assigned(Routine.Code) then Exit;
Exec := TExec(Routine) ;
Exec;
end;

procedure TForm1.CallMeByName(Sender: TObject) ;
begin
ShowMessage('Hello Delphi!') ;
end;

procedure TForm1.Button1Click(Sender: TObject) ;
begin
ExecMethod(Form1, 'CallMeByName') ;
end;

1 comment:

Sebastien Russell said...

Hi, sorry for the resurrection, :P - What if I have a unit with a list of methods in it but want to call a method using this route? There's no objects or anything. Just the methods.

As in.

unit2
interface
uses Dialogs;
procedure Test;
implementation

procedure Test;
begin
ShowMessage('test');
end;

end.

Then in Unit 1,

var
M : TMethod ;
E : TExec ;
begin
M.Code := 'test'; < from Unit2?
E := TExec(M);
E;
end;

Thanks. :)