- •Объекты и события в turbo vision.
- •Глава 1. Объекты TurboVision.
- •Глава 2. События.
- •Глава 3. Взаимодействие видимых элементов.
- •Введение
- •Глава 1. Объекты turbo vision.
- •Иерархия объектов TurboVision. Принципы построения иерархии.
- •Примитивные типы объектов. Система координат TurboVision.
- •Видимые элементы.
- •Взаимосвязи между видимыми элементами.
- •Поля State и Options.
- •Выбор и активизация видимых элементов.
- •Глава 2. События.
- •Чтение ввода пользователя.
- •Виды событий.
- •События-сообщения. Команды. Разрешение и запрещение команд.
- •Запись события. Тип tEvent.
- •Цикл событий. Функция Execute.
- •Методы GetEvent и PutEvent. Централизация сбора событий.
- •Обработка событий. Метод HandleEvent.
- •Маршрутизация событий. Переменные FocusedEvents и PositionalEvents. Поле EventMask.
- •Глава 3. Взаимодействие видимых элементов.
- •Посредники.
- •Сообщения между видимыми элементами.
- •3. Кто обрабатывает общие сообщения.
- •4. Вызов процедуры HandleEvent.
Обработка событий. Метод HandleEvent.
События передаются элементу посредством вызова наследуемого от TView виртуального метода HandleEvent, определяющего реакцию видимого элемента на события. HandleEvent – это центральный метод, через который осуществляется вся обработка событий в TurboVision.
TView.HandleEvent обрабатывает только одно событие – evMouseDown, следующим образом: если видимый элемент не выбран и не запрещен (т.е. не установлены флаги sfSelected и sfDisabled), и если видимый элемент выбираемый (установлен атрибут ofSelectable), то элемент выбирает себя, вызывая процедуру Select.
Почти всегда потомки TView перекрывают HandleEvent для реализации своих типов поведения.
Общий вид HandleEvent:
procedure HandleEvent(var Event: TEvent);
{ Параметр Event содержит запись передаваемого объекту события. }
begin
{ Код, изменяющий или ограничивающий поведение предка. }
TParent.HandleEvent(Event); { Код предка. }
{ Код, выполняющий дополнительные функции. }
end;
Видимый элемент может либо обработать событие, заданное в Event, либо проигнорировать его, тогда событие будет возвращено элементу, вызвавшему HandleEvent данного видимого элемента.
Для индикации того, что событие обработано, видимый элемент должен вызвать процедуру ClearEvent(var Event: TEvent);. ClearEvent очищает событие, устанавливая поле Event.What в evNothing; поле Event.InfoPtr устанавливается в @Self для указания, каким объектом было обработано событие.
TGroup перекрывает HandleEvent для передачи событий своим подэлементам, осуществляя маршрутизацию событий.
Маршрутизация событий. Переменные FocusedEvents и PositionalEvents. Поле EventMask.
Видимые элементы TurboVision работают по принципу «говори только тогда, когда к тебе обратятся», они ожидают, когда монитор событий скажет им, что пришло событие, на которое требуется отклик.
В связи с этим, главное в получении событий в нужном месте – это правильная маршрутизация событий. Некоторые события передаются всем элементам программы, другие направляются точно в определенную часть программы.
Объект-группа передает события своим подэлементам, вызывая их методы HandleEvent. Передача события осуществляется одним из трех способов, в зависимости от вида события:
1). Позиционированные события.
Это события от мышки (evMouse). Позиционированное событие передается первому подэлементу в Z-порядке, содержащему позицию, на которую указывает курсор мыши. Поскольку видимые элементы могут перекрываться, возможно, что отмеченная позиция принадлежит более чем одному элементу, и передача события в Z-порядке гарантирует, что событие получит самый верхний подэлемент, содержащий эту позицию.
2). Активные (сфокусированные) события.
Этот тип событий включает события от клавиатуры (evKeyboard) и события-команды (evCommand). Передача активных событий происходит в три фазы (поле TGroup.Phase отображает фазу передачи события):
Pre-process: поле группы Phase устанавливается в phPreProcess и событие передается тем подэлементам, у которых установлен атрибут ofPreProcess;
Process: Phase устанавливается в phFocused и событие передается выбранному подэлементу группы;
Post-process: группа устанавливает Phase в phPostProcess и передает событие подэлементам, имеющим установленный атрибут ofPostProcess.
Если какой-либо подэлемент группы обработал событие, то передача события прекращается.
Для чего активные события передаются в три фазы?
Рассмотрим следующий пример: допустим, в программе есть диалоговое окно, которое содержит строку ввода (TInputLine) и кнопку (TButton) с горячей клавишей «A». Кнопка должна нажиматься по короткому набору «A», когда строка ввода не сфокусирована (т.е. не производится ввод в нее), и по набору «Alt-A», когда строка ввода сфокусирована (пользователь вводит символы в строке ввода). Следовательно, кнопка должна получать активные события (нажатия клавиш) и в то время, когда сама она не является выбранным и сфокусированным подэлементом:
procedure TButton.HandleEvent(var Event: TEvent);
var C: Char;
begin
…
case Event.What of
…
evKeyDown :
begin
C := HotKey(Title^); { Возвращает символ горячей клавиши }
if (Event.KeyCode = GetAltCode(C)) or
{ GetAltCode(C) возвращает код, соответствующий
нажатию «Alt + C» }
(State and sfFocused <> 0) and (Event.CharCode = ‘ ‘) or
(Owner^.Phase = phPostProcess) and
(C<>#0) and (UpCase(Event.CharCode) = C)
{ UpCase(Ch: Char) возвращает символ верхнего ряда,
соответствующий заданному параметром Ch }
then
begin
PressButton; { Нажатие кнопки }
ClearEvent(Event); { Очистка обработанного события }
end;
end;
…
end;
…
end; .
Как видно из приведенного кода, кнопка нажимается при получении события от клавиатуры в трех случаях:
когда код нажатой клавиши соответствует коду нажатия «Alt + горячая клавиша»;
когда кнопка сфокусирована и нажат пробел;
когда нажата горячая клавиша и событие передано в фазе PostProcess; фаза должна быть именно PostProcess, позволяя сфокусированному элементу обработать нажатие клавиши до того, как это событие «увидит» кнопка.
3). Общие сообщения (не активные и не позиционированные события).
Эти события, по определению, не знают своего назначения и передаются всем подэлементам группы в Z-порядке, пока какой-нибудь из них не обработает событие или оно не будет передано всем подэлементам. Общие сообщения используются для взаимодействия различных объектов, а также для посылки события-сообщения сразу нескольким объектам.
Глобальные переменные PositionalEvents и FocusedEvents (тип Word) определяют, какие события относятся к позиционированным и сфокусированным событиям. В TurboVision, по умолчанию, для них устанавливаются следующие значения: PositionalEvents=evMouse, а FocusedEvents = evKeyboard + evCommand. Если событие не содержится в PositionalEvents и FocusedEvents, то оно передается как общее сообщение.
Поле видимого элемента EventMask типа Word, наследуемое от TView, определяет виды событий, не обрабатываемые видимым элементом. Биты EventMask соответствуют битам TEvent.What. Если событие не содержится в поле EventMask подэлемента, то группа никогда не передаст его этому элементу. Установка EventMask в $FFFF позволяет реагировать элементу на все классы событий, установка в $0 запрещает передачу элементу любых событий. TView.EventMask разрешает передачу событий evMouseDown, evKeyDown и evCommand.