系统关闭没有触发TForm的OnClose、OnDestroy?(100分)

  • 主题发起人 主题发起人 老头
  • 开始时间 开始时间

老头

Unregistered / Unconfirmed
GUEST, unregistred user!
; Windows关机、重启、注销而引起程序关闭时,为何没有触发TForm的OnClose、OnDestroy事件?
这样动态建立的东西会不会产生内存泄漏?
 
试一试CLOSEQUERY
就知道了
 
procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
begin
showmessage('ooo');
canclose:=false;
end;
应该触发了TForm的OnClose、OnDestroy事件,在CLOSEQUERY中释放就行了
 
晚了一步,嘿!
 
我知道会触发OnCloseQuery,但我问的是OnClose与OnDestroy。
将正常关闭之前应该做的事放在OnCloseQuery虽然可行,但影响程序的可读性。
另外这样说来,TForm组件中OnClose与OnDestroy这两个属性不是形同虚设?

先将另一个问题独立出来吧:如果自己建立的组件或者数据(也没有Owner)在程序结束之前不释放,到底会不会产生内存泄漏?

再引出一个问题:如何截获与区分关机、重启、注销、强行结束任务(按Ctrl+Alt+Del后)与正常的关闭,相关的Message常量?

问题的来源:
我在编写一个托盘图标程序实现自定义快捷菜单,随系统启动,希望在关机之前自动保存设置。
题外:我发现用Delphi很多东西都要绕弯子,例如每个程序都有一个隐藏的主窗体,在我的程序中还不得不再加一个(我本身只需要一个属性窗体,可是如果不建立一个永远不显示的作为主窗体,属性窗体关闭时就会关闭整个程序。不要跟我说用Hide,我本来是的,可是要完全识别不该Hide的时候太困难了,简单的说吧,这时Windows都无法关机。)。哦,对于托盘程序,如果同时处理左键单双击还有一个问题:我想在双击时显示属性窗,单击弹出PopupMenu,双击时必然先接收了两次单击,如果双击之后没有其它动作,属性窗将永远不会显示完整,因为它在等待实际上也还没显示的PopupMenu消失(如果在属性窗Show之后加入Application.ProcessMessages,两者会同时显示出来)。大家不知道看明白没有,如果你做过应该很清楚,难题是如何取消已经弹出的PopupMenu。
 
我知道会触发OnCloseQuery,但我问的是OnClose与OnDestroy。
将正常关闭之前应该做的事放在OnCloseQuery虽然可行,但影响程序的可读性。
另外这样说来,TForm组件中OnClose与OnDestroy这两个属性不是形同虚设?

先将另一个问题独立出来吧:如果自己建立的组件或者数据(也没有Owner)在程序结束之前
不释放,到底会不会产生内存泄漏?

再引出一个问题:如何截获与区分关机、重启、注销、强行结束任务(按Ctrl+Alt+Del后)
与正常的关闭,相关的Message常量?

问题的来源:
我在编写一个托盘图标程序实现自定义快捷菜单,随系统启动,希望在关机之前自动
保存设置。
题外:我发现用Delphi很多东西都要绕弯子,例如每个程序都有一个隐藏的主窗体,
在我的程序中还不得不再加一个(我本身只需要一个属性窗体,可是如果不建立一个永远
不显示的作为主窗体,属性窗体关闭时就会关闭整个程序。不要跟我说用Hide,我本来是
的,可是要完全识别不该Hide的时候太困难了,简单的说吧,这时Windows都无法关机。)。
哦,对于托盘程序,如果同时处理左键单双击还有一个不大不小的问题:我想在双击
时显示属性窗,单击弹出PopupMenu,双击时必然先接收了两次单击,如果双击之后没有其
它动作,属性窗将永远不会显示完整,因为它在等待实际上也还没显示的PopupMenu消失(如
果在属性窗Show之后加入Application.ProcessMessages,两者会同时显示出来)。大家不
知道看明白没有,如果你做过应该很清楚,难题是如何取消已经弹出的PopupMenu。
 
>>不要跟我说用Hide,我本来是
>>的,可是要完全识别不该Hide的时候太困难了,

把你的close语句改成hide不中么?
 
回doxpix:
莫名其妙,看懂了再发言行不行
 
实验证明:onclose被触发,OnDestroy没有触发
 
sorry,发错地方了。
 
OnDestroy没有触发,以前我写过一个程序,每次正常关闭才会记录下东西,而通过WINDOWS
关机的就没有记录下来。于是我就抓的WINDOWS的关机信息,倒没有想哪几个没有激活。
 
回张剑波:
1、OnCloseQuery答非所问;
2、“应该触发了TForm的OnClose、OnDestroy事件,在CLOSEQUERY中释放就行了”,既
然“触发了TForm的OnClose、OnDestroy事件”,还提“CLOSEQUERY”干吗,简直是... 另
外,如果“canclose:=false;”,windows都无法关机!!!
3、“实验证明:onclose被触发,OnDestroy没有触发”,什么实验,如何证明?

你的三次发言都自相矛盾,拜托别浪费大家的时间。
 
zhangkan:
关机消息是哪个?重启、注销、强行结束任务、正常关闭呢?
 
> 实验证明:onclose被触发,OnDestroy没有触发
我用以下程序试了,一个也没触发。
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var path:String;
inifile:Tinifile;
begin
path:=ExtractFilePath(paramstr(0));
inifile:=Tinifile.Create (path+'text.ini');
inifile.WriteString('FormClose','Close','触发了Close事件');
end;

procedure TForm1.FormDestroy(Sender: TObject);
var path:String;
inifile:Tinifile;
begin
path:=ExtractFilePath(paramstr(0));
inifile:=Tinifile.Create (path+'text.ini');
inifile.WriteString('FormDestroy','Destroy','触发了Destroy事件');
end;
 
消息么,我记得是 wm_endsession WM_QUERYENDSESSION,后面的先发。
内存泄漏这个顾虑太可笑了。操作系统保证在进程结束时释放所有进程私有内存就不会
有你所担心的内存泄漏。你应当操心的是当程序运行个三年五载操作系统还有没有内存
可以分配(不要每干点活就吃点内存)。
 
>>题外:我发现用Delphi很多东西都要绕弯子……
Delphi 是要绕弯子,不过主要问题是在 Object Pascal 而非 VCL 上。Delphi 并不推荐
在程序的主控函数里面写太多的代码,但是程序怎么结束???主窗口正好可以很简单地
解决这个问题。你的问题解决的方法就是把你的属性窗口用自己的代码创建。

当你享受 Delphi 便利的时候从来不说什么,稍微有一点小问题就说是要绕弯子,
直来直去的编程方式很多,不要使用 VCL 就不绕了。
 
mikedeakins:
讲得不错。关于内存泄漏如果我很顾虑就不会这样问了,我对Windows底层不了解,
倒是怀疑那些狗屁教材在这方面的误导。至于绕弯子,我认为Object Pascal很完美,
VCL(不是指VCL架构,而是Delphi自带的那些东西)很差,尤其是MaskEdit,没有任何
使用价值,居然用了几千行的代码。
 
; 问题解决,就是WM_ENDSESSION,MSDN上如果写成 WM_EndSession可能就注意到了。
:-)实际上,我原来问的(第一句)没人提及,按理说,OnClose也应该包装到TForm的
WM_ENDSESSION处理中。
我看了一下TForm的源文件,对于消息处理搞清楚了一点,但还是有一些不明白...
算了,不提了。
 
多人接受答案了。
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
后退
顶部