主窗体里SHOW一个FORM2后如何FREE了它?(50分)

  • 主题发起人 主题发起人 panjf
  • 开始时间 开始时间
onclose事件中
action:=cafree;
 
terry_lzs的做法可行,但如果子窗体是工程自己创建的,再次show 会出错,

最保险的办法是,所有的子窗体都自己创建,用完后调用 free

ok!

code:

try

form2 := Tform2.create(applicatio);

form2.showmodal;

finally

form2.free;

end;

 
FORM2不是MDI的子窗体,是一个普通类型的
刚才没说清楚,
 
简单的说就是:Form2.Free;
如果复杂点就这样:
Procedure ...
Var Form2 : TForm2;
begin
Form2 := TForm2.Create...
Form2.ShowModal;
Form2.Free;
end;
 
在FORM2的ONCLOSE事件里写上:
Action:=CAFree;
Form2:=nil; // 可有可无
 
: Form2:=nil; // 可有可无
谁说的,如果没有这句,Form2在Free后还是不为nil,如果你在外边这么写
if not Assigned(Form2) then
Form2:=TForm2.Create(Self);
Form2.Show;
第二次Show的时候Create就不会执行,但是实际上Form2已经不存在了,所以Form2.Show
就会出错,看看D5 开发人员指南,里面有解释关于Free<>nil的问题
 
首先FROM2必须在PROJECT OPTION中将其改为AVAILABLE FROM。
try
form2 := Tform2.create(application);
form2.showmodal;
finally
form2.free;
end;
不要用SHOW,因为弹出窗口必须是MODEL方式的,关闭后才进入FREE;
而SHOW,是立即进入主进程FREE,肯定报错。
 
同意>>zhuhuan
 
如果你用showmodal
try
form2 := Tform2.create(application);
form2.showmodal;
finally
form2.free;
end
如果你用show
在onclose 中写代码了


 
有这样的必要吗?
 
悟空的说法是最简单的!
 
在主程序中编一个
procedure createform(t:Tform)
t := t.create(application);
t.showmodal;
finally
t.free;
end
这样较通用一些

 
如果是模态窗体,应该如下写:
with TForm2.Create(Application) do
try
ShowModal;
finally
Release; //To free a form, call its Release method, which destroys the form and releases the memory allocated for it after all its event handlers and those of the components it contains are through executing.
end;

如果是非模态的,则调用的时候不用FREE。 而是在FORM2的ONCLOSE时FREE。
with TForm2.Create(Application) do
begin
Show;
end;

Form2的OnClose中 Action := ctFree;
 
同意xianjun,我刚试了一下,比Free好多了.只是谁能再详细解释一下Release与Free到底有
哪些区别就好了.
 
Free是指一个对象的释放,作为任何对象都存在这个非虚拟的方法,实际上它调用销毁器
Destroy,而销毁器是可以Override的,
Release并非所有的对象都存在这个方法,实际上只有TCustomForm和某些Win32对象具有此
方法,在TCustomForm的代码里,Release方法只有一句PostMessage(Handle, CM_RELEASE, 0, 0);
注意是PostMessage,而不是SendMessage,也就是说只将CM_Release消息放入消息循环队列,
然后立即返回,只有其他消息处理完毕后此消息才会处理,这样也可以理解Help里关于Release
方法的说明了,而Form的默认消息处理器对于CM_Release的处理也只有一句 Free,也就是说
处理CM_Release实际上就是Free,
无论调用那一个方法,对于窗体变量都无法彻底清除(成为nil),为什么不能清除和TObject
的构造有关,所以无论Action=caFree,还是Free or Release本质上没有区别,如果你不
显式将变量置为nil下一次使用此变量时就会产生错误,仔细看一下TApplication的CreateForm
方法具体实现,里面的Try和Except部分可以说明问题,注意问题的所处在的层面!


 
确实, Release最终也是通过调用Free来释放内存的,
但它是通过把一个消息加进消息队列来实现,并不象我们释放其他对象一样直接就调用了
FREE方法。这样能避免在其他事件处理程序正在执行的时候把窗体Free掉。

窗体变量只是指向一个内存区的指针,用FREE或RELEASE都只是把内存区的内容FREE了,
这个指针始终都是指向这个地址的。因此,若用了全局变量的话,就可能要在FREE后把
这个指针设为NIL,当然也可直接调用FreeAndNil过程把两步合为一步。
 
如果form2中有在form1中用到的控件,就是说form2必须始终运行着,只是将form2隐藏,
但是隐藏后form2不能将焦点返回给form1,有人说form1等待form2的终止才能得到焦点,
这种情况下用release 还是free或者用别的方法。
希望能够继续讨论下去,我添100分进去,希望能彻底弄明白,谢谢·
 
to a_fi:
隐藏后form2不能将焦点返回给form1:显示form2时是不是用的showmodal?
用show就可以了
 
多人接受答案了。
 
后退
顶部