1

我的项目中有 2 个表单(Form1 和 Form2),Form1 是自动创建表单,但 Form2 是可用表单。如何创建 Form2 并卸载 Form1?

我在此代码中收到“访问验证”错误。

这是Form1代码:

1.  uses Unit2;
//*********
2.  procedure TForm1.FormCreate(Sender: TObject);
3.  var a:TForm2;
4.  begin
5.      a := TForm2.Create(self);
6.      a.Show;
7.      self.free;  // Or self.destory;
8.  end;

谢谢。


我将“Serg”代码修改为:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
var
  Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
  Application.CreateForm(TForm2, Form2);
  Release;
end;

end.

///

program Project1;
uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};
{$R *.res}
begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Form1:= TForm1.Create(Application);
  Application.Run;
end.

但是这个项目启动然后自动退出,为什么?我想显示 Form1,当我们单击 Button1 时,显示 Form2 和 free(Release) Form1。我怎么能这样?

4

5 回答 5

13

销毁表单时,最好使用 Release。

释放几乎与免费相同,但它等待待处理的消息以避免崩溃。

你永远不应该使用 Destroy。Free/Release 调用析构函数。

Self 是当前对象(在您的代码 Form1 中,因此 self.Free 会杀死当前表单。这会导致访问冲突。Form1 是自动创建的,它也是自动销毁的,因此您不应自己销毁它。如果您不这样做不想要,藏起来。

如果您想稍后处理它,您应该保留对新创建的表单的引用。

您修改后的代码应如下所示:

uses Unit2;

TForm1 = class (TForm)
private
  FChild : TForm2;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  FChild := TForm2.Create(nil);
  Hide; // Hides form 1
  FChild.Show;
end;

procedure TForm2.FormDestroy(Sender: TObject);
begin
  FChild.Release;
end;

但是为什么要在第一个表单的表单创建中创建另一个表单。为什么不完全删除第一个表单而只使用第二个表单(自动创建)?

于 2011-01-07T07:36:21.413 回答
2

你正在尝试做一些奇怪的事情。

您不能在不关闭应用程序的情况下释放主表单,因此您的 Form1 不应该是自动创建的表单,Form1 和 Form2 都应该手动创建。

首先,您应该像这样编辑项目源以手动创建 Form1:

program Project9;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  Unit2 in 'Unit2.pas' {Form2};

{$R *.res}

begin
  Application.Initialize;
  Application.MainFormOnTaskbar := True;
  Form1:= TForm1.Create(Application);
  Application.Run;
end.

Form1.OnCreate 应写为

procedure TForm1.FormCreate(Sender: TObject);
begin
  Application.CreateForm(TForm2, Form2);
  Release;
end;

这将使 Form2 成为您应用程序的主要形式。正如已经回答的那样,您应该使用 Release 方法来释放表单。

于 2011-01-07T08:03:45.760 回答
0

如果 Form1 是“自动创建”,则它归应用程序对象所有 - 您不应在代码中释放它。如果 Form1 拥有 Form2,则应用程序会清除两者。

我会这样做,但不确定它是否符合您的要求:

procedure TForm1.FormCreate(Sender: TObject);
var a:TForm2;
begin
  a := TForm2.Create(nil);
  try
    a.Show;
 finally
   freeandNil(a);
 end; 
end;
于 2011-04-23T19:32:15.347 回答
0
begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

...

procedure TForm1.FormClose(Sender: TObject; var CanClose: Boolean);
begin
  if MessageDlg ('Are you want to exit?', mtConfirmation,
      [mbYes, mbNo], 0) = mrNo then
    CanClose := False;
end;

所以,仅此而已……

于 2013-06-14T20:57:47.403 回答
0

如果 Form1 应该做的只是初始化某些东西但不显示,请考虑改用数据模块。这些无法显示,但仍可以自动创建。

于 2016-09-01T10:17:57.157 回答