Question

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?

Was it helpful?

Solution

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().

OTHER TIPS

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);
            }
        }
    }
}
#include <windows.h>

HWND myConsole = GetConsoleWindow(); //window handle
ShowWindow(myConsole, 0); //handle window

The solution I wound up using was to set Linker->System->SubSystem to "Windows (/SUBSYSTEM:WINDOWS)" instead of "Console (/SUBSYSTEM:CONSOLE)". This makes the console not even appear, which avoids flickering. The second solution was better for me, and it rendered the first obsolete.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top