Title: Extend Delphi Components Without the Need to Install in the IDE - Delphi Interceptor Classes
Have you ever needed for a specific Delphi control, like a TButton, to have just one more property or a method that is a "must have" for your current application?
Experienced Delphi developers, when they need a TMySuperButton, would either look for a third-party VCL solution or would try creating a derived control.
What if you do not want to have this MySuperButton permanently in the Component/Tool Palette - since it solves one problem only for this particular application you are developing?
What's more ... how about having a TButton with more properties and methods, some application specific extra behavior, and not TMySupperButton? How about extending what TButton has without the need to create a derived class with a different name?
You could think now of class helpers, but class helper allow only class methods to be added to a class.
What most beginners do not know is that they *can* create their own custom controls derived from the existing VCL set by creating a, so called, interceptor class that has the same name as the class being extended.
Delphi Interceptor Classes
First, to have two classes with the same name is possible in Delphi if those two classes are in separate units.
Next, the following declaration is legal
type TButton = class(StdCtrls.TButton)
The above code creates an interceptor class for a TButton control by extending the "original" TButton declared in the VCL's StdCtrls unit.
Finally, the above declaration needs to be placed in a separate unit.
Most important, the unit hosting the interceptor class needs to be listed in the uses clause *after* the unit defining the base class.
TButton = class(TButton) - an Interceptor Class Example
Here's one interceptor class for the TButton.
A public property "LastClickTime" is added. The original TButton's Click procedure is overridden - Click raises the OnClick event.
Using the overridden Click procedure our TButton interceptor will not allow running the OnClick event handler if the last click on the button happened during the last two second, only a Beep sound will play.
Ok, a dummy example, but serves the purpose. Download an example project: TButton interceptor.
unit button_interceptor;
interface
uses stdctrls, sysutils, DateUtils;
type
TButton = class(stdctrls.TButton)
private
fLastClickTime: TDateTime;
public
procedure Click; override;
public
property LastClickTime : TDateTime read fLastClickTime write fLastClickTime;
end;
implementation
procedure TButton.Click;
const
ClickWaitPeriod = 2;
var
clickTime : TDateTime;
begin
clickTime := Now;
if SecondsBetween(clickTime, LastClickTIme) ClickWaitPeriod then
inherited
else
Beep;
LastClickTime := clickTime;
end;
end.
Now, drop a standard button (TButton) on a Delphi form. Attach some event handler to its OnClick event.
Most importantly, add the "button_interceptor" unit in the uses list as the last unit listed, or at least after the "stdctrls" unit!
Try clicking the button - note that the code executes only if you wait for two second after the last click.
That's it. Using the above you can easily extend Delphi classes by adding extra properties and methods - without the need to create derived classes and have them in the component palette.
Ah almost forgot: note that when you type "Button1." and the list of button's properties and methods pops up - you see the added "LastButtonClick" as if it belongs to the standard Delphi's TButton. Delphi (compiler) magic :)
Also note that you can use interceptor classes not only to extend VCL controls but to extend any Delphi class.
If you need to fake creating your own inherited VCL control, take a look at Fake Creating a New Delphi Control.