tags:

views:

164

answers:

2

I frequently find myself declaring a simple procedure type

  TMessageProc  = procedure(const AMsg: String);

in Delphi. The purpose is to allow passing callback procedures to processing functions so that they can update the user interface without having to be aware of the user interface.

Surely this must be a common paradigm in Delphi programming. Does there exist an standard procedure type declaration in one of the commonly used units that I can use for this? Unfortunately, with the roll-my-own approach I'm not entirely consistent between projects in the way I name or declare the type.

+1  A: 
  1. There is no such standard type.
  2. You does not need "frequently declare" this type - create your own utility unit, declare this type there, and then just use this unit when you need this type. It will be good to use a prefix in the type name, so your type name will not cross once with some other name. For example - TLLMessageProc.
  3. If you often use such approach with the procedural UI callbacks, then you can consider to replace it with some interface, implementing different UI callbacks, implement it as it is needed for your app, etc. In general, it may improve your code.
da-soft
+2  A: 

The "common Delphi paradigm" is event (event handler). Eg, you can write

type
  TMessageProc  = procedure(const AMsg: String);

procedure DoSomething(OnProgress: TMessageProc);
begin
//  ...
  if Assigned(OnProgress) then OnProgress('123');
//  ...
end;

Normally the events in Delphi are implemented as methods, so the standard Delphi code for the above example is:

type
  TForm1 = class(TForm)
    Button1: TButton;
    Label1: TLabel;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
    procedure ShowProgress(const AMsg: String);
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

type
  TMessageProc  = procedure(const AMsg: String) of object;  // declare event type

procedure DoSomething(OnProgress: TMessageProc);
begin
//  ...
  if Assigned(OnProgress) then OnProgress('123');   // trigger event
//  ...
end;

procedure TForm1.ShowProgress(const AMsg: String);  // event handler
begin
  Label1.Caption:= AMsg;
  Application.ProcessMessages;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  DoSomething(ShowProgress);
end;

There is nothing wrong in declaring your personal event types, but sure you can find standard events in VCL. For example, classes.pas unit containes the declaration

  TGetStrProc = procedure(const S: string) of object;
Serg
Events are not methods; they are method pointers.
vcldeveloper