Delphi TFrame创建/销毁

时间:2012-05-15 20:59:55

标签: delphi frame freepascal lazarus

如何创建(当我想要显示它)并在主TForm上销毁(当我想隐藏它时)帧?帧'align = alClient。

我试过了:

表格:

unit main;

interface

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

type
  TFormMain = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    f1: TFrame1;
    f2: TFrame2;
  end;

var
  FormMain: TFormMain;

implementation

{$R *.dfm}

procedure TFormMain.FormCreate(Sender: TObject);
begin
  f1 := TFrame1.Create(Self);
  f1.Parent := Self;
end;

end.

第一帧:

unit uFrame1;

interface

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

type
  TFrame1 = class(TFrame)
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

uses main, uFrame2;

procedure TFrame1.btn1Click(Sender: TObject);
begin
  Self.Free;
  FormMain.f2 := TFrame2.Create(FormMain);
  FormMain.f2.Parent := FormMain;
end;

end.

第二帧:

unit uFrame2;

interface

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

type
  TFrame2 = class(TFrame)
    lbl1: TLabel;
    btn1: TButton;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

implementation

{$R *.dfm}

uses main, uFrame1;

procedure TFrame2.btn1Click(Sender: TObject);
begin
  Self.Free;
  FormMain.f1 := TFrame1.Create(FormMain);
  FormMain.f1.Parent := FormMain;
end;

end.

但是当我单击FrameStart或Frame1上的按钮时,它会因访问vialataions而崩溃(TForm FormCreate工作正常,即它创建并显示FrameStart)。

Delphi 7。

With the first frame With the second frame

2 个答案:

答案 0 :(得分:9)

您无法在这些事件处理程序中调用Self.Free。当事件处理程序返回时,下一个执行的VCL代码仍然使用对刚刚释放的对象的引用。这就是访问违规的来源。如果您在完全调试模式下运行FastMM,那么您将看到一条有用的诊断消息。

这些帧必须以更迂回的方式自杀。将CM_RELEASE消息发布到帧,要求它在帧上调用Free。您发布消息而不是发送消息,以便首先处理所有正在进行的消息。您需要向帧添加消息处理程序以响应消息。

答案 1 :(得分:3)

你已经有了一些。

这种东西背后的基本理念。

在主窗体中添加一个私有属性来保存框架。

在按钮单击处理程序中,假设您一次只需要一个

if assigned(fMyFrame) then
begin
  fMyFrame.Free;
  fMyFrame := nil;
end;
fMyFrame := TSomeFrame.Create(self);
fMyFrame.Parent := self;
fMyFrame.blah...

当你只是想摆脱它而不是替换它

if assigned(fMyFrame) then
begin
  fMyFrame.Free;
  fMyFrame := nil;
end;

如果你想让你的画框再画一帧,请在那里重复上面的内容。

如果您希望框架中的框架成为兄弟,例如拥有相同的Parent,然后不要使用Form1 var。

fMyNextFrame.Parent = self.Parent;

一旦你开始工作,有很多方法可以改进它,这是接口和/或继承的经典场景,但首先要考虑这一点。

mySomething := TMySomething.Create();

你现在可以用某些东西做点什么了。 在你打电话给自由之后,它不会,它不会,也不会让任何其他东西。

不要做self.free,就像在汽油桶里玩火柴一样。它会伤害....