In step 1 we see that when we create a form dynamically we have access to all of its (public) properties. But what about its events?
Can we create and access those too? We can, as the following code shows. In the previous example we used the auxiliary forms OnShow event handler to assign random values to the Left and Top properties so that the subforms appear at different positions each time they are shown. Well change the program in the previous step to have a similar OnShow event handler.
Ex 1.4 step 2
How do we set about creating an event handler? Lets see how Delphi sets about it and then attempt something similar. Whenever Delphi creates an event handler, it declares this event handler in the class definition (eg ex 1.3 step 2, line 8). In line 19 below we copy this format.The private and public sections of the class definition are for the programmers use and we place the event handler declaration in the private section (line 11) since this is the only unit that needs to access it. We can give the event handler any name we choose, and here well call it frmAuxiliaryShow.
In RAD development, the link between an event and its handler is controlled through the Object Inspector. We cant use that here so we link the OnClick event to the frmAuxShow event handler in program code (eg line 53). Just as Width is a property to which we can assign either a constant or variable name (eg line 24), OnShow is a property to which we can assign the name of a suitable method. (Just as we must use appropriate types when assigning variables and not, for example, assign a string to an integer, when assigning methods they must have a matching method signature. That is why we define frmAuxShow with a Sender parameter of type TObject even though it is not used in the method (line 19).)
In summary, we have a private method (line 19 below) that is used as an event handler, ie initiated by an event, and so it follows same format as Delphi-generated event handlers. Since an events name (eg OnShow) is a property, we can link the event handler to the event for the object we create (eg line 53) This achieves the same effect as linking an event handler through the Object Inspector.
The additional methods we create for the subsidiary form need not just be event handlers. They can also be helper or access methods that we can call through program code. Well create a helper method FormRefFail to use whenever we attempt an invalid reference to frmAuxiliary. First, we declare the method privately (line 20) since no other unit should have access to it. It is a procedure since we are not returning a value. (We look at access methods in subsequent examples.)
Run this program. From an external, black-box perspective it works as before.
... type
7 TfrmMain = class(TForm)
...
17 private
18 frmAuxiliary: TForm;
19 // event handler
20 procedure frmAuxiliaryShow(Sender: TObject) ;
21 // helper method
22 procedure FormRefFail;
23 end;
...
24 implementation
26 const // unit level constant
27 Mssgs: Array [0..1] of string =
28 ('Auxiliary Form does not exist',
28 'Auxiliary Form already exists') ;
29 procedure TfrmMain.radAuxShowClick(Sender: TObject) ;
30 begin
31 try
32 frmAuxiliary.Show;
33 except
34 FormRefFail;
35 end;
36 end;
37 procedure TfrmMain.radAuxHideClick(Sender: TObject) ;
38 begin
39 try
40 frmAuxiliary.Hide;
41 except
42 FormRefFail;
43 end;
44 end;
45 procedure TfrmMain.btnCreateClick(Sender: TObject) ;
46 begin
47 if frmAuxiliary = nil then
48 begin
49 frmAuxiliary := TForm.Create(nil) ;
50 frmAuxiliary.Caption := 'frmAuxiliary';
51 frmAuxiliary.Height := 150;
52 frmAuxiliary.Width := 180;
53 frmAuxiliary.OnShow := frmAuxiliaryShow;
54 end
55 else
56 ShowMessage (Mssgs [1]) ;
57 end;
58 procedure TfrmMain.btnFreeClick(Sender: TObject) ;
59 begin
60 try
61 frmAuxiliary.Hide;
62 frmAuxiliary.Free;
63 frmAuxiliary := nil;
64 except
65 FormRefFail;
66 end;
67 end;
68 procedure TfrmMain.frmAuxiliaryShow(Sender: TObject) ;
69 begin
70 frmAuxiliary.Left := Random (600) ;
71 frmAuxiliary.Top := Random (400) ;
72 end;
73 procedure TfrmMain.FormRefFail;
74 begin
75 ShowMessage (Mssgs [0]) ;
76 radAuxHide.Checked := False;
77 radAuxShow.Checked := False;
78 end;
79 initialization
80 Randomize;
81 end.


