Console Control Handlers
Exception handlers can respond to a variety of events, but they do not detect situations such as the user logging off or entering a Ctrl-c from the keyboard to stop a program. Console control handlers are required to detect such events.The function SetConsoleCtrlHandler allows one or more specified functions to be executed on receipt of a Ctrl-c, Ctrl-break, or one of three other console-related signals. The GenerateConsoleCtrlEvent function, described in Chapter 6, also generates these signals, and the signals can be sent to other processes that are sharing the same console. The handlers are user-specified Boolean functions that take a DWORD argument identifying the actual signal.Multiple handlers can be associated with a signal, and handlers can be removed as well as added. Here is the function used to add or delete a handler.
BOOL SetConsoleCtrlHandler (
PHANDLER_ROUTINE HandlerRoutine,
BOOL Add)
The handler routine is added if the Add flag is trUE; otherwise, it is deleted from the list of console control routines. Notice that the actual signal is not specified. The handler must test to see which signal was received.The actual handler routine returns a Boolean value and takes a single DWORD parameter that identifies the actual signal. The handler name in the definition is a placeholder; the programmer specifies the name.Here are some other considerations when using console control handlers.
- If the HandlerRoutine parameter is NULL and Add is TRUE, Ctrl-c signals will be ignored.
- The ENABLE_PROCESSED_INPUT flag on SetConsoleMode (Chapter 2) will cause Ctrl-c to be treated as keyboard input rather than as a signal.
- The handler routine actually executes as an independent thread (see Chapter 7) within the process. The normal program will continue to operate, as shown in the next example.
- Raising an exception in the handler will not cause an exception in the thread that was interrupted because exceptions apply to threads, not to an entire process. If you wish to communicate with the interrupted thread, use a variable, as in the next example, or a synchronization method (Chapter 8).
There is one other important distinction between exceptions and signals. A signal applies to the entire process, whereas an exception applies only to the thread executing the code where the exception occurs.
BOOL HandlerRoutine (DWORD dwCtrlType)
dwCtrlType identifies the actual signal (or event) and can take on one of the following five values.
- CTRL_C_EVENT indicates that the Ctrl-c sequence was entered from the keyboard.
- CTRL_CLOSE_EVENT indicates that the console window is being closed.
- CTRL_BREAK_EVENT indicates the Ctrl-break signal.
- CTRL_LOGOFF_EVENT indicates that the user is logging off.
- CTRL_SHUTDOWN_EVENT indicates that the system is shutting down.