在Delphi中正确销毁一个表单并显示另一个表单的方法

6
目前在我的程序中,我有一个启动窗体和一个主窗体。启动窗体显示一两秒钟。
现在,在一个计时器中,我有以下代码:
  frmStartup.Destroy;

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

目前,我不确定这是否是正确的方法。虽然它可以运行,但当调用application.Terminate();时,我收到了访问冲突消息,这让我认为在启动窗体的销毁过程中做错了什么。

如果有人能展示我想要的正确程序(非模态),那将不胜感激。

提前致谢,

编辑:

感谢所有的反馈,我通过简单地添加代码解决了我的访问冲突问题:

  Action := caFree;

进入frmStartup.formClose方法。


2
frmStartup.Destroy 应该改为 frmStartup.Free 或者 frmStartup.Release,FWIW。 - David Heffernan
4个回答

8
不要使用Application.CreateForm来创建frmStartup。在那里创建的第一个表单将成为您的应用程序的主表单,如果那是frmStartup,则在Application之外销毁它。
相反,在您的项目源(.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.

4
为了让流程尽可能紧凑,定义一个Windows消息并在启动时的窗体中放置一个消息处理程序,在收到该消息时释放它。然后从主窗体的OnShow方法发送该消息。 - SourceMaid
1
我在我的应用程序中使用启动画面。然而,这似乎超出了这个问题的范围。 - Ken White

4

您可能希望尽早显示启动画面,因此最好在初始化阶段完成,然后只有当主窗体准备好接管时,启动画面才会消失。

这正是我们在应用程序中所做的,我们将“关于”对话框重用为启动画面,然后在主窗体夺取焦点时释放它。

在dpr文件中,在所需的VCL / RTL单元之后,尽可能高地使用uses子句:

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

关于单元(FYI,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.

1
TFrmMain.Create(Self)??? "Self"是什么?你是在frmStartup内部这样做的吗?如果是,不要这样做。使用TFrmMain.Create(NIL)。
使用frmStartup.Release释放frmStartup,如果你发送的所有代码都在frmStartup的一个方法中,你需要将该行放在方法的底部

使用我的当前解决方案,TFrmMain.Create(nil) 在应用程序终止时会导致访问冲突。 :/ - James

0

将frmMain设置为主窗体

在frmMain.FormCreate事件中

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接