[转]Delphi Form的释放和隐藏:free,hide,close

form.Free   -   释放Form占用的所有资源。Free后,Form指针不能再使用,除非对Form重新赋值。
form.Hide   -   隐藏Form。可以调用form.Show再一次显示。
form.close   -   关闭Form,实际的结果取决于OnCloseQuery和OnClose,如果OnCloseQuery的CanClose为False,不执行任何操作,如果为True,进一步考察OnClose的Action的值:
  caNone:   不执行任何操作
  caHide:   隐藏窗口,同form.Hide
  caFree:   释放Form占用的资源,同form.Free
  caMinimize:   Form最小化。
caFree最主要应用于MDI(多窗体)中,因为子窗体关闭时默认的动作是Hide,即隐藏,所以如果希望其释放所占用的资源时,就要设定关闭动作,也就是在OnClose事件中加一句Action:=caFree;而Application.Terminate是关闭整个应用程序。
Create是从继承下来的方法,作用是给对象实例分配内存,语法为:Formname:=Tformname.Create(Application);     //参数Application表示此窗体的拥有者为Application。
Show是显示已经创建的窗口。语法为:  Formname.Show;
另外:Show是无模式显示窗体,ShowModal是模式显示窗体。
创建form的顺序:
  1.formcreate
  2.formactive
  3.formshow  

implementation分割代码的作用域。implementation防止外部引用单元涉及,任意单元如果访问该单元,只能引用该单元的interface节,对于implementation内声明但没有在interface中声明的函数或过程,其他引用该单元的单元都不能调用,同样,implementation内声明的变量,只能在该单元内被使用。

FormDestroy 和 FormClose 区别和联系:
(1).窗口的所有资源真正释放时调用 FormDestroy。当你关闭窗口时,VCL会调用FormClose,如果你在FormClose里写Action = caFree,那么VCL会继续调用FormDestroy;如果你将Action的值赋为其它任何值,VCL不会真正释放窗口资源(如果Action=caNone则什么事都不做,窗口保持原状),这时就不会调用 FormDestroy 。

(2).看这个程序:
将Form2改为available,然后在TForm2.FormClose 写 action := caFree; 在TForm2.FormDestroy 写 Form2 := nil;
然后这样使用Form2
  if not Assigned(Form2) then
    Form2 := TForm2.Create(Self);
    Form2.Show;//  Form2.ShowModal ;
第一种情况:在FormClose中调用Form1.Close,则会调用到TForm.OnClose,其中又调用到了FormClose,所以就死递归了。一死递归,当然就栈溢出(Stack   Overflow)。
第二种情况:在FormClose调用Form1.Free,这样会调用TForm.Destroy,TForm.Destroy会判断自己是否与Application.MainForm相同,如果是,则会将Application.MainForm置为nil,TForm.Destroy然后触发FormDestroy,在FormDestroy中Form1被置成了nil。FormClose是由TForm.Close调用的,本来在FormClose之后,比较它自己是否Application.MainForm,如果是,就调用Application.Terminate结束应用程序。但这时虽然Self还是非nil,它只是Close方法中的一个隐藏变量,而Application.MainForm已经为nil,所以即使MainForm已经不存在了,但应用程序还是存在,只是看不见它了。Application本身也是一个窗口,但它的大小为0。所以只能用别的办法来关闭应用程序了(Ctrl+Alt+Del或在Delphi   IDE中按Ctrl+F2)。
忠告:
  尽量不要用Free方法来关闭窗体,尤其是主窗体,应该用Close方法。在FormCreate,   FormShow,   FormActivate,   FormCloseQuery,   FormClose,   FormDestroy各事件中不要调用关闭、释放或销毁窗体的方法。
  不要在方法或事件中直接引用Form1这类全局实例变量,如果别人用下列方法创建窗体,用Form1变量就没有作用了:
  var
      myFormVar:   TForm1;
  begin
      myFormVar   :=   TForm1.Create(Application);
      myFormVar.Show;
      //   用myFormVar用一些事
      myFormVar.Close;
  end;
  因为这时候TForm1.FormClose中运行的其实是myFormVar而不是Form1。
  在FormDestroy中可以改成这样:
  if   Self=Form1   then
       Form1   :=   nil;
  用这个方法来防止别的程序对Form1的无意错误引用
时间: 2024-10-06 08:25:17

[转]Delphi Form的释放和隐藏:free,hide,close的相关文章

uniGUI动态建立Form及释放 (2015-10-01 14:51:12)

uniGUI动态建立Form及释放 (2015-10-01 14:51:12) 转载▼   分类: uniGUI 用uniGUI开发的项目中,难免要遇到动态建立一个Form,再释放掉,与传统Delphi项目不一样,这是从forum转贴过来的,要这样写: //建立方法if Frm = nil then  Frm := TUniForm1.Create(UniApplication); //调用及释放方法Frm.ShowModal(       Procedure(Sender: TComponen

delphi Form属性设置 设置可实现窗体无最大化,并且不能拖大拖小

以下设置可实现窗体无最大化,并且不能拖大拖小BorderIcon 设为---biMax[False] biHelp [False]BorderStyle 设为---bsSingle 参考-------------- 可以通过设置窗体的属性以及编程的方法,限制和控制窗体的变化.如让窗体不能最小化.最大化.-----1.通过属性设置方法使用Form的BorderIcon属性,我们可设置窗体是否具有系统菜单(biSystemMenu).最小化按钮(biMinimize).最大化按钮(biMaximiz

Android 内部API (com.android.internal)和隐藏API(@hide)概述

内部API和隐藏代码的例子 在翻阅Android源码的时候有时会遇到一些奇怪的代码,例如下面这个: //注:这段代码在源码android/provider/Telephony.java中. import android.util.Patterns; import com.android.internal.telephony.SmsApplication; import java.util.HashSet; //-- 还有这种(下面这段摘自同一文件):         /**          *

Delphi Setlength 内存释放总结

SetLength 功能说明:设置字符串或动态数组长度.该函数有两个参数.第一个参数为要设置的字符串变量或动态数组变量,第二个参数为指定的长度 参考实例: var S: String; arrText: array of Char; // 定义一个动态数组 begin SetLength(S, 10); // 当设置后,S变量只能赋值长度为10的字符串. SetLength(arrText, 10); // 只有使用SetLength为动态数组分配内存空间后才能使用动态数组.这句代码的作用相当于

Delphi Form显示在第二个显示器中的方法

Delphi 中窗体Form显示在第二个显示器中的方法: 假定要显示在扩展的第二个显示器的Form的名称为frmFloat,则除了要设置该form的top.left.width.height为Screen.Monitors[1].Top, Screen.Monitors[1].Left, Screen.Monitors[1].Width, Screen.Monitors[1].Height 外,一定要加上FrmFloat.MakeFullyVisible(Screen.Monitors[1]);

delphi form.hide和form.visiable 失效?

后来我发现form.hide和form.visiable 全部失效了,然后用 ShowWindow(Application.Handle, SW_HIDE);   ShowWindow(Application.MainFormHandle, SW_HIDE);

delphi TStringList.free 释放错误 invalid pointer operation

var   NeedStr : TStringList; begin  NeedStr := TStringList.Create; ..... try ...... tinally needstr.free;  /// 如果needstr值为nil时,直接释放会产生  invalid pointer operation 错误提示. //应该改为:       if NeedStr.Count>0 then NeedStr.Free; end;

java中 什么叫隐藏(Hide)? 最好给个例子

4.隐藏  (视频下载) (全部书籍) 技术核心和实例前面已经给出,这里只是给出大家对这种现象的一个定义而已,马克-to-win:子类重新定义一个与父类那里继承来的域变量完全相同的变量,称为域的隐藏. 这里所谓隐藏是指子类拥有了两个相同名字的变量,一个继承自父类,另一个由自己定义.相当于把父类的变量"隐藏"起来了. 但子类的方法可以通过super操作父类的成员变量. 下面的例子当中,就分新卡和老卡,this获取新卡的余额,super获取老卡的余额. 例1.4.1---本章源码 clas

iOS7 隐藏状态栏 hide statusBar

1.调用 [self setNeedsStatusBarAppearanceUpdate]; 2.重载以下函数 - (BOOL)prefersStatusBarHidden{ return _hideStatusBar; }