The right way to destroy a form and show another in Delphi

Currently, in my program, I have a start form and a main form. The launch form is displayed for a second or two.

Right now, I have the following code in the timer:

frmStartup.Destroy; frmMain := TfrmMain.Create(Self); frmMain.Show; 

Now I'm not sure if this is the right way to do this. It works, but when calling application.Terminate(); I get an access violation message, making me believe that I did something wrong in destroying the launch form.

If someone can show the correct procedure to accomplish what I want (not modally), it would be very helpful.

Thanks in advance,

EDIT:

Thanks for all the reviews, I fixed the access violations by simply adding the code:

  Action := caFree; 

In the frmStartup.formClose method.

+6
source share
4 answers

Do not create frmStartup with Application.CreateForm . The first form created there will become the main form of your application, and if it is frmStartup , you destroy it outside of Application knowledge.

Instead, use the regular Form.Create file in the project source file (.dpr):

 var frmStartup: TfrmStartup; begin Application.Initialize; Application.MainFormOnTaskBar := True; frmStartup := TfrmStartup.Create(nil); // No owner assigned here! frmStartup.Show; frmStartup.Update; Application.CreateForm(TfrmMain, frmMain); // Let Application have this for main form // Delay here if needed frmfrmStartup.Free; Application.Run; end. 
+8
source

You might want your pop-up screen to appear as early as possible, so ideally this should be done during the initialization phase, then it should disappear only when MainForm is ready to capture.

This is what we do in our application, where we reuse the About dialog as a splash screen , then release it when MainForm steals focus.

In dpr, as high as possible in the uses section after the required VCL / RTL blocks:

  f_adtDlgAbout in 'f_adtDlgAbout.pas' {frmDlgAbout}, // ASAP to be used as a Splash screen 

Unit About (FYI, FormStyle equals fsStayOnTop and Position equals poScreenCenter ):

 unit f_adtDlgAbout; [...] type TfrmDlgAbout = class(TForm) [...] procedure TfrmDlgAbout.SplashFormDeactivate(Sender: TObject); begin Release; end; initialization // Use it as a Splash screen with TfrmDlgAbout.Create(nil) do begin AlphaBlend := True; AlphaBlendValue := 208; BorderStyle := bsNone; btnOK.Visible := False; OnDeactivate := SplashFormDeactivate; Show; Update; end; end. 
+4
source

TFrmMain.Create (Self) ??? What is the "I"? Are you doing this from inside frmStartup? If yes, then no. Use TFrmMain.Create (NIL).

Use frmStartup.Release to issue frmStartup, if all the code you submitted is inside the frmStartup method, you need to put this line at the bottom of the method.

+1
source

Set frmMain as the main form

In frmMain.FormCreate

 frmStartup := TfrmStartup.Create(nil); try frmStartup.ShowModal; finally frmStartup.Free; end; 
0
source

Source: https://habr.com/ru/post/908360/


All Articles