0

I have a WinAPI/Win32 application that also opens a console window (with debugging purposes) before the main window is opened). I added a safe check for when the main window gets its X button pressed it asks the "Are you sure?" thing. However, if I click X on the console, it kills the application right away without asking anything. Is there any way to prevent that? Here is a snippet of my code:

int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR args, int nCmdShow)
{
EnableDebug();
WNDCLASSA MainWindow = { 0 };
MainWindow.hbrBackground = (HBRUSH) COLOR_WINDOW;
MainWindow.hCursor = LoadCursor(NULL, IDC_ARROW);
MainWindow.hInstance = hInst;
MainWindow.lpszClassName = "WindowClass";
MainWindow.lpfnWndProc = WndProc;
ATOM result = RegisterClassA(&MainWindow);
if (!result)
{
    MessageBoxA(NULL, "Failed to register window class", "Error", MB_OK);
    return -1;
}
MSG msg = { 0 };
//here the app goes on


 //here is the start of the debug function
    void EnableDebug(){
    if (AllocConsole() == 0)
    {
        MessageBoxA(NULL, "Unable to create a debug window!", "Error", MB_OK);
        return;
    }
    freopen("CONOUT$", "w", stderr);
    SetConsoleTitleA("Debug Window");
    clog.clear();
DarkAtom
  • 2,589
  • 1
  • 11
  • 27
  • Start your program in the background in 1st place? – πάντα ῥεῖ Nov 24 '18 at 21:45
  • What value is that incomplete, useless snippet of code supposed to provide? – Ken White Nov 24 '18 at 21:53
  • 1
    What *problem* are you trying to solve? This question is merely asking, how to fix your proposed solution. – IInspectable Nov 24 '18 at 22:00
  • it seems you didn't understand the question. The snippet of code shows how I start my application and the console window. What I am asking is how to make the application not close when I close the console. – DarkAtom Nov 24 '18 at 22:24
  • You need to stop assuming that this can be fixed. You can get a notification about it that was designed to do some critical cleanup but you can't block it. Just like you can't stop other ways the user has available to end the app, like Task Manager. Give him a good reason to keep it running and you have little to worry about. – Hans Passant Nov 24 '18 at 23:18
  • 1
    if you create console only for debugging purposes - you easy can create usual window in your process (say create separate thread, `WC_EDIT` windows) and printf to it for debugging – RbMm Nov 25 '18 at 09:04
  • The code snippet shows your *proposed solution*, but not the problem. In general terms, what *problem* are you trying to solve? It appears that you are allocating a console for debug output. If that is all you need, you may consider using [OutputDebugString](https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx) instead. – IInspectable Nov 25 '18 at 13:34

2 Answers2

2

You can disable the close button of the console window to prevent accidentally terminating your application:

if( HWND hwnd = GetConsoleWindow() )
{
    if( HMENU hMenu = GetSystemMenu( hwnd, FALSE ) )
    {
        EnableMenuItem( hMenu, SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED );
    }
}
zett42
  • 25,437
  • 3
  • 35
  • 72
1

I believe you need to call SetConsoleCtrlHandler to provide a handler routine to handle the close event. Something like this:

BOOL WINAPI MyCtrlHandler (DWORD dwCtrlType)
{
    if (dwCtrlType == CTRL_CLOSE_EVENT)
        ...
}

SetConsoleCtrlHandler (MyCtrlHandler, TRUE);

You probably want to handle various values of dwCtrlType in various ways. Consult the documentation for details.

Paul Sanders
  • 24,133
  • 4
  • 26
  • 48
  • unfortunately this is not work. event if you not exit from app on close console event, after several seconds process will be force terminated external – RbMm Nov 24 '18 at 22:26
  • *csrss.exe* external call `TerminateProcess` with `STATUS_CONTROL_C_EXIT` - https://stackoverflow.com/questions/26404907/gracefully-terminate-a-boost-asio-based-windows-console-application#comment84600447_26405412 – RbMm Nov 24 '18 at 22:39
  • disabling the X button on the console could also be an option, but I think that is not possible. – DarkAtom Nov 24 '18 at 23:09
  • @DarkAtom It is possible, see my answer. – zett42 Nov 25 '18 at 16:39
  • something like this: `BOOL CALLBACK ConProc(DWORD dwCtrlType) { if (dwCtrlType == CTRL_CLOSE_EVENT) { SetConsoleCtrlHandler(ConProc, FALSE); FreeConsole(); return TRUE; } }` doesn't seem to work. – DarkAtom Nov 25 '18 at 20:10
  • No, see RbMm's comments above. – Paul Sanders Nov 25 '18 at 22:42