The Unofficial Newsletter of Delphi Users - by Robert
Vivrette
Piggybacking Event Handlers with Components
by Stein Svendsen - stein.svendsen@idgruppen.no
I have enjoyed UNDU some time now, getting many hints and ideas from it. Reading a past issue, Alan Lloyd pointed out the way to change event handlers at runtime, I realized that I could clean out some of my custom forms in the repository.
In my repository growing full of different forms, I have quite a few that have the OnCreate event filled up with code. These forms don't hide my customization when inherited, so they all have plenty of code already in the OnCreate handler when I use one. I prefer to have my forms as clean and codeless as possible, with all event handlers free and fresh for use.
I found that i could move my customizations into components that chain into a form's event handlers. The example below shows an example of this.
The component below may be dropped onto a form, and will make the form materialize itself with a feathery effect when created. The Speed property determines how quickly the effect runs. But the main thing is that it won't interfere with any OnCreate code that the form may have from before.
As far as I can discover, a form, when created, will create all its objects first, paint itself, and then fire its OnCreate code (if any). This component's create() code maps the form's Oncreate event to it's own FormOncreateIntercept procedure. Hence, when the form is ready to execute it's OnCreate code it actually executes the code that the component's FormOncreateIntercept code. The FormOncreateIntercept will execute the form's original OnCreate event if there was one, allowing any other initializations to be completed, before it runs it's own.
(I imagine that this technique allows multiple components using it, to operate on the same form as long as they are different from each other, and don't conflict in their nature.)
Note: You can't use this component with a modal form.
Editors Comment: This is a pretty neat application of this technique. The function of the Speed property will differ though depending on how fast the machine is that is running the code. I am sure a Timer would probably make this work regardless of processor speed.
Unit Slideform;
interface
uses
forms,windows, sysutils, classes, dsgnintf,dialogs;
type
FormSideSlide = class(TComponent)
private
FSpeed: integer;
protected
public
//Procedure pointers
GrabbedFormOnCreate,
InterceptedFormCreate:tnotifyevent;
constructor Create(AOwner: TComponent);override;
procedure FormOncreateIntercept(AOwner: TObject);
published
property Speed: integer read FSpeed write FSpeed
Default 1;
end;
procedure Register;
implementation
// The procedure that the form will think is it's own...
procedure FormSideSlide.FormOncreateIntercept(AOwner: TObject);
var
R : HRgn;
inx:integer;
begin
// First, keep the form invisble for now...
with aowner as tform do visible:=false;
// Run the form's original OnCreate proc
if assigned(GrabbedFormOncreate) then
GrabbedFormOncreate(aowner);
// Then do the wizzy wazzy thing...
with aowner as tform do
begin
inx:=0;
R := CreateRectRgn(0,0,inx,Height);
SetWindowRgn(Handle,R,True);
show;
while inx<=width do
begin
R :=
CreateRectRgn(0,0,inx,Height);
SetWindowRgn(Handle,R,True);
inx:=inx+fspeed;
application.processmessages;
end;
SetWindowRgn(Handle,0,True);
DeleteObject(R);
end;
// Finished: The form has been created in a slightly fancy way
end;
constructor FormSideSlide.Create(AOwner: TComponent);
begin
inherited create(Aowner);
// Assign initial property values
fspeed:=1;
interceptedformcreate := FormOncreateIntercept;
// Hooking an extra link into the forms OnCreate
with aowner as Tform do
if fspeed>0
then
//Speed=0 diables the effect...
if not (csDesigning in ComponentState)
then // Of course doing this at design time would cause disaster..
begin
GrabbedFormOncreate:=oncreate;
//Catch the form's OnCreate handler for later use
oncreate:=interceptedformcreate;
//Plant custom handler
end;
end;
procedure Register;
begin
RegisterComponents('FancyForms', [FormSideSlide]);
end;
end.