Delphi TFrame创建/销毁

Delphi TFrame创建/销毁,delphi,frame,freepascal,lazarus,Delphi,Frame,Freepascal,Lazarus,如何在主TForm上创建(当我想显示它时)和销毁(当我想隐藏它时)帧?框架对齐=alClient 我试过这个: 表格: unit main; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, uFrame1, uFrame2; type TFormMain = class(TForm) procedure F

如何在主TForm上创建(当我想显示它时)和销毁(当我想隐藏它时)帧?框架对齐=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.
第一帧:

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.
第二帧:

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上的按钮时,access vialataions会崩溃(TForm FormCreate工作正常,即创建并显示FrameStart)

德尔菲7


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

这些框架将不得不以更迂回的方式自杀。将CM_释放消息发布到框架,要求其在框架上调用
Free
。您发布消息,而不是发送消息,以便首先处理所有飞行中的消息。您需要在框架中添加一个消息处理程序来响应消息。

您已经得到了一些消息处理程序

这类东西背后的基本思想

将私有属性添加到mainform以保存框架

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

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;
如果你想让你的车架升起另一个车架,重复上面的步骤

如果您希望在一个框架中提升的框架是同级,例如,具有相同的父级,则不要使用Form1 var

fMyNextFrame.Parent = self.Parent;
一旦开始工作,有很多方法可以改进它,这是接口和/或继承的经典场景,但首先要弄清楚这一点

mySomething := TMySomething.Create();
你现在可以做点什么了。 在你叫免费后,这不是不能,这是不要,也不要让任何其他东西


不要自由自在,这就像在一桶汽油里玩火柴。它会伤害……

自由自在吗?0_o,我不确定VCL的事件处理代码是否能够处理这一点-对于表单,这不起作用,例如Self.free是可以的,只是不要对Self做任何事情,打电话后,你会遇到访问违规等情况。仍然有点不确定。即使没有捕获AV,也不意味着没有AV@托尼:不,赛尔夫。自由绝对不是fine@TonyHopkinson: ...
TFrame
没有
Release()
方法,但很容易模拟-使用
PostMessage(Self.Handle,CM_Release,0,0)
而不是
Self.Free
,然后在
TFrame.WndProc()内调用
Self.Free
方法,当它处理
CM\u发布
消息时。Boris链接向您展示了一些…没错!然而,我无法用问题中的代码重现AV(至少在Delphi 2009中是这样)。@tlama这正是这种AV的本质。在FastMM完全调试模式下运行,您将看到一些操作。这个错误是一个经典错误。我知道我永远不应该试图砍掉一根树枝,我只是想知道为什么会这样沉默。谢谢:)这个由@Whiler提供的答案和链接对我来说是一个解决方案。这并不能解决问题。您需要将事件处理程序移动为表单方法,才能使其正常工作。这违背了使用框架的目的。同意,但必须管理对框架的引用,这就需要管理框架的生命周期。我试图让大家了解管理方面,应该选择框架以外的东西作为例子。