从另一个线程关闭WINAPI中的重定向控制台

时间:2014-07-10 21:40:57

标签: c++ winapi io console

所以我在主OpenGL窗口旁边的Win32中创建了一个控制台,以便用它为我的事件循环生成命令。但是,我遇到了一些困难。控制台使用以下循环重复检查cin输入:

while (*loopEnabled)
{
    string str;
    getline(cin, str);

    if (str == "quit")
    {
        PostQuitMessage(0);
        return;
    }
}

这是在我的主窗口的一个单独的线程中运行,并且意味着发送退出事件并退出。但是,首先,退出消息似乎并不完全有效。似乎发生的是,这只允许关闭主窗口 - 我仍然需要手动关闭主窗口。似乎PostQuitMessage没有为我处理适当的Windows事件?也许我在这里犯了一些错误。

更严重的问题实际上是从控制台线程外部退出此事件循环而不必输入随机输入以使其移过常量getline并在条件失败时退出。我试图通过尝试输入虚假输入来做到这一点,但我无法做到这一点。它可能与重定向到控制台的输入有关。也许例外可能有效吗?我不知道。

这里是将io重定向到控制台的代码:

AllocConsole();

handleOut = GetStdHandle(STD_OUTPUT_HANDLE);
int hCrt = _open_osfhandle((long)handleOut, _O_TEXT);
hfOut = _fdopen(hCrt, "w");
setvbuf(hfOut, NULL, _IONBF, 0); //Can assign custom buffer here! Currently no buffering (_IONBF)
*stdout = *hfOut;

handleIn = GetStdHandle(STD_INPUT_HANDLE);
hCrt = _open_osfhandle((long)handleIn, _O_TEXT);
hfIn = _fdopen(hCrt, "r");
setvbuf(hfIn, NULL, _IOLBF, 256);
*stdin = *hfIn;

要点: 我有窗户和控制台。我关闭窗口,它等待控制台输入以获得循环中的getline。我键入"退出"在控制台中,控制台循环结束但主窗口没有注意到。救命? .-。我对Windows编程很陌生。

1 个答案:

答案 0 :(得分:1)

PostQuitMessage()WM_QUIT消息发布到正在调用它的线程的消息队列中。您的控制台循环在其自己的线程中运行,因此在不同线程中运行的主窗口将永远不会收到WM_QUIT消息。要将WM_QUIT消息发布到另一个帖子中的窗口,请改用PostMessage()

在用户在控制台中键入一行文本之前,

std::getline()不会退出。如您所见,这不允许您终止控制台线程。 std::cin没有告诉您文本何时可供阅读,因此您无法在有需要阅读的内容时调用std::getline()。请尝试切换为ReadConsole()ReadConsoleInput()。然后,您可以使用WaitForSingleObject()来检测何时有可供读取的输入。这将使您有机会监视线程中每次读取之间的任何终止条件,例如布尔变量。或者,使用等待的event object来表示终止,然后您可以使用WaitForMultipleObjects()同时等待终止和输入,并且它会告诉您要对哪个信号进行操作。