读书人

有关弹出窗口的一个莫名其妙的有关问题

发布时间: 2012-03-07 09:13:51 作者: rapoo

有关弹出窗口的一个莫名其妙的问题,急!!!!!
我在程序中使用了一个弹出窗口FrmPop
当在应用程序区使用
Application.CreateForm(TFrmPop,FrmPop)预先创建窗体时,一切正常。
当在应用程序区去掉这句,改为程序运行时动态创建窗体
FrmPop := TFrmPop.Create(Self)
程序执行时一切正常,但是在关闭程序时,出错
“Project TTSTErp.exe raised exception class EInvalidPointer With message ‘Invalid Pointer Operation’.”
单步调试,程序运行至dxfRes的finalization区语句
ImageList.Free

请问诸位,这个问题怎么解决


[解决办法]
self 改为 application
[解决办法]
delphi没有垃圾回收机制,所以每个创建的对象都需要有释放代码。Form是个对象,当然也不例外。但是如果在设计窗体时,给每个窗口,窗口上的每个按钮菜单之类的东西都生成一句free很麻烦。而且很难保证不会在要使用的时候它没有被释放掉了。
所以VCL设计的时候采用了变通的办法,对于TApplication,TForm这样的对象都可以在下面管理一系列窗体类的对象。就像一个树形一样,Application下面有若干个Form,Form下面又有若干Component。当销毁一个根的时候,它会依次先销毁它下面的每个子对象。
TFrmPop.Create(application)的意思就是,你把你的窗体托付给了application,因此这个窗体就会在程序结束的时候free掉
TFrmPop.Create(self)的意思是,窗体在你这段代码所在的窗体free的时候free掉。

出现退出的时候指针错误,最大的可能性就是一个对象被free了两次。比如你把窗体已经交给application了。但是你后面的代码又free了它,而且,没有给它赋值为nil。那么当application结束的时候,它还会去调用这个对象的free方法,但这时候已经没有这个对象了。
另一种可能是窗口内部的对象,或者代码free了一个application级别的对象。这样就算你没有任何窗口释放的代码,如果创建多个实例,因为在结束的时候对那个使用到的对象多次释放,同样会出现错误。
这一类内存相关的错误不容易调试,而且其实就是不报错,也可能有内存泄露错误。所以写代码时记住以下规则是避免错误的良好方法:
谁创建,谁释放。哪个层次创建,哪个层次释放。

对这个问题来说,如果你把窗口托付给了Application,那就表示它应该由application同生共死,所以,在application的整个生命周期里,应该只有单一的一次TFrmPop.Create(application)
同理如果参数是self,建议在主窗体的生命周期只有一次创建,而且这两种情况都不要去自己free窗口。
如果要自己管理这个窗口的生命周期,建议这样写
TFrmPop.Create(nil)
弹出窗口操作
TFrmPop.Free

读书人网 >.NET

热点推荐