除了主Win32窗口外,我还使用AllocConsole()打开了一个控制台窗口。控制台窗口在主窗口之前打开。
当我关闭主窗口并且程序从main函数返回时,控制台保持打开状态(过程也是如此)。它实际上被卡在ntdll中的某个地方,因为调试器显示暂停Visual Studio 2012中的程序。
单击X按钮关闭它会退出该过程,但是使用FreeConsole()关闭它不会,该过程仍然无窗口。 CloseWindow(GetConsoleWindow())不关闭它,它最小化它(!?!)。 PostMessage(GetConsoleWindow(),WM_QUIT,0,0)关闭窗口但该过程仍然有效(在视觉上这与FreeConsole()相同。
有时程序会以正确的方式退出,但每次都会点击X按钮。
如何点击X按钮做同样的事情?
答案 0 :(得分:5)
使用PostMessage(wnd, WM_CLOSE, 0, 0)
关闭控制台窗口,但问题可能是程序中的其他位置,即使这可用作修补程序。当您从main()
或WinMain()
返回时,控制台窗口应自动关闭/消失。
答案 1 :(得分:1)
您需要使用WM_DESTROY
在FreeConsole
消息中销毁控制台。我通常在包装我的控制台的类中执行此操作。这样它就可以在构造函数中将输入/输出重定向到控制台,并在析构函数中重置输入/输出,以及分别分配/销毁控制台。
但是,如果不使用类或任何包装器,可以按如下方式完成。
示例:
#include <windows.h>
#include <streambuf>
#include <fstream>
#include <iostream>
std::streambuf *CinBuffer, *CoutBuffer, *CerrBuffer;
std::fstream ConsoleInput, ConsoleOutput, ConsoleError;
void RedirectIO()
{
CinBuffer = std::cin.rdbuf();
CoutBuffer = std::cout.rdbuf();
CerrBuffer = std::cerr.rdbuf();
ConsoleInput.open("CONIN$", std::ios::in);
ConsoleOutput.open("CONOUT$", std::ios::out);
ConsoleError.open("CONOUT$", std::ios::out);
std::cin.rdbuf(ConsoleInput.rdbuf());
std::cout.rdbuf(ConsoleOutput.rdbuf());
std::cerr.rdbuf(ConsoleError.rdbuf());
}
void ResetIO()
{
ConsoleInput.close();
ConsoleOutput.close();
ConsoleError.close();
std::cin.rdbuf(CinBuffer);
std::cout.rdbuf(CoutBuffer);
std::cerr.rdbuf(CerrBuffer);
CinBuffer = NULL;
CoutBuffer = NULL;
CerrBuffer = NULL;
}
LRESULT __stdcall WindowProcedure(HWND Hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
{
switch(Msg)
{
case WM_CREATE:
AllocConsole();
RedirectIO();
std::cout<<"HELLO CONSOLE!"<<std::endl;
break;
case WM_DESTROY:
std::cout<<"BYE-BYE CONSOLE!"<<std::endl;
ResetIO();
FreeConsole();
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(Hwnd, Msg, wParam, lParam);
}
return 0;
};
int main()
{
WNDCLASSEX WndClass =
{
sizeof(WNDCLASSEX), CS_DBLCLKS, WindowProcedure,
0, 0, GetModuleHandle(NULL), LoadIcon(NULL, IDI_APPLICATION),
LoadCursor(NULL, IDC_ARROW), HBRUSH(COLOR_WINDOW + 1),
NULL, "WindowClass", LoadIcon (NULL, IDI_APPLICATION)
};
if(RegisterClassEx(&WndClass))
{
HWND WindowHandle = CreateWindowEx(0, "WindowClass", "Window Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, 500, 500, NULL, NULL, GetModuleHandle(NULL), NULL);
if(WindowHandle)
{
MSG msg = {NULL};
ShowWindow(WindowHandle, SW_SHOWDEFAULT);
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
答案 2 :(得分:-1)
#include <windows.h>
HWND myConsole = GetConsoleWindow(); //window handle
ShowWindow(myConsole, 0); //handle window
我使用的解决方案是将Linker-&gt; System-&gt; SubSystem设置为“Windows(/ SUBSYSTEM:WINDOWS)”而不是“Console(/ SUBSYSTEM:CONSOLE)”。这使得控制台甚至不出现,这避免了闪烁。第二个解决方案对我来说更好,它使第一个过时了。