How i can to Destroy (free) a Form from memory?
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?
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)?
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.
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;
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...
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.
精彩评论