如何创建(当我想要显示它)并在主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。
答案 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,就像在汽油桶里玩火柴一样。它会伤害....