Jump to content
Mark Williams

Finalization section not called unless main form shown

Recommended Posts

In order to pop up a login box I have removed my main form from the autocreation section and I create it in the project file as follows:

 

 Application.Initialize;
 Application.MainFormOnTaskbar := False;
 Application.CreateForm(TfrmMain, frmMain);
 Application.Run;

The reason I do this is to stop the main form showing if the login process is cancelled.

 

The main form has an initialization and finalization section.

 

If the login process is cancelled so that the main form never shows, the initialization section is called, but the finalization section does not get called. In fact, the app hangs and has to be terminated via task manager.

 

if not DoLogIn(self, CurrServer, MainUser, ltStartUp) then
  begin     
    Application.Terminate;
    exit;
  end;

 

If I insert a Show command prior to Application.Terminate all works as expected.

 

Does anyone know why Application.Terminate does not terminate the app without a call to "Show" and is there aw away around this (other than calling Show)?

Share this post


Link to post

I'm not sure what your "exit" does, and I can't see your code, but with the code below finalization is called:

 

if not DoLogIn() then

begin

    Application.ShowMainForm := False;
    Application.Terminate;
    Application.Run;
end;

  • Like 1

Share this post


Link to post

Is this a VCL app or FMX?

 

Where does the code appear? In the proj file? if so, it does not really remove the form from being auto created. You just don't use the feature in the IDE

 

Try creating the form using the default way: frmMain:=TfrmMain.Create.... and then assign it to the Application as the MainForm

 

Share this post


Link to post
17 minutes ago, John Kouraklis said:

Is this a VCL app or FMX?

 

Where does the code appear? In the proj file? if so, it does not really remove the form from being auto created. You just don't use the feature in the IDE

 

Try creating the form using the default way: frmMain:=TfrmMain.Create.... and then assign it to the Application as the MainForm

 

VCL

 

The form creation code is in the proj file.

 

You can't assign the form as the main form other than in project options. It's readonly. Which has made me realise I don't have a mainform. Maybe that's the problem

  • Like 1

Share this post


Link to post
48 minutes ago, Attila Kovacs said:

I'm not sure what your "exit" does, and I can't see your code, but with the code below finalization is called:

 

if not DoLogIn() then

begin

    Application.ShowMainForm := False;
    Application.Terminate;
    Application.Run;
end;

The "exit" does nothing. I was under the misapprehension that the current function would run to its conclusion even after terminate call.

 

Unfortunately, I have been fiddling around trying to find out how to solve the problem and now I can't recreate it! My main form flashes on the screen at the point of application.terminate and it closes properly. Can't seem to get it back to its original state. Will just have to live with the form momentarily flashing on screen. Thanks for the help.

Share this post


Link to post

Ok, here is the thing:

1 hour ago, Mark Williams said:

Does anyone know why Application.Terminate does not terminate the app without a call to "Show" and is there aw away around this (other than calling Show)?

Application.Terminate only sends a message to the application to terminate.

It will be processed in the main Application message loop, which you can start with Application.Run.

To avoid showing the mainform, set Application.ShowMainForm := False; prior to .Run;

Share this post


Link to post

That means Application.ShowMainForm := False; and Application.Terminate; and  Application.Run; if login fails, and you won't get a flickering mainform and you will have a clean termination of the application including calling the finalization section in the mainform.

Edited by Attila Kovacs

Share this post


Link to post
1 minute ago, Attila Kovacs said:

That means Application.ShowMainForm := False; and Application.Terminate; if login fails, and you won't get a flickering mainform and you will have a clean termination of the application including calling the finalization section in the mainform.

I have Application.ShowMainForm:=false, but it still flickers after call to terminate. I cannot figure out why it is now doing this. It wasn't when I originally posted and as far as I can see my code is the same. But as mentioned above, there is apparently no mainform.

Share this post


Link to post
On 11/24/2019 at 10:53 AM, Mark Williams said:

You can't assign the form as the main form other than in project options. It's readonly. Which has made me realise I don't have a mainform. Maybe that's the problem

The MainForm is established by the first call to TApplication.CreateForm().  Changing the project options simply changes the default code that calls CreateForm() in the main .dpr file.  If there is no MainForm assigned when Application.Run() is called, Run() simply exits immediately.

  • Like 2
  • Thanks 1

Share this post


Link to post
5 hours ago, Remy Lebeau said:

The MainForm is established by the first call to TApplication.CreateForm().  Changing the project options simply changes the default code that calls CreateForm() in the main .dpr file.  If there is no MainForm assigned when Application.Run() is called, Run() simply exits immediately.

Ok. Thanks that makes sense. I was testing whether mainform was assigned in the onCreate event of the first form created.

Share this post


Link to post
9 hours ago, Remy Lebeau said:

by the first call to TApplication.CreateForm().

This info is actually cool. I was never paying attention to it. I was thinking the main form were the first form created any way.

But with this, it's enough to write:

 frmYourFormsNeededToCreateIfAny := TfrmYourFormsNeededToCreateIfAny.Create(Application);
 frmLogin := TfrmLogin.Create(Application);
 if frmLogin.DoLogin then
  Application.CreateForm(TfrmMain, frmMain);
 Application.Run;
 

or similar

 

no need for Terminate prior to .Run;, no need for ShowMainForm := False, no unnecessary OnCreate() of the main form.

however initialization and finalization will run (of course), and prepare, that adding new forms via IDE will screw up your dpr mostly every time.

 

 

Edited by Attila Kovacs
  • Thanks 1

Share this post


Link to post
On 11/26/2019 at 12:24 AM, Mark Williams said:

I was testing whether mainform was assigned in the onCreate event of the first form created.

The TApplication.MainForm property is set by TApplication.CreateForm() only after the first TForm object is fully constructed.  So no, the MainForm property will not have been assigned yet in the OnCreate event of any TForm object that is created before, or during, the first call to TApplication.CreateForm().

  • Like 1
  • Thanks 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×