
Hooking an event handler
This paper shows how you can 'hook'an event handler.
This demoprogramexample uses two forms. (Form1 and Form2). Form1 uses Form2.
Form2 however is not 'linked' to Form1, so we can say that we could use Form2 in
all applications we would like.
(Form2 is an independent form)
We want to fill the textbox Edit1on Form1 with the value (of the text property)
from Edit2 on Form2 by pressing
the button on Form2.
Here is the problem, because Form2 does not know the existing of Form1, how could
it set the Edit1.Text on Form2 property ?
The answer is that we should hook an event on form2 to do the trick.
This event should be of type TNotifyEvent, an event that should simply
notify the component that an event has occurred.
Sounds like magic!
Before we go further let's see what components we have :
This example has two forms :
Well let's take a good look at the source code of the two
units :
Unit1 :
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm1 = class(TForm)
Edit1: TEdit;
btnHook: TButton;
LabelStatus: TLabel;
procedure btnSetTextClick(Sender: TObject);
procedure btnHookClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Procedure SomeThingChanged (Sender : TObject);
end;
var
Form1: TForm1;
implementation
uses Unit2; // Form1 uses Form2
{$R *.DFM}
procedure TForm1.btnSetTextClick(Sender: TObject);
begin
Form2.Edit2.Text := Edit1.Text;
end;
procedure TForm1.SomeThingChanged(Sender: TObject);
begin
//Read the text from the edit box
Edit1.Text := Form2.Edit2.Text;
end;
procedure TForm1.btnHookClick(Sender: TObject);
begin
//The OnSomethingChanged event must me be 'hooked' by
//assinging it to the method SomethingChanged (Form1)
//Otherwise it is nil and is not assigned
Form2.OnSomeThingChanged := SomeThingChanged;
LabelStatus.Caption := 'Form1 and Form2 are now hooked !';
end;
end.
|
Unit 2 :
unit Unit2;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TForm2 = class(TForm)
Edit2: TEdit;
btnSetText: TButton;
procedure btnSetTextClick(Sender: TObject);
private
{ Private declarations }
FOnSomethingChanged : TNotifyEvent;
public
{ Public declarations }
property OnSomethingChanged : TNotifyEvent read FOnSomeThingChanged
write FOnSomeThingChanged;
end;
var
Form2: TForm2;
implementation
{$R *.DFM}
procedure TForm2.btnSetTextClick(Sender: TObject);
begin
//Trigger the event if assigned then execute
If Assigned(FOnSomeThingChanged) then
FOnSomeThingChanged(Self) //execute
else
showMessage('Sorry forms are not hooked!')
end;
end.
|
If the property OnSomethingChanged (the event) in unit2 is assigned then
it will execute anything that it is assigned to.
In this case the assingment is done by clicking on the btnHook button. This
button assigns the property OnSomethingChanged to the method
SomethingChanged on form1, which reads the value of edit2.
Form2 itself is not aware of what he is going on.
Magic ? No just good OOP. Techniques like this can make your programs much more
maintaneable because by writing independent
units you can reuse the code as much as you want.
| More information : Related papers Dutch : Related papers english : |