Как я могу уничтожить (освободить) форму из памяти? - PullRequest
1 голос
/ 07 января 2011

У меня есть 2 Форма (Form1 и Form2) в моем проекте, Form1 - это Авто-создание форм, но Form2 - Доступные формы.Как я могу создать Form2 и выгрузить Form1?

Я получил ошибку «Access validation» в этом коде.

Вот код 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 и свободную (Release) форму Form1.как я могу к этому?

Ответы [ 5 ]

12 голосов
/ 07 января 2011

Когда вы уничтожаете форму, лучше использовать Release.

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;

Но почему вы хотите создать другую форму в форме создания первой формы. Почему бы не удалить первую форму целиком и использовать только вторую (автосоздан)

2 голосов
/ 07 января 2011

Вы пытаетесь сделать что-то странное.

Вы не можете освободить основную форму, не закрывая приложение, поэтому ваша форма 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 для освобождения формы.

0 голосов
/ 01 сентября 2016

Если все, что должна сделать Form1, это что-то инициализировать, но не показывать, попробуйте вместо этого использовать модуль данных. Они не могут быть показаны, но все еще могут быть созданы автоматически.

0 голосов
/ 15 июня 2013
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;

Итак, это все ...

0 голосов
/ 23 апреля 2011

Если Form1 'autocreate', он принадлежит объекту приложения - вы не должны освобождать его в своем коде. Если Form1 владеет Form2, приложение очищает оба.

Я бы сделал это так, но не уверен, что он соответствует вашим требованиям:

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