I am trying to open the console from my main program (Win32). I found some code, and it works, but I don\'t understand it. The problem I\'m happening is that when I click X
I do not think this is possible. From the MSDN documentation for a HandlerRoutine, there's this sentence.
The CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals give the process an opportunity to clean up before termination.
I read this as saying that CTRL_CLOSE_EVENT is advisory, and that the process is going to exit regardless. My guess is that when the system sends CTRL_CLOSE_EVENT, it starts a timer. The process is allowed to keep running for a little bit of time, but eventually, the OS will just kill the process unilaterally.
Here's the handler that I registered
BOOL WINAPI ConsoleCtrlHandler(DWORD dwCtrlType) {
switch (dwCtrlType) {
case CTRL_C_EVENT:
case CTRL_CLOSE_EVENT:
return TRUE; // breakpoint set here
default:
return FALSE;
}
}
Here's how I registered the handler, after my call to AllocConsole
:
BOOL result = SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE /* Add */);
assert(result);
I set a breakpoint on the line marked //breakpoint set here
. Then, I ran the process under the Visual Studio debugger. When the console window was focused, I pressed Ctrl+C. My breakpoint got hit, and I was able to step through my handler and back into KernelBase.dll!CtrlRoutine
and so on. The process kept running when I let the process resume normal execution.
However, when I closed the console window, my handler did get called, but I was unable to trace its execution very far. I was able to single step execution a few times, but then the process simply exited. Visual Studio reported "The program '[10644] Win32Project.exe' has exited with code -1073741510 (0xc000013a)."
0xc000013a is STATUS_CONTROL_C_EXIT:
c:\Tools\ERR>Err.exe 0xc000013a
# for hex 0xc000013a / decimal -1073741510 :
STATUS_CONTROL_C_EXIT ntstatus.h
# {Application Exit by CTRL+C}
# The application terminated as a result of a CTRL+C.
# 1 matches found for "0xc000013a"
One thing you can do is disable the close button on the console window:
HWND hwnd = ::GetConsoleWindow();
if (hwnd != NULL)
{
HMENU hMenu = ::GetSystemMenu(hwnd, FALSE);
if (hMenu != NULL) DeleteMenu(hMenu, SC_CLOSE, MF_BYCOMMAND);
}