我如何从内存中销毁(释放)表单?

发布于 2024-10-10 11:18:31 字数 1288 浏览 0 评论 0原文

我的项目中有 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 和释放(释放)Form1。我怎样才能做到这一点?

i have 2 Form (Form1 and Form2) in the my project, Form1 is Auto-create forms, but Form2 is Available forms.
how i can to create Form2 and unload Form1?

I received a "Access validation" Error in this code.

Here is Form1 code:

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;

Thanks.


I modified that "Serg" code to this :

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.

but this project start and then exit automatically, Why?
i want to show Form1 and when we click Button1 then show Form2 and free(Release) Form1. how i can to this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

歌枕肩 2024-10-17 11:18:31

当你销毁一个表单时,最好使用Release。

Release 与 free 几乎相同,但它会等待挂起的消息以避免崩溃。

你永远不应该使用 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;

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

When you destroy a form, it's better to use Release.

Release is almost the same as free, but it waits for pending messages to avoid crashes.

You should never use Destroy. Free/Release calls the destructor.

Self is the current object (in your code Form1, so self.Free kills the current form. Which results in the access violation. Form1 is auto created, it is also auto destroyed so you shouldn't destroy it yourself. If you don't want it, hide it.

And you should keep a reference to the newly created form if you want to handle it later.

Your modified code should be like:

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;

But Why do you want to create another form in the form create of the first form. Why not remove the first form entirely and only use the second one (auto created)?

清风无影 2024-10-17 11:18:31

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

在不关闭应用程序的情况下,您无法释放主表单,因此您的 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 方法来释放表单。

You are trying to do something strange.

You cannot free main form without closing application, so your Form1 should not be autocreated form, both Form1 and Form2 should be created manually.

First, you should edit your project source like this to create Form1 manually:

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 should be written as

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

that will make Form2 the main form of your application. As already answered you should use Release method to free the form.

枯叶蝶 2024-10-17 11:18:31

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

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

procedure TForm1.FormCreate(Sender: TObject);
var a:TForm2;
begin
  a := TForm2.Create(nil);
  try
    a.Show;
 finally
   freeandNil(a);
 end; 
end;

If Form1 is 'autocreate', it's owned by the application object - you shouldn't free it in your code. If Form1 owns Form2, application cleans up both.

I'd do it like this, but not sure it meets your requirements:

procedure TForm1.FormCreate(Sender: TObject);
var a:TForm2;
begin
  a := TForm2.Create(nil);
  try
    a.Show;
 finally
   freeandNil(a);
 end; 
end;
紫﹏色ふ单纯 2024-10-17 11:18:31
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;

所以,就这些了……

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;

So, that is all...

一梦浮鱼 2024-10-17 11:18:31

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

If all Form1 should do is initialize something but not being shown, consider using a datamodule instead. These cannot be shown but can still be autocreated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文