Delphi动态创建窗口可能出现的问题

来源:互联网 发布:淘宝平台如何让新产品 编辑:程序博客网 时间:2024/06/05 04:32

      程序中经常会用到动态创建的窗口,而这其中用得最多的应该还是调用DLL封装的窗口,代码网上是一大堆了,所以在这里说说动态创建窗口后可能遇到的麻烦。

 

      创建的窗口分模式和非模式窗口两种,第一种是对话框式的窗口,焦点是封装的,只有关闭后才能激活主窗口,而第二种是可以与主窗口进行焦点切换。模式窗口创建时通常不会出现什么问题,因为用的是showModal(),并直接用了try finally进行的显示、关闭、释放,程序顺序执行,所以创建消毁都很正常。非模式窗口用的是show(),所以需要手动释放窗口,而麻烦也经常会出现在这里。释放窗口有3种方法,一般都会写在窗口的close事件里:

 

1. formName.free;formName:=nil;

 

光是Free是不行的,因为只是这样的话引用窗口实例的指针还是存在的,那样你就没法在第二次动态调用窗口时显示窗口了,因为你在调用时肯定需要判断窗口是否已经调用并创建,否则一定会出问题,而且如果在调用显示窗口后直接关闭整个程序也是很有可能报错的。

 

2. freeAndNil(formName)

 

这个是上面代码的合集,更方便。

 

3. Action:=caFree;FormName:=nil;

 

这个是在窗口关闭时同步释放,然后销毁。

 

      如果是直接创建普通的窗口,那是没有任何问题的,就算你动态调用了窗口,然后直接关闭主窗口也能顺利结束程序,可是如果在窗口中使用了第三方控件的话可就不一定能顺利关闭了。像我使用FlashPlayerControl控件时就遇到了动态调用窗口后直接关闭主程序的报错,要么就是runtime error 216 ,要么就是内存读取错误,经过调试才发现是第三方控件引起的,用过前两种方法都不行,然后发现,只要先关闭动态调用的窗口再关闭主程序就没问题,没办法,所以在退出主程序之前调用了Findwindow(nil,FormName)来找出调用的窗口并向窗口发送关闭的消息,可就算是这样窗口也不能同步释放,依然报错,所以才用了第三种,这样的调用才算是完成了真正意义上的“动态”调用。

 

      接下来还碰到了更加有趣的问题,在Delphi2010里,我发现如果动态调用上面创建的这样一个非模式窗口,并且将窗口风格设置为无边框标题栏时,用消息来控制拖动窗口是无效的,而且在窗口里使用ApplicationEvent控件也是没任何反应,可窗口标题栏的功能是正常的,能拖动,于是试着调用显示了窗口句柄,发现读取窗口句柄会出错,所以我想这问题应该是出在窗口句柄上了,但查了很多资料都没找到答案,大概是动态调用无标题栏非模式窗口的人不多,不过我也不打算在这样的问题上多花脑力,也许更多人愿意用多线程去开这样的非模式窗口,但我离用这样强大功能的时候还很远,希望有知道答案的能说说。