Организация высокоуровневого консольного ввода-вывода
Каждый консольный процесс имеет свой собственный список функций-обработчиков, которые вызываются системой, когда происходят определенные события, например при активном окне консоли пользователь нажимает комбинации клавиш CTRL + C, CTRL + Break или CTRL + Close. При запуске консольного приложения список функций-обработчиков содержит только заданную по умолчанию функцию-обработчик, которая вызывает функцию ExitProcess. Консольный процесс может добавлять или удалять дополнительные функции-обработчики, вызывая функцию SetConsoleCTRLHandler.
B00L SetConsoleCTRLHandler(PHANDLER_ROUTINE HandlerRoutine. B00L Add):
Данная функция имеет два параметра:
- HandlerRoutine – указатель на определенную приложением функцию HandlerRoutine, которая должна быть добавлена или удалена;
- Add – логическое значение, которое означает: 1 – функция должна быть добавлена, 0 – функцию необходимо удалить.
Функция HandlerRoutine – это определенная приложением функция обратного вызова. Консольный процесс использует эту функцию, чтобы обработать нажатия клавиш управления. На самом деле HandlerRoutine – идентификатор-заполнитель для определенного приложением имени функции.
B00L WINAPI HandIerRoutine(DWORD dwCTRLType):
Параметр DwCTRLType определяет тип сигнала управления, получаемого обработчиком. Этот параметр может принимать одно из следующих значений:
- CTRL_C_EVENT=0 – сигнал, имитирующий нажатие клавиш CTRL + C, может быть получен из двух источников: с клавиатуры или как сигнал, сгенерированный функцией GenerateConsoleCTRL Event;
- CTRL_BREAK_EVENT=1 – сигнал имитирующий нажатие клавиш CTRL + Break, может быть получен из двух источников: с клавиатуры или как сигнал, сгенерированный функцией GenerateConsoleCTRL Event;
- CTRL_CL0SE_EVENT=2 – сигнал, который система посылает всем процессам, подключенным к данному консольному приложению, когда пользователь его закрывает (либо выбирая пункт Close в системном меню окна консоли, либо щелкая на кнопке завершения задачи в диалоговом окне Менеджера задач);
- CTRL_LOGOFF_EVENT=5 – сигнал, который посылается всем консольным процессам, когда пользователь завершает работу в системе (этот сигнал не указывает, какой именно пользователь завершает работу);
- CTRL_SHUTD0WN_EVENT=6 – сигнал, который система посылает всем консольным процессам при подготовке к выключению машины.
Функция HandlerRoutine должна возвратить логическое значение: 1 – если она обрабатывает конкретный сигнал управления; 0 – для обработки полученного события будет использоваться другая функция-обработчик HandlerRoutine из списка функций-обработчиков для этого процесса (то есть включенная в этот список раньше данной функции).
Как уже было упомянуто, каждый консольный процесс может определить несколько функций HandlerRoutine, которые связываются в цепочку. Первоначально этот список содержит только заданную по умолчанию функцию обработчика, которая вызывает функцию ExitProcess и, как результат, приводит к завершению текущего консольного приложения. Консольный процесс добавляет или удаляет дополнительные функции обработчика, вызывая функцию SetConsoleCTRLHandler, которая не затрагивает список функций-обработчиков для других процессов.
Когда консольный процесс принимает любой из сигналов управления (см. выше), то вызывается последняя зарегистрированная функция-обработчик, если она не возвращает 1, то управление передается следующему (предыдущему) зарегистрированному обработчику и т. д., до тех пор пока один из обработчиков не возвратит 1. Если ни один из обработчиков этого не сделал, то вызывается обработчик, заданный по умолчанию.
Установка обработчиков для сигналов CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT и CTRL_SHUTDOWN_EVENT дает процессу возможность выполнить специфичные для него действия по корректному завершению приложения.
Пользовательская функция HandlerRoutine может быть вызвана для того, чтобы выполнить следующие действия:
- вызвать функцию ExitProcess для завершения процесса;
- возвратить 0 (ложь) – это означает, что завершение приложения должен выполнить обработчик, заданный по умолчанию;
- возвратить 1 – в этом случае никакие другие функции-обработчики не вызываются, а система отображает всплывающее диалоговое окно с запросом о необходимости завершения процесса;
- система также отображает диалоговое окно, если процесс не отвечает определенное время (5 секунд для CTRLCLOSEEVENT и 20 секунд для CTRLLOGOFFEVENT и CTRLSHUTDOWNEVENT);
- процесс может использовать функцию SetProcessShutdownParameters, чтобы запретить системе отображать последнее диалоговое окно, в этом случае система просто заканчивает процесс, когда HandlerRoutine возвращает истину или когда истекает определенный период времени.