在应用程序表单创建事件上创建两次的表单

时间:2014-09-02 21:12:39

标签: delphi

我正在尝试在主窗体启动时加载表单。我使用ShowModal来做。此表单也不是自动创建表单,因此我必须先使用application.CreateForm创建它。

我的问题是当我尝试在FormCreate事件中加载表单时,它会加载表单两次,当我关闭表单时,我的整个应用程序关闭。

这是我的代码:

procedure Tfrm_main.FormCreate(Sender: TObject);
var
  username, password : string;
begin
  username := ini.ReadString('user','username','');
  if username = '' then
  begin
    application.CreateForm(Tfrm_user,frm_user);
    frm_user.ShowModal;
  end;
end;

如何解决此问题?感谢。

2 个答案:

答案 0 :(得分:6)

您的问题中的代码是从调用创建主窗体的Application.CreateForm调用的。然后,您再次以递归方式调用Application.CreateForm,这会导致Tfrm_user实例成为主要形式。

众所周知,Application.CreateForm创建的第一个表单成为主要表单。在这里,您调用Application.CreateForm来创建主表单。但是在Application.CreateForm的代码确定VCL认为是主要形式的内容之前,对Application.CreateForm的递归调用会执行。一直到最后,这样做确定主要形式是使用递归调用创建的辅助表单。

然后以模态方式显示辅助表单。稍后您拨打Application.Run,其中会显示VCL主表单,即您的辅助表单。再次。然后你关闭它。这会关闭程序,因为当你关闭VCL主表单时会发生什么。

我的建议是在你的程序生命周期中只调用一次Application.CreateForm。因此,在OnCreate处理程序中创建另一个这样的表单:

frm_user := Tfrm_user.Create(Application);

或者让主要表格成为所有者。当然可以考虑不使用全局变量frm_user。我删除了。

或者另一种选择是在调用Application.CreateForm之前以模态方式显示辅助表单。

答案 1 :(得分:5)

您因操作订单问题而被咬伤。

如果您查看TApplication.CreateForm的代码,您会发现事情按此顺序发生:

  • 创建相应类型的新表单。
  • 如果FMainForm = nil,请将此新表单分配给它。
  • 稍后,TApplication.Run调用FMainForm.Show;

但是当程序设置你的主要表格时:

  • 首先创建它,调用OnFormCreate事件处理程序。然后事件处理程序调用{​​{1}},(在第一个返回之前)创建新表单,看到未分配TApplication.CreateForm并将此表单分配给它,然后返回。
  • 您的FMainForm会将此表单显示为模式,然后返回。
  • 事情稍微放松一下,我们回到原来的FormCreate,进入下一部分,看到已经分配了FMainForm,并且没有分配它。
  • 然后它返回,TApplication.CreateForm被调用,这显示主要形式......错误的形式。

如果您要创建新表单,请改为调用构造函数:TApplication.Run实际上,frm_user := Tfrm_user.Create(Application);只应一次使用,以设置主表单。如果你不确切知道它是如何运作的话,它会给你带来麻烦。