Assigned的问题?

amiao 2002-12-16 05:03:08
我写了一个方法用于在MainForm的Panel2上显示窗体。但当两次点击Button1后,
方法CreateForm中的AForm依然为nil,不解?
procedure TMainForm.CreateForm(Form: TFormClass; AForm: TForm);
begin
if Assigned(AForm) then
begin
AForm.Show;
Exit;
end;
AForm := Form.Create(Application);
AForm.Parent := Panel2;
AForm.BorderStyle := bsNone;
AForm.Align := alClient;
AForm.Show;
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
CreateForm(TForm1, Form1);
end;

...全文
238 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
amiao 2002-12-17
  • 打赏
  • 举报
回复
问题基本解决了,多谢各位参与,请接分!
wjlsmail 2002-12-16
  • 打赏
  • 举报
回复
加 Var 传址来保证指向同一地址 ,好办法
wjlsmail 2002-12-16
  • 打赏
  • 举报
回复
Study
lxpbuaa 2002-12-16
  • 打赏
  • 举报
回复
wzrlover(流光逝水) 说的基本正确,加var修饰字可以。不过:
AForm: TForm的确是传值,但是是传指针值。CreateForm(TForm1, Form1)调用时,Form1=nil,也就是说这个指针没有指向,所以
CreateForm(Form: TFormClass; AForm: TForm)中的AForm根本不会和Form1同步。也就是说,行参(CreateForm中的参数)变了,但是实参没有跟着变,原因很简单:它们根本没有指向同一个地方。这常常是使用对象参数的误区。
而var AForm: TForm,实际上是传送指向指针的指针。这时候可以解决以上的问题,但是编译器会检查严格匹配问题。
另一个办法是写成一个函数而不是过程,但是这时候需要自己管理已经创建的窗口实例(可以用TObjectList)。

—————————————————————————————————
宠辱不惊,看庭前花开花落,去留无意;毁誉由人,望天上云卷云舒,聚散任风。
—————————————————————————————————
knock 2002-12-16
  • 打赏
  • 举报
回复

procedure TMainForm.CreateForm(Form: TFormClass; AForm: TForm);
begin
if Assigned(AForm) then
AForm.Show;
else
begin
AForm := Form.Create(Application);
AForm.Parent := Panel2;
AForm.BorderStyle := bsNone;
AForm.Align := alClient;
AForm.Show;
end;
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
CreateForm(TForm1, Form1);
end;

wzrlover 2002-12-16
  • 打赏
  • 举报
回复
我想是这样的,CreateForm(Form: TFormClass; AForm: TForm);
形参AForm是传值的,而非传址,只在该函数有效,一离开该函数
Aform初始化是为nil,所以会反复创建实例。
办法是:将Aform形参该为传址,如
CreateForm(Form: TFormClass; var AForm: TForm);

应该还有其他更好的办法。还没试出 :(
具体没有测试过,不托之处恳请指正!

windofsun 2002-12-16
  • 打赏
  • 举报
回复
可以用这种方法:
procedure TMainForm.CreateForm(Form: TFormClass; var AForm: TForm);
begin
// ...
end;

调用的时候:
CreateForm(TForm1, TForm(Form1));

这是因为var修饰要求类型完全匹配,你声明为TForm类型,实参就必须为TForm类型,不能用它的子类实例。用as操作转化都不可以。
amiao 2002-12-16
  • 打赏
  • 举报
回复
MainForm是在dpr文件中自动创建的,而Form1则需要手动创建,而且它不是MainForm的ChildForm
amiao 2002-12-16
  • 打赏
  • 举报
回复
to:lws0472(hero),不是这个原因,我该了一下代码:

procedure TMainForm.CreateForm(Form: TFormClass; AForm: TForm);
begin
// if Assigned(AForm) then
// begin
// AForm.Show;
// Exit;
// end;
AForm := Form.Create(Application);
// AForm.Parent := Panel1;
// AForm.BorderStyle := bsNone;
// AForm.Align := alClient;
AForm.Show;
end;

procedure TMainForm.Button1Click(Sender: TObject);
begin
if not Assigned(Form1) then
CreateForm(TForm1, Form1);
end;
这样后当两次点击Button1时,已经Create的Form1依然为nil
lws0472 2002-12-16
  • 打赏
  • 举报
回复
不知是否因为assigned不能检测子form。
你在AForm.Parent := Panel2后,创建的form2变成了子窗口,不知是否因为如此.
lws0472 2002-12-16
  • 打赏
  • 举报
回复
用findwindow也很麻烦,创建的form是子窗口,还要根据Getchild,getwindowtext来取
lws0472 2002-12-16
  • 打赏
  • 举报
回复
很奇怪,我定义dd : unit1.Tform1,

CreateForm(unit1.TForm1, dd);居然还是创建多个窗口,用assigned根本检测不到,建议改用findwindow吧。
amiao 2002-12-16
  • 打赏
  • 举报
回复
不是Assigned的问题,而是怎么去调用或者说怎样改进这个方法,避免Create多个Form实例。请各位大虾指点迷津!
amiao 2002-12-16
  • 打赏
  • 举报
回复
to: wzrlover(流光逝水),没错啊,我的Form都是动态创建的啊,但是现在的问题是我CreateForm完Form1后我没有关闭或释放Form1啊,但是再次调用CreateForm方法并创建同一个Form(如Form1)时,形参AForm(Form1)明明已经Create,但是AForm却为nil。这样一来,如果我点击Button1若干次,Form1岂不创建了若干个实例了
amiao 2002-12-16
  • 打赏
  • 举报
回复
to: cobi(我是小新),呵呵,不是那个问题
wzrlover 2002-12-16
  • 打赏
  • 举报
回复
你的Form1应该是动态创建的吧,所以Aform才为nil.

如果是设计时创建的就没这个问题了。
cobi 2002-12-16
  • 打赏
  • 举报
回复
测试你的代码,没有任何问题。
你检查一下dpr文件中的Application.CreateForm(TForm1, Form1);一句是否被删除了,如果没有被删除,请删除
amiao 2002-12-16
  • 打赏
  • 举报
回复
而如果方法中的形参AForm用指针而不是TForm类型又该怎样做呢?

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧