I have a console window opened using "AllocConsole()`, besides the main Win32 window. The console window opens before the main one.
When I close the main window and the program returns from main function, the console remains open (and so does the process). It actually gets stuck somewhere in ntdll
, as the debugger shows on pausing the program from Visual Studio 2012.
Closing it by clicking on the X
button exits the process, but closing it with FreeConsole()
doesn't, the process remains working windowless.
CloseWindow(GetConsoleWindow())
doesn't close it, it minimizes it (!?!).
PostMessage(GetConsoleWindow(),WM_QUIT,0,0)
closes the window, but the process still remains working (visually, this is the same as "FreeConsole()`).
Occasionally, the program exits in the right way, but clicking on the X
button works every time.
How do I do the same thing that clicking on the X
button does?
To close or exit the Windows command line window, also referred to as command or cmd mode or DOS mode, type exit and press Enter . The exit command can also be placed in a batch file. Alternatively, if the window is not fullscreen, you can click the X close button in the top-right corner of the window.
If you run without debugging (Ctrl+F5) then by default it prompts your to press return to close the window.
Before the end of your code, insert this line: system("pause"); This will keep the console until you hit a key. It also printed "Press any key to continue . . ." for me.
Use PostMessage(wnd, WM_CLOSE, 0, 0)
to close the console window, but the problem is probably somewhere else in your program even if this works as a hotfix. The console window should close/disappear automatically when you return from your main()
or WinMain()
.
You need to destroy the console within the WM_DESTROY
message using FreeConsole
. I usually do this all in a class that wraps my console. This way it can redirect input/output to the console in the constructor and reset input/output in the destructor as well as alloc/destroy the console respectively.
However, without using a class or any wrappers, it can be done as follows..
Example:
#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);
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With