1

我的代码如下:

begin
  Application.Initialize;
  Application.Title := 'Controle Bancário';
  Application.CreateForm(T_DMEstagio, _DMEstagio);
  Application.CreateForm(T_frmLogin, _frmLogin);
  if (_frmLogin.ShowModal = 1) then
    begin
      FreeAndNil(_frmLogin);
      Application.CreateForm(T_frmPrincipal, _frmPrincipal);
      Application.Run;
    end;
    _DMEstagio.Free;

end.

如果我没有像在代码中那样显式释放 DM,我会收到访问冲突异常,但在另一个应用程序中,代码是这样的:

begin
    Application.Initialize;
    Application.Title := ' > Sistema de Gestão Comercial <';
    if HPrevInst = 0 then
    begin
      Application.CreateForm(TFrmPrincipal, FrmPrincipal);
      Application.CreateForm(TIBDM, IBDM);
      Application.Run;
    end ;
end.

我不必释放 DM,也没有任何异常。这是为什么?

4

1 回答 1

0

回答你的问题

“我什么时候需要释放应用程序创建的数据模块?”

从来没有。

使用方法创建的所有数据模块和/或表单Application.CreateForm将归所有Application并自动处理。


但看起来,您的问题与自动销毁过程无关。以下代码应该可以解决您的问题,因为某些组件和类需要应用程序完成其完整的初始化/运行周期才能优雅地销毁。有可能RXHook就是其中之一。

begin
  Application.Initialize;
  Application.Title := 'Controle Bancário';
  Application.ShowMainForm := false;
  Application.CreateForm(T_DMEstagio, _DMEstagio);
  Application.CreateForm(T_frmLogin, _frmLogin);
  if (_frmLogin.ShowModal = 1) then
    begin
      FreeAndNil(_frmLogin);
      Application.ShowMainForm := true;
      Application.CreateForm(T_frmPrincipal, _frmPrincipal);
    end
  else Application.Terminate;
  Application.Run;
end.

那么上面的代码到底发生了什么?

您正在尝试显示登录表单,并根据登录结果继续运行您的应用程序或终止它。

重要的是要注意,您创建的第一个表单将变为Application.MainForm,如果该表单在Application.Run执行之前被释放,Application.MainForm则将被设置回nil. 这将确保下一个创建的表单可以成为主表单。

在您的情况下,这意味着_frmLogin将设置为您的Application.MainForm. 如果登录成功,将被释放并_frmPrincipal接管。但如果登录不成功_frmLogin,仍然会Application.MainFormApplication.Run执行时再次显示。

这是Application.ShowMainForm到位的地方。当它设置为时false Application.Run将只运行而不显示任何表单。在您的情况下,它将阻止_frmLogin再次出现。当然,在成功登录时您要设置Application.ShowMainFormtrue以确保应用程序正常启动。

在登录失败的情况下调用Application.Terminate将确保您的应用程序退出应用程序主消息循环,该循环将从调用开始Application.Run并正常终止。

于 2015-05-21T19:50:49.220 回答