我做了个MDI应用程序,假如里面有n个子窗体,
当我在MDI form上点击关闭按纽时候 ,触发OnClose事件,我在OnClose响应里写上一些释放全局单元里的全局类对象,但是我的MDI Child切换时候有一个子窗体A在它的OnActivate响应里会引用到全局单元里的全局类对象,这样导致关闭时候在某些情况下程序会抛出exception class EAccessViolation with message ' Access violation at address XX地址 异常 ...'我现在想求教两个问题:
1.就是关闭程序时候,我的主窗体的OnClose响应和子窗体的释放顺序(经过测试发现主窗体的OnClose响应处理之后才会出现子窗体的释放..(最好能帮我理顺下点击关闭时候的时候父窗体和子窗体(假定在程序中已经创建了多个子窗体)会有哪些操作,及产生事件的顺序(如:OnClose)
2.主窗体的OnClose响应为什么不需要里面加上Inherited代码,只需要将需要手动释放的的空间释放就行..,这里面是不是有个隐含代码的自动调用父类的关闭

解决方案 »

  1.   

    楼主这个思路似乎是有问题的。
    1.OnClose事件的帮助看一下,里面不应该牵涉释放的东西的?全局对象的释放应该写在主窗口的OnFree事件里面。
    2.主窗口的Class是从什么类继承下来的,如果你的主窗口不是自己手工继承的,那么就会默认去调用VCL的事件,就不需要Inherited。你先看看Inherited这行代码是代表什么吧
      

  2.   

      现在开始具体的求救你个问题,假如我在子窗体的A的OnActivate里有个自定义函数里面需要调用全局单元里的自己定义的一个全局类对象MyClass,当我在多个子窗提切换完后,注意假定当前MDIChildCount不为0而且等于4时候,且子窗体A也存在了,此时当我点击关闭主窗体的后,我开始将全局对象的释放放在主窗体的OnClose里处理,但是有可能发生抛出exception class EAccessViolation with message....;自己已经找出了原因就是当关闭主窗体时候,子窗体A在某些情况下会再次激活一次(具体原因我就不说了,高手应该明白),所以就会调用A的OnActivate里的代码,而代码里引用了全局对象,但是此时全局对象MyClass
    已经释放,原因就是我把MyClass的释放代码放在了主窗体的OnCLose。
    -----------------请教各位高手如何既保证全局对象的释放,又能使得程序不暴错误。
      

  3.   


    try
      FT.Free;
    except
    end;
      

  4.   

    你说全局对象的释放应该写在主窗口的OnFree事件里面。
    我还真没用过OnFree事件,有吗,
    我现在的解决方法是将A的在OnActivate里引用到的全局对象换成其他的,不在OnActivate用全局对象了
      

  5.   

    OnClose里
      form1.Action=cafree;
      

  6.   

    OnClose里
      form1.Action=cafree;
      

  7.   

    就是当子窗体B覆盖A时候及C时候我测试的时候在某些部分添加断点,发现当关闭主窗体时候,先运行主窗体的OnClose,然后会进入A的OnActivate,(这只是在某些情况下发生),我个人认为当关闭主窗体时候,B窗体或者其他的子窗体也会关闭,然后在覆盖在A窗体的其他的激活子窗体释放时候,有可能发生A子窗体获得焦点,然后释放,所以在A窗体的OnActivate事件处理里的引用全局变量时候会抛出异常,因为我在主窗体的OnClose里已经将这个全局对象释放了,该全局对象不可访问...
      

  8.   

    楼主应该看一下李维的关于VCL架构那本书,或者看点OOP方面的东西。
    作为窗口来说,其实也是一个对象,有自己的CREATE,也有作为对象的FREE(可能在DELPHI里面不是ONFREE事件,而是叫OnDestroy,很久没有用DELPHI了)。在类(窗口)的OnCreate事件里面,一般会负责创建这个类(窗口)需要的变量,放到你的MDI来说,就是你的主窗口里面创建的全局变量。而窗口的OnClose只是作为窗口关闭时触发的事件,而窗口作为对象来说,这个时候他的实例没有释放,所以在OnClose事件里面就释放变量就会存在一定的问题,比如说,你的窗口不是主窗口,你释放了变量,下次你不调用CREATE而直接Show的时候,你的那些变量已经释放了,就会出错。
    至于关闭主窗口的时候和子窗口的事件的调用关系,你可以看看MDIForm类关于Close事件的代码。但OnClose事件先于子窗口的OnActivate是很有可能的,
      

  9.   

    这位仁兄,我也想买李维的书啊,就是现在买不到了,现在开始在公司用Delphi开发,刚开始的有些细节确实不很清楚,所以需要各位的顶力帮助
      

  10.   

    在MDI中,你要关闭母窗体时,必须判断这个APPLICAION已经创建了多少窗体.所以,在MDI中,你最好就是创建子窗体和那种SHOWMODAL(就是用完一定要关的窗体.)
    在MDI关闭的时候,你得做个循环.
     var 
     i:integer;
     begin
       for i:=Application->MDIFORM->ChildFormCount-1 downto 0 
       begin        
         Application->MDIFORM->ChildForm[i]:=Close();
    //     delete  Application->MDIFORM->ChildForm[i];
    //     Application->MDIFORM->ChildForm[i]:=NULL;
       end end
    =====================
    把他们都释放掉.