События и их обработка
Поведение вновь созданного варианта программы внешне ничем не отличается от предыдущего: также будут созданы меню, строка статуса и основное поле экрана, программа по-прежнему будет распознавать команды ALT + X и F10. Однако теперь она будет реагировать и на новые команды. Чтобы убедиться в этом, установите контрольные точки в заглушках FileOpen и FileSave и запустите программу вновь: нажатие на клавишу F3 вызовет останов в контрольной точке FileOpen – ведь именно с этой клавишей мы связали команду cmOpen в процедуре InitStatusLine, в то время как нажатие на клавишу F2 не приведет к срабатыванию контрольной точки FileSave, поскольку команда cmSave пока еще запрещена и обработчик HandleEvent ее просто не "увидит".
Чтобы использовать нестандартные команды меню или строки статуса, мы должны перекрыть обработчик событий программы, в новом обработчике выделить из потока событий команды и распознать их коды.
Чтобы стали более понятны действия обработчика событий, отметим, что тип TEvent в Turbo Vision определен как запись такого вида:
type TEvent = record What: Word; {Определяет тип события} case Word of {"Пустое" событие} evMouse: ({Событие от мыши:} Buttons: Byte; {Состояние кнопок} Double: Boolean;{Признак двойного нажатия кнопки мыши} Where: TPoint); {Координаты курсора мыши} evKeyDown: ({Событие от клавиатуры:} case Integer of 0: (KeyCode: Word);{Код клавиши} 1: (CharCode: Byte; ScanCode: Byte)); evMessage: ({Событие-сообщение:} Command: Word; {Код команды} case Word of 0:(InfoPtr: Pointer); 1:(InfoLong: Longlnt); 2:(InfoWord: Word); 3:(Infolnt: Integer); 4:(InfoByte:Byte); 5:(InfoChar:Char)); end;
Стандартная маска evCommand позволяет выделить из потока событий только те, которые связаны с передачей команд между различными обработчиками событий. Именно таким способом стандартный обработчик TApplication.HandleEvent сообщает новому обработчику TNotebookHandleEvent о возникновении события, связанного с вновь определенной командой. Если бы мы не предусмотрели вызов стандартного обработчика с помощью оператора:
Inherited HandleEvent(Event);
Нам пришлось бы самим анализировать положение мыши или нажатую клавишу и интерпретировать их как соответствующие команды. Включение вызова TApplication.HandleEvent в тело нашего обработчика событий избавляет нас от этой рутинной работы.
В конце обработчика мы вызвали стандартную процедуру ClearEvent, с помощью которой в переменную Event помещается сообщение Nothing ("пустое" событие). Это событие игнорируется всеми обработчиками, так что программа будет повторять проверку состояния мыши и клавиатуры до тех пор, пока не произойдет нового события. Фактически тело процедуры TApplication.Run (см. раздел исполняемых операторов нашей программы) состоит из бесконечно повторяющегося цикла проверки мыши и клавиатуры и передачи событий по цепи обработчиков событий.
После получения любого события обработчик должен либо обработать это событие и очистить переменную Event, либо просто вернуть управление обработчику верхнего уровня, если эта команда не предназначена для него, либо, наконец, сформировать и передать новое событие для реализации команд, которые распознаны им, но которые он выполнять не умеет или не должен.