Let's begin with a little example. Imagine you want to handle application
exceptions (see "TApplication.OnException") in a little unit, which you plan
to use in all your projects. Now it would seem logical to try something like
the following:
 |
unit HandleApplicationExceptions;
interface
implementation
uses Forms, SysUtils;
procedure ApplicationException(Sender: TObject; E: Exception);
begin
end;
initialization
Application.OnException := ApplicationException;
end.
|
|
But unfortunately Delphi complains in the last line, because it doesn't like
to assign "ApplicationException" to the "OnException" event. And the reason
is simple. Look at the event's type definition:
 |
type TExceptionEvent = procedure (Sender: TObject; E: Exception) of object;
|
|
The decisive part is the "of object". This means that "OnException" wants to
have a method rather than a procedure. So normally you would have to do
something like this:
 |
unit HandleApplicationExceptions;
interface
implementation
uses Forms, SysUtils;
type
TDummyClass = class
procedure ApplicationException(Sender: TObject; E: Exception);
end;
procedure TDummyClass.ApplicationException(Sender: TObject; E: Exception);
begin
end;
var dummyClass : TDummyClass;
initialization
dummyClass := TDummyClass.Create;
Application.OnException := dummyClass.ApplicationException;
finalization
dummyClass.Free;
end.
|
|
This compiles and works alright. But wait - isn't this a bit complicated?
Yes, it is. At least IMHO. So I've written a little function named
"ProcedureToMethod", which will make our life a bit easier:
 |
function ProcedureToMethod (self: TObject; procAddr: pointer) : TMethod;
|
|
This function kind of converts a procedure to a method. But please note, that
your procedure must have an additional "Self" parameter at the first
position. This parameter will receive whatever you enter into
ProcedureToMethod. In our example it's "nil", because we don't need it:
 |
unit HandleApplicationExceptions;
interface
implementation
uses Forms, SysUtils, madTools;
procedure ApplicationException(Self, Sender: TObject; E: Exception);
begin
end;
initialization
Application.OnException := TExceptionEvent(ProcedureToMethod(nil, @ApplicationException));
end.
|
|
Well, this looks better (shorter), doesn't it? And it's faster, too, because
you don't need to create and free a dummy class.