Reputation: 4370
I'm trying to load a form when my main form starts. And I do it using ShowModal
. Also that form is not an auto create form so I have to create it first with application.CreateForm
.
My problem is when I try to load the form in FormCreate
event, it load the form twice and when I close the form my whole app closes.
Here is my code:
procedure Tfrm_main.FormCreate(Sender: TObject);
var
username, password : string;
begin
username := ini.ReadString('user','username','');
if username = '' then
begin
application.CreateForm(Tfrm_user,frm_user);
frm_user.ShowModal;
end;
end;
How can I fix this problem? Thanks.
Upvotes: 2
Views: 437
Reputation: 612954
The code in your question is called from the call to Application.CreateForm
that creates the main form. Then you call Application.CreateForm
again, recursively, and that results in the Tfrm_user
instance becoming the main form.
It's well known that the first form created by Application.CreateForm
becomes the main form. Here, you call Application.CreateForm
to create the main form. But before the code of Application.CreateForm
gets to determine what the VCL considers to be the main form, the recursive call to Application.CreateForm
executes. All the way to the end, and in doing so determines the main form to be the secondary form made with the recursive call.
You then show the secondary form modally. Later you call Application.Run
which shows the VCL main form, your secondary form. Again. And then you close it. Which closes the program, because that's what happen when you close the VCL main form.
My advice is to call Application.CreateForm
exactly once in the life of your program. So, in the OnCreate
handler create the other form like this:
frm_user := Tfrm_user.Create(Application);
Or perhaps let the main form be the owner. And certainly consider not using the global variable frm_user
. I'd remove that.
Or another option would be to show the secondary form modally before you make the call to Application.CreateForm
.
Upvotes: 6
Reputation: 84550
You're getting bitten by an order-of-operations issue.
If you look at the code to TApplication.CreateForm
, you'll see that things happen in this order:
FMainForm.Show;
But when the program is setting up your principal form:
OnFormCreate
event handler. Then the event handler calls TApplication.CreateForm
, (before the first one has returned) which creates the new form, sees that FMainForm
is not assigned and assigns this form to it, then returns.FormCreate
then shows this form as a modal, then returns.TApplication.CreateForm
, which goes on to the next part, sees FMainForm already assigned, and does not assign it.TApplication.Run
gets called, which shows the main form... the wrong one.IF you want to create the new form, call the constructor instead: frm_user := Tfrm_user.Create(Application);
Really, TApplication.CreateForm
should only be used the one time, to set up the main form. It's kind of a hack that can make trouble for you if you don't know exactly how it works.
Upvotes: 5