我要做的是在同一程序中安装我的Windows GUI应用程序和Windows控制台应用程序。所以我的GUI应用程序显示但我可以输出
std::cout
到控制台窗口。
我会输出像变量值等的东西。
答案 0 :(得分:3)
这是可能的,您必须记住,控制台链接目标是指具有控制台自动创建的32位应用程序,它们与GUI相同,因此您看到它是“自动创建”,这意味着您可以执行相同操作手动
您可以使用控制台制作控制台应用程序或使用控制台的GUI应用程序,由您自己决定,我个人会使用GUI制作控制台应用程序,因为您可以将GUI放入单独的线程中,即使是确保控制台总是在那里,所以它也为你提供了捕捉致命错误的机会。
这是一个从我自己的项目中截取的代码,它不是你想要做的但非常相似的
if (!AttachConsole(ATTACH_PARENT_PROCESS) ||\
GetLastError()==ERROR_NOT_SUPPORTED ||\
GetLastError()==ERROR_INVALID_HANDLE)
{
if (!AllocConsole())
{
// in this case we failed to alloc a console
// fatal error?
}
}
// at this point you already have a console or you created one
SetConsoleTitle("caption"); // you can set the console caption if you want to
freopen("CON","w",stdout);
SetConsoleOutputCP(CP_UTF8); // also this is needed when you want to use UTF8
当您想要从cmd.exe或其他控制台应用程序启动应用程序时,AttachConsole是一种特殊情况,这意味着它将继承控制台,据我记得您不能拥有多个控制台,所以如果你的进程继承了一个(比如,你已经拥有一个)你不能分配一个新进程,该函数将失败并且不会发生任何事情。如果您 从未 在这种情况下运行您的应用程序,您不需要这部分,但我认为这比这要复杂得多,因为Visual Studio可以将您的控制台输出附加到其中日志窗口意味着它实际上是一个非常好的“免费”调试工具。但我不确定它是否会起作用,从未尝试过。
AllocConsole可能会失败所以你也应该检查那个案例,在那个部分之后,你要么拥有自己的新控制台,要么以某种方式继承自另一个应用程序,这里是最重要的部分!你必须重新打开stdout,以便系统知道stdout应该进入这个控制台。
答案 1 :(得分:1)
尝试以下方法来生成一个控制台,很久以前从其他地方捡起它,但不记得给谁信任:
static const WORD MAX_CONSOLE_LINES = 500;
int hConHandle;
long lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
// allocate a console for this app
if( AllocConsole() )
{
// set the screen buffer to be big enough to let us scroll text
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
coninfo.dwSize.Y = MAX_CONSOLE_LINES;
SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE),
coninfo.dwSize);
// redirect unbuffered STDOUT to the console
lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );
// redirect unbuffered STDIN to the console
lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "r" );
*stdin = *fp;
setvbuf( stdin, NULL, _IONBF, 0 );
// redirect unbuffered STDERR to the console
lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stderr = *fp;
setvbuf( stderr, NULL, _IONBF, 0 );
// make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
// point to console as well
std::ios::sync_with_stdio();
}