在 delphi 中启动时从 mainform 自动加载第二个表单时出错

error when auto-loading second form from mainform at startup in delphi

这里是第一次业余程序员。希望得到一些帮助。使用 Delphi XE7.

我有一个 Mainform,它有一个可以调出第二个窗体的按钮。在初始启动时,我想单击调出第二个窗体的按钮,以便两个窗体都可见。然后我将它保存到一个配置文件中,这样它就不会在每次加载时都这样做。

在内部跟踪时,我看到 Form2 为 nil,并且出现访问冲突错误。我认为问题在于 MainForm 尚未完全加载以显示 Form2。或者那个Form2还没有被创建,所以不能被调出。

我已尝试添加延迟以等待 MainForm 加载。我试过一个计时器。我曾尝试寻找其他答案,但仍未找到有帮助的答案。我希望这里有人能指引我正确的方向。

MainForm 仍在创建过程中时,Form2 尚未创建是正确的。您必须等到 Form2 创建完成后才能显示它。

最简单的方法是在设计时简单地将 Form2.Visible 属性 设置为 True(辅助表单默认设置为 Visible=False),然后使确保 Form2 在项目选项中设置为自动创建(默认情况下不会自动创建辅助表单)。让Form2在启动时创建后自动显示。

但是,如果您的按钮需要设置 Form2,那么您必须延迟按钮点击,直到创建 Form2 之后。为此,我喜欢使用延迟的 window 消息,例如:

const
  WM_DELAYED_STARTUP = WM_APP + 1;

type
  TMainForm = class(TForm)
    Button1: TButton;
    procedure FormCreate(Sender: TObject);
    procedure ButtonClick(Sender: TObject);
  private
    procedure WMDelayedStartup(var Message: TMessage); message WM_DELAYED_STARTUP;
  end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  PostMessage(Handle, WM_DELAYED_STARTUP, 0, 0);
end;

procedure TMainForm.ButtonClick(Sender: TObject);
begin
  //...
  Form2.Show;
  //...
end;

procedure TMainForm.WMDelayedStartup(var Message: TMessage);
begin
  Button1.Click;
end;

计时器也可以正常工作:

type
  TMainForm = class(TForm)
    Button1: TButton;
    StartupTimer: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure ButtonClick(Sender: TObject);
    procedure StartupTimerTimer(Sender: TObject);
  end;

procedure TMainForm.FormCreate(Sender: TObject);
begin
  StartupTimer.Enabled := True;
end;

procedure TMainForm.ButtonClick(Sender: TObject);
begin
  //...
  Form2.Show;
  //...
end;

procedure TMainForm.StartupTimerTimer(Sender: TObject);
begin
  StartupTimer.Enabled := False;
  Button1.Click;
end;

或者,您可以使用 MainForm 的 OnShow 事件(如果您只显示 MainForm 一次并且在应用程序的生命周期内不隐藏它):

type
  TMainForm = class(TForm)
    Button1: TButton;
    procedure FormShow(Sender: TObject);
    procedure ButtonClick(Sender: TObject);
  end;

procedure TMainForm.FormShow(Sender: TObject);
begin
  Button1.Click;
end;

procedure TMainForm.ButtonClick(Sender: TObject);
begin
  //...
  Form2.Show;
  //...
end;

我建议您在打开项目后,执行 Shift + Ctrl + F11 快捷方式和 select 表单选项,如下所示 [1]。在此之后,select 自动创建表单中的 Form2,将其移至可用表单并单击确定按钮。 在此之后,将调用 Form2 的代码行更改为:

Application.CreateForm(TForm2, Form2); Form2.ShowModal; FreeAndNil(Form2)

如果这能解决您的问题,请告诉我。

干杯,