First of all, to make sure we can receive this event, the ENABLE_PROCESSED_INPUT console mode must be enabled using SetConsoleMode; without this, the CTRL+C signal would be sent as a keystroke inside the input buffer.
SetConsoleMode(hdlStdInput, ENABLE_ECHO_INPUT | ENABLE_INSERT_MODE | ENABLE_LINE_INPUT | ENABLE_MOUSE_INPUT | ENABLE_PROCESSED_INPUT | ENABLE_QUICK_EDIT_MODE);
We can now register our HandlerRoutine function using SetConsoleCtrlHandler
BOOL WINAPI blCtrlCHandler(DWORD dwCtrlType) { ... }
...
SetConsoleCtrlHandler(blCtrlCHandler, TRUE);
The handler function can be also handy for cleanup code, since it does not receives only the CTRL+C signal, but other events as well. Checking the dwCtrlType variable allows you to detect CTRL+BREAK and system events like logoff, shutdown, and the program's termination through the close button.
If you don't need the CTRL+C signal, and you want to mask it, it is possible to register a null function pointer that will prevent the default handler from handling the signal.
SetConsoleCtrlHandler(NULL, TRUE);
Source code: http://www.insanedevelopers.net/sources/CTRL-CHandling.zip