I am trying to create an application with 2 forms in Delphi XE6. Depending on a ParamStr
setting Form2 may or may not be shown before Form1.
In a quick test app both forms are created before Form1.Show
is invoked - during which Form2 is shown or not
procedure TForm1.FormShow(Sender: TObject);
begin
if ParamStr(1) = 'foo' then
Form2.FooShow;
end;
procedure TForm2.FooShow;
begin
ShowModal;
end;
However in the "real" application I am seeing a different behaviour.
In this case Form1.Show
is being called as soon as Application.CreateForm(TForm1, Form1)
is called. This is before Form2 is being created, which is causing problems as Form2 doesn't exist when it is needed.
Any explanation why the behaviour would differ? Am I missing a setting buried somewhere in Project>Options
Visible
set to True, then it will be shown as soon as it's created.Setting the property to False should resolve your problem.
EDIT
PS: Just in case someone with a similar problem has their main form unexpectedly show even though Visible
is set to False
. This happens because by default the application will show the main form regardless of its Visible
property in the call to Application.Run
.
If so, the following question should help: How can I start Delphi application with the hidden main form?
EDIT2
For the sake of completeness, there are a couple other things that could cause a form to be shown as soon as it's created. However, these probably aren't applicable to this specific question.
OnCreate
event) would obviously cause the form to be shown. However, one would hope that such actions don't lead to these kinds of questions.TIP
The quickest way to finding the answer to such questions is usually just a little bit of debugging.
FormShow
method.In this case you should have found the following code in Forms.pas
.
procedure TCustomForm.DoCreate;
begin
//...
if fsVisible in FFormState then Visible := True; //<-- The trigger
end;
And a little more investagation on fsVisible
would reveal the root cause as: The Visible
property is set to True
.
That said, you don't want to be coding this way because you're creating dependencies via globals. This is error-prone; and your little experiment shows shows just one of many subtle things that can cause problems.
Rather avoid the globals with something like the following changes in your DPR:
begin
Application.Initialize;
ShowForms;
end;
Where ShowForms
is implemented as:
procedure ShowForms;
var
LForm1: TForm1;
LForm2: TForm2;
begin
Application.CreateForm(TFrom1, LForm1);
Application.CreateForm(TFrom2, LForm2);
if (ParamStr(1) = 'foo') then
LForm2.Show
else
LForm1.Show;
end;
If you don't have any dependencies between the forms, the above will suffice. If you do have a dependency, e.g. Form2 uses Form1: then you can explicitly pass a reference after creating the forms, bu before you start doing anything with them.
//Define a property on TForm2 E.g.
property MainForm: TForm1 read FMainForm write SetMainForm;
//Immediately after creating both forms tell form2 which to use as its main form.
LForm2.MainForm := LForm1;