求助,有关主窗体和子窗体的问题在主窗口上有一个按钮,点击它时显示子窗口,而子窗口关闭后,点击它能重新把子窗口打开,我做了响应函数,感觉不是特别好:
使用这函数在反复打开关闭时,易报错,
错误为:"access violation at address D10C0202. Read of address D10C0202."
或是:"access violation at address 007C8749 in module 'CT.exe'. Read of address 079B051C."几个响应为:
点击按钮打开子窗口:
//在多次打开后,点击按钮时开始报以上的错,报错后子窗口不打开
procedure TFormMain.N22Click(Sender: TObject); 
begin
  if (Form_Child = nil) or Form_Child.mFormClose then
    Application.CreateForm(TForm_Child, Form_Child);
  Form_Child.Show; 
end;子窗口:
  public
    { Public declarations }
    mFormClose:boolean;
子窗口关闭时的响应函数为:
procedure TForm_Child.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  Action:=caFree;
  mFormClose := True;
end;我猜想,可能是打开子窗口的响应函数不合理,请高手指教,谢谢!·

解决方案 »

  1.   

    Form没关闭时再Create Form应该会出错
      

  2.   

    窗体创建的时候是分配窗体内所有对象的内存,并窗体指针指向窗体.free方法会释放窗体的所有对象及成员,但指针还是指向原来的内存地址,所以free掉后一定要将窗体指向nil,或用freeandnil方法free和指nil同时操作.所以你的问题来了
    if (Form_Child = nil) or Form_Child.mFormClose then
    这句代码在对象存在的时候,即没有销毁的时候,你下面直接执行Form_Child.Show;是正确的,但是当你关闭的时候,你用了cafree,所以窗体会销毁,但指针不指空,那么Form_Child = nil是返回false,也就会继续判断Form_Child.mFormClose,这时候FormClose已经不存在了,当然内存就报错了
      

  3.   

    procedure TForm_Child.FormClose(Sender: TObject;
      var Action: TCloseAction);
    begin
      Action:=caFree;
      mFormClose := True;
      Form_Child:=nil; //添加这句
    end;
      

  4.   

    其实你的mFormClose变量是没有什么用的.既然你要销毁,那么就要使用
    Action:=caFree;
    Form_Child=nil;
    创建也没必要这么判断,直接改成
     if Assigned(Form_Child)then
        Application.CreateForm(TForm_Child, Form_Child);
      Form_Child.Show;
      

  5.   

    or操作在前条件是true的情况下不会继续后续判断,所以你只改close事件,加Form_Child=nil;这句也不会出错,即使这时你的Form_Child.mFormClose不存在
      

  6.   

    那为什么有的时候不报错呢?一般说前五次~前十次都可以,打开的次数太多或是打开/关闭的太快才会报错,这是什么原因呢?对阿,这是个问题不如用form.hide好不好?
      

  7.   

    没有必要用hide啊,这样资源是不会释放的,当你子窗体多的时候就很耗费资源了
    fenger8293(http://www.pceggs.cn/pgComDefault.aspx?ID=191016) 的答案已经够你使用了内存出错的概率是随机的  内存释放的时候如果没有写入的操作其内存里的数据仍旧保存着上一次的数据也就是说虽然你没释放也不一定会出错 但是是迟早会出错 这个用在指针数据的时候就能体现的明显些 而且如果不注意很容易后面发生错误之后很难找到问题发生的地方
      

  8.   

    先判断是否有这个东西
    可以用findComponent 函数来判断