
Диспетчеризация действий на основе компонента ActionList
Страница Standard
Обеспечивает диспетчеризацию действий разработчика и, соответственно, событий компонентов.
Этот компонент менее мощный, чем введенный в Delphi 6 компонент ActionManager. Но и ActionList не потерял своего значения. Во-первых, только его можно использовать в версиях, младше Delphi 6. Во-вторых, компонентActionList можно использовать в кросс-платформенных приложениях, тогда какActionManager только в приложениях Windows. Наконец, мощьActionManager проявляется в основном при взаимодействии со специальными компонентамиActionMainMenuBarи ActionToolBar, а в некоторых случаях эти компоненты менее удобны, чемMain Menu и ToolBar.
В компонент ActionList, заносится тот список действий, который вы составили в начале процесса проектирования. Перенесите на форму этот компонент. Перенесите также компонентImageList, и сошлитесь на него в свойствеImages компонентаActionList. Это полезно сделать в самом начале, так как описанные далее стандартные действия автоматически занесут вImageList соответствующие им изображения.
Теперь сделайте на компоненте ActionList двойной щелчок. Вы попадаете в редактор действий (рис. 2), позволяющий вводить и упорядочивать действия. Щелчок правой кнопкой мыши или щелчок на маленькой кнопочке со стрелкой вниз правее первой быстрой кнопки окна редактирования позволит вам выбрать одну из команд: New Action (новое действие) или New Standard Action (новое стандартное действие). Первая из них относится к вводу нового действия любого типа. По умолчанию эти действия будут получать имена Action1, Action2 и т.д.
Вторая команда открывает окно, в котором вы можете выбрать необходимое вам стандартное действие. Работу со стандартными действиями мы рассмотрим в следующем разделе.
Каждое действие, которое вы внесли в список — это объект типа TAction. Выбрав в левом окне редактора ту или иную категорию или [AllActions] (все категории), а в правом — конкретное действие, вы можете увидеть в Инспекторе Объектов его свойства и события.
Свойства класса TAction
Name(имя) — оно появится в правом окне редактора свойств и будет в дальнейшем фигурировать в заголовках обработчиков событий. При задании имени следует заботиться, чтобы оно было осмысленным, так как это облегчит вашу последующую работу. С другой стороны, желательно, чтобы имена не совпадали с какими-то именами функций, компонентов и т.п. Подобное совпадение в некоторых случаях может внести двусмысленность в код вашего приложения.
Рис. 2 Окно редактора действий
Category(категория) не имеет отношения к выполнению приложения. Задание категории просто позволяет в процессе проектирования сгруппировать действия по их назначению. Вы можете для каждого действия выбрать категорию из выпадающего списка, или написать имя новой категории и отнести к ней какие-то действия. Например, на рис. 2 видны введенные пользователем категории Файл,Edit. Обычно целесообразно называть категории по заголовкам будущих меню или инструментальных панелей.
Caption– надпись, которая далее будет появляться в инициаторах действия — кнопках, разделах меню и т.д. В надписи можно (и нужно) выделить символ, который будет подчеркнут и обеспечит быстрый доступ к данному действию.
Shortcut– горячие клавиши,
Hint– надписи на ярлычках подсказок и в строке состояний
ImageIndex– индекс (начиная с 0) изображения, соответствующего данному действию в компоненте списка изображений ImageList. Этот индекс передастся в дальнейшем компонентам, связанным с данным действием — разделам меню, кнопкам. Эти же изображения появляются также в окне редактора действий (рис. 2).
Checked : boolean– указывает, будет ли в инициаторах действий отображаться маркер флажка. показывающий, что данныйраздел выбран
AutoCheck: boolean(введено, начиная с Delphi 6). Если его установить вtrue, то при каждом выборе пользователем данного инициатора действиямаркер будет автоматически переключаться, указывая то на выбранное состояние, то на отсутствие выбора.
ActionComponent:Tcomponent– Определяет какой компонент вызвал (инициировал) действие.
События действий
OnExecuteвозникает в момент, когда пользователь инициализировал действие, например, щелкнув на компоненте (разделе меню, кнопке), связанном с данным действием. Обработчик этого события должен содержать процедуру, реализующую данное действие. Например, обработчик события OnExecute действия AExit может в простейшем случае иметь вид
procedure TForml.AExitExecute(Sender: TObject);
begin
Close;
end;
а в более сложных случаях может содержать проверку возможности закрыть приложение, запросы пользователю и т.д..
В этом же обработчике можно проверить какой компонент инициировал действие. Например
if (Action1.ActionComponent.name='MSave') then …
Здесь 'MSave' – имя компонента–инициатора действия (имя пункта меню, имя кнопки и т.д.)
OnUpdate периодически возникает в промежутках между действиями. Возникновение этих событий прекращается только во время реализации события или во время, когда пользователь ничего не делает и компьютер находится в состоянии ожидания действий.
Обработчик события OnUpdate может содержать какие-то настройки, подготовку ожидаемых дальнейших действий или выполнение каких-то фоновых операций.
procedure TForm1.Action1Update(Sender: TObject);
begin
{ Indicate whether ToolBar1 is currently visible }
(Sender as TAction).Checked := ToolBar1.Visible;
end;
Этот обработчик устанавливает маркер в инициаторах действия если панель ToolBar1 видима, и снимает его в противном случае.
OnHint возникает в момент, когда на экране отображается ярлычок подсказки в результате того, что пользователь задержал курсор мыши над компонентом, инициализирующим событие.
Наличие в объекте действия событий OnUpdate и OnHint обогащает ваши возможности по проектированию приложения. Без этого объекта подобные события отсутствуют, и их при необходимости приходится моделировать более сложными приемами.
Связь объектов действий с конкретными инициаторами действий
Связь объектов действий с конкретными инициаторами действий — управляющими элементами типа кнопок, разделов меню и т.д., осуществляется через свойство Action, имеющееся у всех управляющих элементов.
Поместите на вашу форму кнопку, и вы увидите в Инспекторе Объектов это свойство. Раскройте его выпадающий список и выберите из него действие, которое вами было предварительно описано. Вы сможете заметить, что после этого в кнопку перенесутся такие свойства объекта действия, как Caption, Hint и др., и что в ее событие OnClick подставится обработчик, предусмотренный вами для данного действия. Если далее вы введете в приложение меню с разделом, соответствующим тому же действию, или на панелиToolBar введете кнопку и укажете в этом объекте то же значение свойстваAction, то свойства и обработчики событий объекта действия будут перенесены и на этот раздел меню, и на эту кнопку. Вам не придется повторно задавать значениеHint, Caption и др.
Подобная связь между свойствами объекта действия и свойствами управляющих элементов выполняется классом TActionLink и его наследниками. Передаются в компоненты такие свойства действия, какCaption, Checked, Enabled, HelpContext, Hint, Imagelndex, Shortcut, Visible. Впрочем, в любом компоненте разработчик может изменить переданное в него свойство. Обратной связиTActionLink с компонентами нет, так что эти изменения будут локальными и не отразятся на других компонентах. Если же требуется изменить свойства всех связанных с одним действием компонентов, надо изменять свойство объекта действия. Это облегчает программное управление компонентами, связанными с одним и тем же деиствием. Например, если в какой-то момент вам надо сделать недоступными (или, наоборот, доступными) два компонента — кнопкуButton5 и раздел меню N5,связанные с одним событием (назовем его объект Do), то при отсутствии централизованной диспетчеризации событий черезActionList вам пришлось бы писать два оператора:
Button3.Enabled := false;
N5.Enabled ;= false;
a при наличии объекта Do — всего один:
Do.Enabled := false;
Дело не только в экономии кода, но и в его прозрачности, понятности его как для вас самих, так и для тех, кому придется, может быть, в дальнейшем сопровождать ваше приложение.