Mark Williams 14 Posted November 24, 2019 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
Attila Kovacs 631 Posted November 24, 2019 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; 1 Share this post Link to post
John Kouraklis 94 Posted November 24, 2019 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
Mark Williams 14 Posted November 24, 2019 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 1 Share this post Link to post
Attila Kovacs 631 Posted November 24, 2019 @Mark Williams Can you see what I'm writing? Just for the record. Share this post Link to post
Mark Williams 14 Posted November 24, 2019 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
Attila Kovacs 631 Posted November 24, 2019 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
Attila Kovacs 631 Posted November 24, 2019 (edited) 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 November 24, 2019 by Attila Kovacs Share this post Link to post
Mark Williams 14 Posted November 24, 2019 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
Attila Kovacs 631 Posted November 24, 2019 Mainform is always the first form you create. Make sure you are not creating the mainform or any other twice. Share this post Link to post
Remy Lebeau 1436 Posted November 26, 2019 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. 2 1 Share this post Link to post
Mark Williams 14 Posted November 26, 2019 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
Attila Kovacs 631 Posted November 26, 2019 (edited) 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 November 26, 2019 by Attila Kovacs 1 Share this post Link to post
Remy Lebeau 1436 Posted November 27, 2019 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(). 1 1 Share this post Link to post