将数据传递给Windows控制台控制处理程序

Passing Data to Windows Console Control Handler

本文关键字:控制台 控制 处理 程序 Windows 数据      更新时间:2023-10-16

我正在编写一个简单的游戏引擎,我在处理Windows主机事件时遇到了麻烦;具体来说,我不知道如何将自定义数据传递给回调处理程序。

我首先调用这段代码来指定我的回调函数:

SetConsoleCtrlHandler((PHANDLER_ROUTINE)WindowsSystemManager::ConsoleControlHandler, true);

我的静态成员回调函数定义为:

bool WINAPI WindowsSystemManager::ConsoleControlHandler(DWORD controlType){
    if(controlType == CTRL_CLOSE_EVENT){
        MessageBox(NULL, L"Close Event Captured", L"Close Event Captured", NULL);
    }
    return true;
}

一切工作正常-当我点击控制台的关闭按钮,这个消息框弹出。唯一的问题是,我需要调用代码,在这种类型的关闭(以及其他清理)上刷新日志缓冲区到日志文件,并且Logger实例是我的WindowsSystemManager中的成员。

我已经处理了一个类似的问题,通过使用SetWindowLongPtr和GetWindowLongPtr成功地传递自定义数据到窗口句柄,但我找不到任何关于如何用控制台控制处理程序做这种类型的事情的信息。任何想法吗?

编辑:我得到了这个功能工作基于MSalters的建议。控制台控制处理程序的最终代码如下:

bool WINAPI WindowsSystemManager::ConsoleControlHandler(DWORD controlType){
    BerserkEngine* engine = (BerserkEngine*)GetWindowLongPtr(GetConsoleWindow(), GWLP_USERDATA);
    if(controlType == CTRL_CLOSE_EVENT){
        engine->~BerserkEngine();
        PostQuitMessage(0);
    }
    return true;
}

我在WindowsSystemManager构造函数中设置了这个自定义数据指针:

SetWindowLongPtr(GetConsoleWindow(), GWL_USERDATA, (LONG_PTR)this->engine);

我不知道你为什么需要这个。你可以有多个窗口,但只能有一个控制台。

然而,GetConsoleWindow将为您提供控制台HWND,您可以调用SetWindowLongPtr。不是很干净(你不应该在你不管理的窗口上这样做),但它可能只是工作。