系统关闭窗体的事件顺序为:
OnCloseQuery ----> OnClose ----> OnDestroy
下面的代码说明问题:
- unit Unit3;
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs;
- type
- TForm3 = class(TForm)
- procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure FormDestroy(Sender: TObject);
- private
- { Private declarations }
- public
- { Public declarations }
- end;
- var
- Form3: TForm3;
- implementation
- {$R *.dfm}
- procedure TForm3.FormClose(Sender: TObject; var Action: TCloseAction);
- begin
- MessageBox(Handle,'正在关闭窗体!','提示',MB_OK or MB_ICONWARNING);
- end;
- procedure TForm3.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
- begin
- if MessageBox(Handle,'你确定要关闭该窗体吗?','提示',MB_YESNO or MB_ICONINFORMATION) = IDYES then
- CanClose:=True
- else
- CanClose:=False;
- end;
- procedure TForm3.FormDestroy(Sender: TObject);
- begin
- // 必须用Application的方法了
- Application.MessageBox('释放窗体','提示');
- end;
另外 从网友 http://echocancer.spaces.live.com/blog/cns!97776b41bf0a7f5d!141.entry 出摘的 文章:
程序不能关机?看看你在OnCloseQuery里是不是写了代码!
今天终于解决了程序不能关机的问题,都是OnCloseQuery惹得祸!
程序里有多个窗体,其中有两个在OnCloseQuery里写了处理代码,导致程序不能关机。
一开始我安网上找到的办法试图在主窗口中截获WM_QUERYENDSESSION消息然后返回Msg.Result=1。发现这个消息根本就没有传到主窗口来,后来我又怀疑是不是Application.OnMessage把这个消息给拦截掉了,后来发现也不是的。最后才弄清楚如果一个窗体的OnCloseQuery事件中如果写了代码那么WM_QUERYENDSESSION消息就传不过去了msg.result会返回0,关机事件也就停止了。因为程序中有两个窗体的OncloseQuery中都写了代码所以WM_QUERYENDSESSION消息根本就传不到主窗口。最后在那两个窗口中拦截WM_QUERYENDSESSION消息,强制将msg.result返回1就解决了问题。
这次的问题让我对windows的消息机制又有了更深的了解,所有的windows的广播消息都是逐窗口传递的。
http://blog.csdn.net/procedure1984/article/details/5418279