【问题标题】:error when auto-loading second form from mainform at startup in delphi在delphi中启动时从mainform自动加载第二个表单时出错
【发布时间】:2017-06-20 19:56:02
【问题描述】:

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

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

在内部跟踪时,我看到 Form2 为 nil,并且出现访问冲突错误。我认为问题在于 MainForm 尚未完全加载以调出Form2。或者 Form2 还没有创建,因此无法调出。

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

【问题讨论】:

标签: forms delphi access-violation delphi-xe7


【解决方案1】:

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

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

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

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;

【讨论】:

    【解决方案2】:

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

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

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

    干杯,

    【讨论】:

      猜你喜欢
      • 2014-09-26
      • 1970-01-01
      • 2017-02-26
      • 2014-10-10
      • 1970-01-01
      • 1970-01-01
      • 2014-01-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多