Учись программированию на C++ Builder бесплатно!

Компонент ActionList (диспетчеризация действий) не менее мощный, чем введенный в C++Builder 6 компонент ActionManager. Но и ActionList не потерял своего значения. Во-первых, только его можно использовать в версиях, младше C++Builder 6. Во-вторых, компонент ActionList можно использовать в кросс-платформенных приложениях, тогда как ActionManager только в приложениях Windows. Наконец, мощь ActionManager проявляется в основном при взаимодействии со специальными компонентами ActionMainMenuBar и ActionToolBar, а в некоторых случаях эти компоненты менее удобны, чем MainMenu и ToolBar.

В компонент ActionList, расположенный в библиотеке на странице Standard, заносится тот список действий, который был составлен в начале процесса проектирования. Перенесите на форму этот компонент и компонент ImageList, сошлитесь на него в свойстве Images компонента ActionList. Это полезно сделать в самом начале, так как описанные далее стандартные действия автоматически занесут в ImageList соответствующие им изображения.

Теперь сделайте на компоненте ActionList двойной щелчок. Вы попадаете в редактор действий, позволяющий вводить и упорядочивать действия.

Щелчок правой кнопкой мыши или щелчок на маленькой кнопочке со стрелкой вниз правее первой быстрой кнопки окна редактирования позволит вам выбрать одну из команд: New Action (новое действие) или New Standard Action (новое стандартное действие). Первая из них относится к вводу нового действия любого типа. По умолчанию эти действия будут получать имена Action1, Action2 и т.д. Вторая команда открывает окно, в котором вы можете выбрать необходимое вам стандартное действие.

Каждое действие, которое вы внесли в список - это объект типа TAction. Выбрав в окнах редактора ту или иную категорию или [AllActions] (все категории), а в правом конкретное действие, вы можете увидеть в Инспекторе Объектов его свойства и события. Вы можете установить свойство Name (имя) оно появится в правом окне редактора свойств и будет в дальнейшем фигурировать в заголовках обработчиков событий. При задании имени следует заботиться, чтобы оно было осмысленным, так как это облегчит вашу последующую работу. С другой стороны, желательно, чтобы имена не совпадали с какими-то именами функций, компонентов и т.п. Подобное совпадение в некоторых случаях может внести двусмысленность в код вашего приложения. Удачным, выходом является добавление к имени каждого действия символа "А".

Для каждого действия надо задать надпись (Caption), которая далее будет появляться в инициаторах действия кнопках, разделах меню и т.д. В надписи можно (и нужно) выделить символ, который будет подчеркнут и обеспечит быстрый доступ к данному действию. Можете задать «горячие» клавиши (Shortcut), надписи на ярлычках подсказок и в строке состояний (Hint), идентификатор темы контекстной справки (HelpContext) и другие обычные для многих компонентов свойства.

Можно для каждого или некоторых действий указать свойство Imagelndex, которое является индексом (начиная с 0) изображения, соответствующего данному действию в компоненте списка изображений ImageList. Этот индекс передастся в дальнейшем компонентам, связанным с данным действием разделам меню, кнопкам. Эти же изображения появляются также в окне редактора действий.

Свойство Category (категория) не имеет отношения к выполнению приложения. Задание категории просто позволяет в процессе проектирования сгруппировать действия по их назначению. Вы можете для каждого действия выбрать категорию из выпадающего списка, или написать имя новой категории и отнести к ней какие-то действия. Обычно целесообразно называть категории по заголовкам будущих меню или инструментальных панелей.

На странице событий Инспектора Объектов для каждого действия определено три события: OnExecute, OnUpdate и OnHint.

Событие OnExecute возникает в момент, когда пользователь инициализировал действие, например, щелкнув на компоненте (разделе меню, кнопке), связанном с данным действием. Обработчик этого события должен содержать процедуру, реализующую данное действие. Например, обработчик события OnExecute действия AExit (окончания работы) может в простейшем случае иметь вид:

void fastcall TFMain::AExitExecute(TObject *Sender)
{
Close();
}

а в более сложных случаях может содержать проверку возможности закрыть приложение, запросы пользователю и т.д. Одним из преимуществ использования действий является то, что заголовки обработчиков приобретают осмысленный характер и код становится более прозрачным. Действительно, гораздо понятнее заголовок AExitExecute, чем, например, Button7Click или N14Click (попробуйте найти в вашем большом приложении, где эта кнопка Button7 или раздел меню N14). В результате вы избавляетесь от необходимости давать осмысленные имена кнопкам и разделам меню, т.е. облегчаете свою работу с компонентами.

Событие OnUpdate периодически возникает в промежутках между действиями. Возникновение этих событий прекращается только во время реализации события или во время, когда пользователь ничего не делает и компьютер находится в состоянии ожидания действий. Обработчик события OnUpdate может содержать какие-то настройки, подготовку ожидаемых дальнейших действий или выполнение каких-то фоновых операций.

Событие OnHint возникает в момент, когда на экране отображается ярлычок подсказки в результате того, что пользователь задержал курсор мыши над компонентом, инициализирующим событие.
Наличие в объекте действия событий OnUpdate и OnHint обогащает ваши возможности по проектированию приложения. Без этого объекта подобные события отсутствуют и их при необходимости приходится моделировать более сложными приемами.

Связь объектов действий с конкретными инициаторами действий, управляющими элементами типа кнопок, разделов меню и т.д., осуществляется через свойство Action, имеющееся у всех управляющих элементов. Поместите на вашу форму кнопку, и вы увидите в Инспекторе Объектов это свойство. Раскройте его выпадающий список и выберите из него действие, которое вами было предварительно описано. Вы сможете заметить, что после этого в кнопку перенесутся такие свойства объекта действия, как Caption, Hint и др., и что в ее событие OnClick подставится обработчик, предусмотренный вами для данного действия. Если далее вы введете в приложение меню с разделом, соответствующим тому же действию, или на панели ToolBar введете кнопку и укажете в этом объекте то же значение свойства Action, то свойства и обработчики событий объекта действия будут перенесены и на этот раздел меню, и на эту кнопку. Вам не придется повторно задавать значение Hint, Caption и др.

Подобная связь между свойствами объекта действия и свойствами управляющих элементов выполняется классом TActionLink и его наследниками. Передаются в компоненты такие свойства действия, как Caption, Checked, Enabled, HelpContext, Hint, Imagelndex, Shortcut, Visible. Впрочем, в любом компоненте разработчик может изменить переданное в него свойство. Обратной связи TActionLink с компонентами нет, так что эти изменения будут локальными и не отразятся на других компонентах. Если же требуется изменить свойства всех связанных с одним действием компонентов, надо изменять свойство объекта действия. Это облегчает программное управление компонентами, связанными с одним и тем же действием. Например, если в какой-то момент вам надо сделать недоступными (или, наоборот, доступными) два компонента кнопку Button3 и раздел меню N5, связанные с одним событием (назовем его объект Do), то при отсутствии централизованной диспетчеризации событий через ActionList вам пришлось бы писать два оператора:

Button3->Enabled = false;
N5->Enabled = false;

а при наличии объекта Do всего один:

Do->Enabled = false;

Дело не только в экономии кода, но и в его прозрачности, понятности его как для вас самих, так и для тех, кому придется, может быть, в дальнейшем сопровождать ваше приложение.

Поделиться