Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ Windows: How to close a console window?

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?

like image 371
Vladivarius Avatar asked Mar 08 '14 16:03

Vladivarius


People also ask

How do I close the console window?

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.

How do I close the console in Visual Studio?

If you run without debugging (Ctrl+F5) then by default it prompts your to press return to close the window.

How do you stop a screen in C++?

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.


2 Answers

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

like image 131
pasztorpisti Avatar answered Sep 19 '22 16:09

pasztorpisti


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);
            }
        }
    }
}
like image 23
Brandon Avatar answered Sep 19 '22 16:09

Brandon