我能在Win32 GUI应用程序中使用默认控制台吗?还是应该创建一个新的控制台?

3
我刚接触Windows API编程,用的是C++语言。我想要创建一个控制台,用于输出信息和通过GetMessage接收键盘命令。但是,如果我创建一个控制台应用程序,就无法使用GetMessage读取发送到该控制台的键盘消息。在这个项目中,通过GetMessage响应键盘输入是必需的。
当我在Code::Blocks 13.12中创建Win32 GUI应用程序(使用MinGW进行编译)并在开头调用AllocConsole时,我会得到错误5:“拒绝访问”。如果我先使用FreeConsole,那么FreeConsole将成功执行且没有错误;如果我接着使用AllocConsole,则会出现一个控制台窗口。MSDN对FreeConsole的描述如下:
“从其控制台中分离调用进程。”
这表明,在调用FreeConsole之前,已经存在一个控制台(即使我看不见它,也没有显式地创建它)。它是一个不可见的控制台,还是每次运行Code::Blocks项目时都会出现的控制台?使用FreeConsole然后AllocConsole是否毫无意义?是否有一种方法可以使已经存在的控制台可见(如果它是不可见的),并能够通过GetMessage接收键盘输入?
下面是一个展示此行为的简化代码示例:
#include <windows.h>

DWORD dw = 0;

int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nCmdShow)
{
    if (FreeConsole() == 0) {
        dw = GetLastError();
        return dw;
    }

    if (AllocConsole() == 0) {
        dw = GetLastError();
        return dw;
    }
    return 1;
}

为什么你想要使用GetMessage?无论如何,你可以在控制台应用程序中使用它。 - dsi
@dsi 我需要使用GetMessage的原因很复杂,但是如果你真的想知道,可以在这里阅读更多关于我的情况的信息:http://stackoverflow.com/questions/21139698/how-can-i-recognize-keyboard-input-in-c-with-windows-api-using-getmessage-in - Cerran
@dsi 我知道我可以使用GetMessage,但我不认为我可以使用它从键盘获取输入。在我之前的评论中链接的问题中,我问道:“有没有人有关于如何将键盘输入定向到我的控制台应用程序中的消息系统的任何提示?”对此,Hans Passant回答说:“这是不可能的。控制台窗口由完全不同的可执行文件管理,您不能干扰它。” - Cerran
@Cerran 好的,请看一下 MsgWaitForMultipleObjects 函数。它可能是你正在寻找的东西。 - dsi
@DavidHeffernan 嗯,那很有趣!我也在使用MinGW。只是为了确认,AllocConsole在没有先调用FreeConsole的情况下成功了吗? - Cerran
显示剩余2条评论
1个回答

1
当我在Code::Blocks中创建Win32 GUI应用程序(使用MinGW进行编译)并在开头调用AllocConsole时,我会收到错误5:拒绝访问
你的AllocConsole调用失败的原因是你实际上正在构建一个控制台应用程序。即使你使用WinMain,mingw仍将默认生成一个针对控制台子系统的可执行文件。你可以使用类似dumpbin的工具来检查PE头以确认我的结论。
使用-mwindows编译,以确保可执行文件针对GUI子系统。

1
看起来是正确的。感谢您的帮助!当我将-mwindows指定为链接器选项时,AllocConsole在不使用FreeConsole的情况下成功,并且新控制台出现了。我觉得很奇怪,因为我明确将其创建为“Win32 GUI项目”,而不是Code::Blocks中的“控制台应用程序”,我的项目中不会自动指定它。我仍然不知道为什么控制台是不可见的,但是有了-mwindows,我就不必担心这个问题,因为唯一创建的控制台是我明确创建的,默认情况下是可见的。 - Cerran
我尝试在我的可执行文件上使用dumpbin,但由于我不熟悉这个工具,我不确定如何找到相关信息。但我想-mwindows所做的差异基本上已经证明了你的观点。再次感谢,非常有帮助。 - Cerran
你需要运行命令 dumpbin /headers myexe.exe | more,而关注的值是所属子系统。可以是Windows CUI或者Windows GUI。 - David Heffernan
啊,是的,我忘记了 more。确实,如果没有 -mwindows,我会得到 3 子系统 (Windows CUI);而有了 -mwindows,我会得到 2 子系统 (Windows GUI) - Cerran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接