【发布时间】:2022-09-21 03:35:13
【问题描述】:
回到 BCB3 或 BCB5,我似乎记得有一种方法可以查看我的应用程序关闭的原因。如果用户关闭它,我想显示一个对话框,但如果计算机正在重新启动,我想优雅地关闭它。如何知道我的应用程序关闭的原因?
【问题讨论】:
标签: c++builder
回到 BCB3 或 BCB5,我似乎记得有一种方法可以查看我的应用程序关闭的原因。如果用户关闭它,我想显示一个对话框,但如果计算机正在重新启动,我想优雅地关闭它。如何知道我的应用程序关闭的原因?
【问题讨论】:
标签: c++builder
为了区分原因,您必须手动拦截并直接处理WM_(QUERY)ENDSESSION、WM_SYSCOMMAND 和WM_CLOSE 窗口消息。
不过,至少在这种情况下,WM_(QUERY)ENDSESION 就足够了。您可以让它设置一个标志,然后您可以在表单的OnCloseQuery 事件中查看,例如:
class TMyForm : public TForm
{
__published:
...
void __fastcall FormCloseQuery(TObject *Sender, bool &CanClose);
private:
bool SystemIsShuttingDown;
protected:
virtual void __fastcall WndProc(TMessage &Message);
...
};
void __fastcall TMyForm::FormCloseQuery(TObject *Sender, bool &CanClose)
{
if (!SystemIsShuttingDown)
{
// display dialog....
}
}
void __fastcall TMyForm::WndProc(TMessage &Message)
{
if (Message.Msg == WM_QUERYENDSESSION)
SystemIsShuttingDown = true;
else if (Message.Msg == WM_ENDSESSION && Message.WParam == FALSE)
SystemIsShuttingDown = false;
TForm::WndProc(Message);
}
【讨论】:
Application->Terminate() 只是将WM_QUIT 消息发布到主消息队列,然后消息处理程序将Application->Terminated 属性设置为true,这会导致Application->Run() 中的消息循环退出。任何仍处于活动状态的表单都将在进程清理期间被销毁,不会为它们触发任何事件。关闭Application->MainForm 将在触发OnClose(Query) 事件后调用Application->Terminate()。