C++ 如何防止(C+;+;)控制台窗口在单击关闭窗口X后关闭

C++ 如何防止(C+;+;)控制台窗口在单击关闭窗口X后关闭,c++,windows,signals,C++,Windows,Signals,我有以下代码来演示这个问题。 安装了处理ctrl-C(ctrl\u C\u事件)和窗口关闭(ctrl\u close\u事件)的处理程序。 输出有关可能操作的信息后,将启动一个无限循环,等待用户控制C或关闭控制台窗口。 在这两种情况下,都会显示一个带有“是/否”选项的消息框。 对于ctrl-C,这可以正常工作,但在关闭时单击“否”无效。更糟糕的是,5秒钟后,整个系统就关闭了。这完全符合文件,所以我的问题是: 有没有其他方法可以让我返回到应用程序,而不是用5秒钟来祈祷,然后被枪杀? 守则: #in

我有以下代码来演示这个问题。 安装了处理ctrl-C(ctrl\u C\u事件)和窗口关闭(ctrl\u close\u事件)的处理程序。 输出有关可能操作的信息后,将启动一个无限循环,等待用户控制C或关闭控制台窗口。 在这两种情况下,都会显示一个带有“是/否”选项的消息框。 对于ctrl-C,这可以正常工作,但在关闭时单击“否”无效。更糟糕的是,5秒钟后,整个系统就关闭了。这完全符合文件,所以我的问题是: 有没有其他方法可以让我返回到应用程序,而不是用5秒钟来祈祷,然后被枪杀? 守则:

#include <stdio.h>
#include <Windows.h>
#pragma comment(lib, "user32.lib")

BOOL myCtrlHandler(DWORD fdwCtrlType)
{
    auto userwantstoquit = [](HWND wnd = nullptr)
    {
        return MessageBox(
            wnd,
            "Do you really want to stop?",
            "CTRL tester",
            MB_YESNO | MB_ICONWARNING | MB_DEFBUTTON2 | MB_APPLMODAL
        ) == IDYES;
    };
    switch (fdwCtrlType)
    {
    case CTRL_C_EVENT:
        // Console window handle is passed to prevent window interaction
        // return TRUE will stop the signal, allow app to go on
        // return FALSE will allow the other handlers to be called.
        return !userwantstoquit(GetConsoleWindow());
    case CTRL_CLOSE_EVENT:
        // passing console window handle will not display the box
        return !userwantstoquit();
    default:
        // use default handlers for everything else
        return FALSE;
    }
}

int main()
{
    SetConsoleCtrlHandler(myCtrlHandler, TRUE);
    puts("Press ctrl-C or close the console window using x");
    while (true);
    return 0;
}
#包括
#包括
#pragma注释(lib,“user32.lib”)
布尔myCtrlHandler(DWORD FDWCTRL类型)
{
自动用户WANTSTOQUIT=[](HWND wnd=nullptr)
{
返回消息框(
wnd,
“你真的想停下来吗?”,
“CTRL测试仪”,
MB|u YESNO | MB|u i警告| MB|u debutton2 | MB|u应用程序
)==田园诗;
};
开关(fdwCtrlType)
{
案例控制事件:
//传递控制台窗口句柄以防止窗口交互
//返回TRUE将停止信号,允许应用程序继续运行
//return FALSE将允许调用其他处理程序。
return!userwantstoquit(GetConsoleWindow());
案例控制关闭事件:
//传递控制台窗口句柄不会显示该框
return!userwantstoquit();
违约:
//对其他所有内容使用默认处理程序
返回FALSE;
}
}
int main()
{
SetConsoletrlHandler(myCtrlHandler,TRUE);
放置(“按ctrl-C或使用x关闭控制台窗口”);
虽然(正确);
返回0;
}
假设在CTRL-CLOSE信号的情况下,可能已经执行了任意数量的(控制台)清理例程,因此在这个阶段没有返回的方法。
那么,尝试添加windows消息泵可能是唯一可能的解决方案,但对于控制台应用程序来说,这显然有点过头了。但这可能是唯一的方法,因为通过使用MessageBox(user32.dll),通过CtrlHandler函数将不会发生CTRL_注销或CTRL_关闭事件。

您的程序无法控制控制台窗口,因此您真的无能为力。控制台主机(conhost.exe)通过会话服务器(csrss.exe)发送此事件在进程中注入一个新线程。对于ctrl+close事件,服务器在此线程上等待5秒(默认),然后终止进程。这是没有出路的;这个过程必须结束。如果需要应用程序在控制台关闭后继续运行,请使用未连接到控制台的后端服务器进程创建客户端/服务器体系结构。然后,如果用户界面客户端被杀死,你可以用一个新的控制台重新启动它。@Someprogrammerdude我想你是对的。我打算研究一个隐藏窗口的概念,以便更早地获取信息,请参见。但是它看起来很脆弱,虽然不难。@ErykSun我会深入研究,没有那么多经验,但是有一些例子,所以我会尝试一下。谢谢