简体   繁体   English

正确的方法来破坏一个表单,并在Delphi中显示另一个

[英]Correct way to destroy a form and show another in Delphi

Currently in my program I have a Startup form, and a Main form. 目前在我的程序中,我有一个Startup表单和一个Main表单。 The startup form shows for a second or two. 启动表单显示一两秒钟。

Right now, I have the following code within a timer: 现在,我在计时器中有以下代码:

  frmStartup.Destroy;

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

Right now, I'm not sure if this is the correct way to do it.. It works, but when calling application.Terminate(); 现在,我不确定这是否是正确的方法..它有效,但在调用application.Terminate(); I receive an access violation message, leading my to believe that I have done something wrong in the destruction of the startup form.. 我收到一条访问违规消息,导致我相信我在破坏启动表单时做错了什么..

If anyone could show the the correct procedure for doing what I want (non-modally) It would be greatly appreciated. 如果有人能够显示正确的程序来做我想要的(非模态),我将不胜感激。

Thanks in advance, 提前致谢,

EDIT: 编辑:

Thanks for all the feedback, I fixed my access violations by simply adding the code: 感谢所有反馈,我通过简单地添加代码修复了访问冲突:

  Action := caFree;

Into the frmStartup.formClose method. 进入frmStartup.formClose方法。

Don't create the frmStartup using Application.CreateForm . 不要使用Application.CreateForm创建frmStartup The first form created there becomes your application's main form, and if that's frmStartup you're destroying it outside Application knowledge. 在那里创建的第一个表单将成为应用程序的主要表单,如果是frmStartup ,则会在Application知识之外将其销毁。

Instead, use a normal Form.Create in your project source (.dpr) file: 而是在项目源(.dpr)文件中使用普通的Form.Create:

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.

You may want to have your Splash Screen showing up as early as possible, so ideally it should be done during the initialization phase, then it should disappear only when the MainForm is ready to take over. 您可能希望尽早显示您的启动画面,因此理想情况下应该在初始化阶段完成,然后只有在MainForm准备好接管时它才会消失。

That's exactly what we do in our application where we reuse the About dialog as a splash screen then release it when the MainForm steals the focus. 这正是我们在应用程序中所做的,我们将关于对话框作为启动画面重用,然后在MainForm窃取焦点时释放它。

In the dpr, as high as possible in the uses clause after the needed VCL/RTL units: 在dpr中,在所需的VCL / RTL单元之后的uses子句中尽可能高:

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

The About unit (FYI, FormStyle is fsStayOnTop and Position is poScreenCenter ): 关于单位(仅供参考, FormStylefsStayOnTopPositionpoScreenCenter ):

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.

TFrmMain.Create(Self)??? TFrmMain.Create(自拍)??? What is "Self"? 什么是“自我”? Are you doing that from inside frmStartup? 你是从frmStartup里面做的吗? If so, don't . 如果是这样, 不要 Use TFrmMain.Create(NIL). 使用TFrmMain.Create(NIL)。

Use frmStartup.Release to release frmStartup, if all of the code you sent is inside a method of frmStartup, you need to put that line at the bottom of the method. 使用frmStartup.Release释放frmStartup,如果你发送的所有代码都在frmStartup的方法中,你需要将该行放在方法的底部

Set frmMain as Main Form 将frmMain设置为主窗体

On frmMain.FormCreate 在frmMain.FormCreate上

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM