如何在winEventFilter上取消WM_CLOSE?

时间:2014-03-04 14:50:35

标签: c++ windows qt qt4 signals

我创建了简单的handler inside my QApplication

bool QtMyApplication::winEventFilter ( MSG * msg, long * result ){
    switch(msg->message) {
        case WM_CLOSE:{
            qDebug() << "Haha Not killing appp =)";
            *result = 0;
            return true;
            break;
        }
    }
    return false;
}

我启动了我的应用程序,打开了任务管理器,在我的qt应用程序上调用End Task并在fiew秒获得了消息:

enter image description here

我在QWidget WinEvent上实施QMainWindow也得到了相同的结果:

bool QMyMainWindow::winEvent(MSG *message, long *result)
{
    switch(message->message) {
        case WM_CLOSE:{
            qDebug() << "Haha Not killing appp =)";
            *result = 0;
            return true;
            break;
        }
    }

    return QMainWindow::winEvent(message, result);
}

注意应用程序和任务管理器是从Administrator上的Windows Server 8 r2

启动的

所以我想知道如何处理WM_CLOSEQApplication上任务管理器发送的QMainWindow,以便不会显示End Programm消息?

2 个答案:

答案 0 :(得分:1)

更好(并且更少特定于平台)的方法是在主窗口中重新实现Qt closeEvent函数,而不是查找窗口系统关闭事件。假设您的应用程序设置了quitOnLastWindowClosed标志,则在窗口关闭后退出。

在主窗口代码中,实施closeEvent

void MainWindow::closeEvent(QCloseEvent *event)
{
    if(want_to_check)
    {
        int result = QMessageBox::critical(this, tr("Are you sure"),
                    tr("Are you sure you want to exit?"),
                    QMessageBox::Yes | QMessageBox::No);
            if(result==QMessageBox::Yes)
            {
                    // You can save files, etcetera, here
                    event->accept(); // The event is accepted, the window will close, and the application will exit
            }
            else
            {       // Your window will not close, and application will stay open
                    event->ignore(); // The window will stay open
            }
         }
    }

答案 1 :(得分:0)

从评论中看,真正的问题是如何在任务管理器关闭之前询问用户是否保存文件。这是一个奇怪的问题,因为从任务管理器关闭应用程序通常是最后的手段。

当用户尝试以常用方式关闭应用程序时,要求用户保存文件是完全合理的,例如从菜单中选择退出或单击主窗口上的关闭按钮。所以继续处理WM_CLOSE来做到这一点。

但请记住,还有很多其他方法可以终止进程。例如,用户可能会注销或关闭计算机,或者电源可能会熄灭,或者程序可能会因为错误而崩溃,或者可能是用户可能会尝试从任务管理器中删除该进程(可能因为它已挂起)

在这些情况下,您实际上没有选项来提出互动问题。

选项1:无需询问即可保存文件。您可以使用不同的文件名保存它,以便在用户有意跳过保存时原始文件仍然可用。下次应用程序启动时,它可以检查是否存在这些“紧急保存”中的任何一个,然后询问用户他/她想要使用哪个副本。

选项2:消除储蓄的概念。用户编辑内存中副本时,使文件保持最新。这使得所有事务都变得棘手,以便文件永远不会处于错误状态,但它适用于某些类型的应用程序。

选项3:每隔一段时间自动保存(这是实施选项2的简化方式)。这样,如果进程终止,用户只会丢失自上次自动保存以来的更改。