如何释放根据窗体名称找到的窗体对象呢?   FreeAndNil(TForm(form1));                                  //不报错
   FreeAndNil(TForm(FindGlobalComponent(strName))));       //报错,strName为窗体名称目的是,是根据用户操作取得窗体名称,然后释放该窗体。因为窗体是动态创建的,所以只能根据窗体名称来释放窗体var
  strName:string;
begin
  strName:=...;//根据用户操作来取得窗体的名称(窗体为动态创建的)
  Tfrom(FindGlobalComponent(strName))).free;
  Tfrom(FindGlobalComponent(strName))):=nil;  //这句报错 left side cannot be assigned to
使用如下方法,可不报错,但是,当再次创建窗体时就报错,因为上次关闭时并没有使得窗体对象置为nil。var
  f:TForm;
begin
  f:=TForm(FindGlobalComponent(strName));
  freeandnil(f);  

解决方案 »

  1.   

    1)普通情况如下:
    窗体名.free
    窗体名.close
    或者直接写   close
    2)特殊情况如下:
    如果窗体中是静态加载DLL的话,就在关闭窗体之前,先释放掉那个DLL
    再close
    即可
    3)我上面说的那种情况,假设窗体中设置与数据库控件关联时,必须点周“保存”
    这个按扭时,才能关闭窗体时,当然这个方面是为了将信息在保存时后的最后一个
    “确认保存”功能的,否则最后一条记录是不会保存到数据库中........
      

  2.   

    可能是我没将问题表述清楚吧,sorry。
      

  3.   

    FindGlobalComponent找到的是实例的地址,而不是指向实例的指针的地址(比如Form1),所以不能置为nil。
    比如实例的地址是123,而Form1的地址是456(它指向的值是123);把FindGlobalComponent的结果置为nil,就是mov [123],0,而不是想要的mov [456],0。 解决办法很简单,自己保存一个List,存入字符串Form1和Form1的地址即可。like this:List := TStringList.Create;
    List.AddObject('Form1', TObject(@Form1));//保存TObject(PDWORD(List.Objects[List.IndexOf('Form1')])^).Free;//Form1.Free
    PDWORD(List.Objects[List.IndexOf('Form1')])^ := 0;//Form1 := nil
      

  4.   

    在主窗体frmmain中,动态穿件窗体frmx:=Tfrmx.create(self);frmx.name=strname;
    然后调用frmx.show;
    然后在单击主窗体的关闭按钮时释放frmx,  FreeAndNil(TForm(FindGlobalComponent(strname)));
    这时就会报错,
    当然,可以在TFrmx的onclose事件中释放,但是我的工程不允许这么做,只能在主窗体中释放他所创建并调用的窗体。
      

  5.   

    我根据你的标题:“如何释放根据窗体名称找到的窗体对象呢?”
    的想法:
    1)根据窗体名称找到窗体上的对象
         清空信息值
         初始化参数
    2)在“单元2”中引用“单元1”的中窗体中的控件,就是必须
    在“单元2”中引用一下“单元1”的名称后,使用其值即可如下:
    uses  单元1;
      if  单元1.edit1.text='abc' then
          ShowMessage('信息为:'+(单元1.edit1.text));
      

  6.   

    sgzhou12345,对不起了,是我急着解决问题,语气不太好,原谅啊!
      

  7.   


    这样好像是是不行的
    当下次创建窗体时,form1依然不等于nil
      

  8.   

    不会吧?我这边测试过了,assigned(form1)返回false
      

  9.   

    8楼的代码,我也测试了,就是一个“退出”功能吗
    但是有个BUG呀,你可以在“进程”看一下,窗体是关闭了,但是“进程”中还有呀
    没有
    CLOSE直接在将窗体和进程一块“关闭”的
      

  10.   

    s11ss你真行呀,8楼的代码,我也测试了,就是一个“退出”功能吗
    但是有个BUG呀,你可以在“进程”看一下,窗体是关闭了,但是“进程”中还有呀
      

  11.   

    6#的方法不行啊。
    我现在主要要解决的是,如何使得窗体的name来找到窗体对象的变量变为nil。
      

  12.   

    ???什么意思,也就是说
    窗的为NIL值就可以吗,这样进程中不是还有一个“程序体”吗
    那程序在“结束”时,你也应该“考虑”这个问题的,否则会
    “浪费资源”的
      

  13.   


    先free然后nil
    free是没有问题的,问题是free后,如何nil呢(注意:是根据name找到的窗体对象,所以不能直接使用对象的变量名,即不能nFrom:=nil);
      

  14.   

    打个比方,窗体值必须先以NIL(就是空值)赋值,才能再free(释放)
    不过这种NIL空值,一般情况都是针对“图片”控件(image1)的
    代码如下:
      Image1.Picture.Assign(nil);
      Image1.Picture.Graphic.Free;
    这窗体中的Image1中的图片就会清空的
      

  15.   


    “窗体值必须先以NIL(就是空值)赋值,才能再free(释放)”这种说法是不正确的。
      

  16.   


    我的意思是如何实现以下语句要实现的功能:
    FreeAndNil(TForm(FindGlobalComponent(strName))));       //报错,strName为窗体名称
      

  17.   

    FreeAndNil
    根据你的这个理解的话,既然窗体被FREE后,就从内存就消失了呀
    不能再接受任意值的呀NIL???
      

  18.   

    自己创建的对象 自己管理不就得了。
    我平时管理对象的时候 喜欢用自己写的一个hashtable来管理。
    只要你做到 你所有对象名称 别名不重复 你可以把你程序中所有的对象放到这个hashtable中来,对象的查找速度是非常快的。
    type
      TInitComponent= procedure (Compent:TComponent);
     
    type
      PPHashItem = ^PHashItem;
      PHashItem = ^THashItem;
      THashItem = record
      Next: PHashItem;
      Key: String;
      Value: TObject;
      end;
      
      THXHashTable = class
      private
        Buckets: array of PHashItem;
        function GetValue(key: String): Tobject;
        procedure SetValue(key: String; const Value: Tobject);
      protected
        function Find(const Key: String): PPHashItem;
        function HashOf(const Key: String): Cardinal; virtual;
       public
        constructor Create(Size: Integer = 256);
        destructor Destroy; override;
        procedure Add(const Key: String; Value: Tobject);
        procedure Clear;
        procedure InitCompentValues(funcP:TInitComponent);
        procedure Delete(const Key: String);
        property ValueOf[key:String]: Tobject read GetValue write SetValue;
      end;{ THXHashTable }procedure THXHashTable.Add(const Key: String; Value: tobject);
    var
      Hash: Integer;
      Bucket: PHashItem;
    begin
      Hash := HashOf(Key) mod Cardinal(Length(Buckets));
    //  Bucket := Find(key)^;
     // if Bucket = nil then
      New(Bucket);
      Bucket^.Key := Key;
      Bucket^.Value := Value;
      Bucket^.Next := Buckets[Hash];
      Buckets[Hash] := Bucket;
    end;procedure THXHashTable.Clear;
    var
      I: Integer;
      P, N: PHashItem;
    begin
      for I := 0 to Length(Buckets) - 1 do
      begin
      P := Buckets[I];
      while P <> nil do
      begin
        N := P^.Next;
        Dispose(P);
        P := N;
      end;
      Buckets[I] := nil;
      end;
    end;constructor THXHashTable.Create(Size: Integer);
    begin
      inherited Create;
      SetLength(Buckets, Size);
    end;destructor THXHashTable.Destroy;
    begin
      Clear;
      inherited;
    end;function THXHashTable.Find(const Key: String): PPHashItem;
    var
      Hash: Integer;
    begin
      Hash := HashOf(Key) mod Cardinal(Length(Buckets));
      Result := @Buckets[Hash];
      while Result^ <> nil do
      begin
      if Result^.Key = Key then
        Exit
      else
        Result := @Result^.Next;
      end;
    end;function THXHashTable.HashOf(const Key: String): Cardinal;
    var
      I: Integer;
    begin
      Result := 0;
      for I := 1 to Length(Key) do
      Result := ((Result shl 2) or (Result shr (SizeOf(Result) * 8 - 2))) xor
        Ord(Key[I]);
    end;function THXHashTable.GetValue(key: String): Tobject;
    var
      P: PHashItem;
    begin
      P := Find(Key)^;
      if P <> nil then
      Result := P^.Value else
      Result := nil;
    end;procedure THXHashTable.SetValue(key: String; const Value: Tobject);
    var
      P: PHashItem;
    begin
      P := Find(Key)^;
      if P <> nil then
      P^.Value := Value;
    end;procedure THXHashTable.Delete(const Key: String);
    var
      P: PHashItem;
      Prev: PPHashItem;
    begin
      Prev := Find(Key);
      P := Prev^;
      if P <> nil then
      begin
       Prev^ := P^.Next;
       Dispose(P);
      end;
    end;
    procedure THXHashTable.InitCompentValues(funcP:TInitComponent);
    var
      I: Integer;
      P, N: PHashItem;begin
      for I := 0 to Length(Buckets) - 1 do
      begin
      P := Buckets[I];
      while P <> nil do
      begin
        N := P^.Next;
        funcP(TComponent(P^.value));
        P := N;
      end;
      end;end;上面的InitCompentValues 是将你自己定义 的一个对控件操作的函数传入进行处理的一个函数。
      

  19.   


    你家的地址是XXX路XXX街XXX号,你家是违章建筑被强拆了,难道就不能再在你家的这个地方重新建楼房?再或者是有关部门不能把你家的地址都注销掉?有木有?  有木有?? 有木有???!!!
      

  20.   

    答案就在8#, 还有什么好讨论的...正常做法是在各个窗体的Close或Destroy事件,让窗体为nil,麻烦就是每个窗体都要这么写
    解决办法就是采用TList来管理你的所有窗体,在Close时,让TList中对应实例的地址为0即可(即nil)
    下面是例子:...
      private
        procedure ShowForm(frm:TForm;Pfrm:TFormClass);
        procedure MdiFormClose(Sender: TObject; var Action: TCloseAction);
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      FList: TStringList;implementationuses unit2,unit3;{$R *.dfm}procedure TForm1.MdiFormClose(Sender: TObject; var Action: TCloseAction);
    var
      frmIndex: Integer;
    begin
      Action:=caFree;
      if Sender is TForm then
      begin
        frmIndex := FList.IndexOf(TForm(Sender).Name);
        if frmIndex >= 0 then
        begin
          PWord(FList.Objects[frmIndex])^:=0;
          FList.Delete(frmIndex);
        end;
      end;
    end;procedure TForm1.ShowForm(frm:TForm;Pfrm:TFormClass);
    begin
       if not AsSigned(frm)then
      begin
        frm:=Pfrm.Create(self);
        frm.OnClose:=MdiFormClose;
        FList.AddObject(frm.Name, @frm);
      end;
      frm.Show;
    end;procedure TForm1.Button1Click(Sender: TObject);
    begin
      ShowForm(Form2,TForm2);
    end;procedure TForm1.Button2Click(Sender: TObject);
    begin
      ShowForm(Form3,TForm3);
    end;initialization
      FList := TStringList.Create;
    finalization
      FList.Free;end.
      

  21.   

    感谢
    kaikai_kk
    (KAIKAI) 
    的总结,我再研究研究这个问题
      

  22.   

    var
      strName:string;
      Mycomp : TComponent;
    begin
      strName:=...;//根据用户操作来取得窗体的名称(窗体为动态创建的)
    Mycomp := FindGlobalComponent(strName);
      Tfrom(Mycomp).free;
      Tfrom(Mycomp):=nil;  //这句报错 left side cannot be assigned to
      

  23.   

    s11ss在8楼,一语道破天机,指出了问题的关键!
    kuangning在33楼系统深入地讲述了使用哈希表解决管理对象的方法。
    kaikai_kk在36楼写出了完整的demo,方法与8楼一致。
    -------------------------------------------------
    再次感谢所有关注问题的朋友!