События,
связанные с действиями
Компонент TAction реагирует на три события: OnExecute, OnUpdate И OnHint.
Первое — и самое главное — должно быть как раз реакцией на данное действие. Это событие возникает в момент нажатия кнопки, пункта меню — короче, при поступлении сигнала от клиента действия. Здесь — как правило—и пишется обработчик. Почему "как правило"? Потому что схема обработки сигнала 4-этапная:
1. Сначала вызывается обработчик события OnExecute списка действий
TActionList:
property OnExecute: TActionEvent; TActionEvent = procedure (Action: TBasicAction; var Handled: Boolean)
of object;
Если обработчик этого события вами не предусмотрен, или в параметре Handled он вернул значение False, происходит генерация следующего события — шаг 2.
2. Вызывается обработчик события onActionExecute глобального объекта Application (тип события тот же — TActionEvent). Если и оно не обработало сигнал действия, переходим к следующему шагу.
3. Вызывается обработчик события onExecute самого действия (объекта типа TAction или его потомка).
4. Если первые три шага не обработали ситуацию (вернули False), то, вероятно, это было связано с неправильной целью (Target) действия. В качестве "последнего шанса" приложению посылается сообщение CM_ACTIONEXECUTE. В этом случае происходит поиск другой цели для данного действия (об алгоритме поиска цели см. ниже).
Первые две возможности в этом списке используются относительно редко. Тем не менее они полезны, если вам нужно глобально добавлять/удалять/разрешать/запрещать действия.
Введение события onupdate является очень хорошей находкой, о нем напишем подробно. И автор этих строк, и, возможно, вы потратили немало времени, чтобы в разрабатываемых программах элементы управления находились в актуальном состоянии. Если, скажем, вашей программой открыт первый файл, то нужно активировать ряд кнопок и пунктов меню (Save, Save as, Print и т. п.); как только закрыт последний — отключить их. Если в буфере обмена есть что-то подходящее, необходимо активизировать пункт меню и кнопку Paste, если нет — отключить. В результате код, отслеживающий это, у неопытных программистов "размазывается" по всему приложению. А ведь можно поступить проще. Событие TAction.onUpdate возникает в моменты простоя приложения, т. е. тогда, когда оно не занято обработкой сообщений (цикл содержится в методе idle объекта Application). Это гарантирует, что оно возникнет ДО ТОГО, как пользователь щелкнет мышью и увидит выпадающие пункты меню; поэтому можно успеть обновить их состояние. Пример использования события onupdate:
procedure TForml.PasteActionUpdate(Sender: TObject); begin
TAction(Sender).Checked := Clipboard.HasFormat(CFJTEXT);
end;
Примечание
Перед вызовом события onupdate также происходит 4-этапная последовательность действий, точно такая же, как при OnExecute.
Третье событие имеет такой тип:
THintEvent = procedure (var HintStr: string; var CanShow: Boolean) of object;
Оно вызывается тогда, когда от элемента управления требуется показать подсказку, связанную с данным действием. В обработчике события можно указать, будет ли что-нибудь показываться (параметр CanShow) и, если да, то что именно (параметр Hintstr).
Это были события, относящиеся к компоненту TAction. Сам компонент TActionList также имеет три события: OnExecute, OnUpdate И OnChange. О первых двух мы уже сказали; третье происходит в момент изменения списка (добавления или удаления действий).