Exception handlers can respond to a variety of asynchronous 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. Use console control handlers 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, 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 signal.
Multiple handlers can be associated with a signal, and handlers can be removed as well as added. Here is the function 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 signal is not specified. The handler must test to see which signal was received.
The handler routine returns a Boolean value and takes a single DWORD parameter that identifies the signal. The HandlerRoutine 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 will cause Ctrl-C to be treated as keyboard input rather than as a signal.
The handler routine actually executes as an independent thread 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.
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 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 Windows is shutting down.
The signal handler can perform cleanup operations just as an exception or termination handler would. The signal handler can return TRUE to indicate that the function handled the signal. If the signal handler returns FALSE, the next handler function in the list is executed. The signal handlers are executed in the reverse order from the way they were set, so that the most recently set handler is executed first and the system handler is executed last.