Команда New Standard Action (новое стандартное действие) открывает окно, в котором можно выбрать из списка необходимое стандартное действие (или сразу несколько действий). Действия в списке сгруппированы по категориям. В С++Вuilder 5 список включает 26 действий. В C++Builder 6 этих стандартных действий уже 62. Стандартные действия охватывают операции редактирования текстов (категория Edit), форматирования текстов (категория Format), поиска в текстах (категория Search), работу со справками (категория Help), с файлами (категория File), с окнами в приложениях MDI (категория Window), с многостраничными панелями (категория Tab), списками (категория List), стандартными диалогами (категория Dialog), с Интернет (категория Internet), наборами данных (категория DataSet) и некоторые другие.
Перенесите на форму компоненты ActionList и ImageList. Сошлитесь в свойстве Images компонента ActionList на список ImageList. Теперь, нажав два раза по ActionList1, откроется окно редактора действий (Editing), выделите в нем категорию Edit и действие TFileExit категории File, нажмите кнопку OK.
После выбора вернется окно редактора действий (Editing), и в списке будут занесены выбранные действия, причем большинство из них имеют пиктограммы, хотя никаких пиктограмм в компонент ImageList не еще нет. Можно выделить ImageList1 и убедиться, что в него автоматически занеслись пиктограммы выбранных действий. Правда, не все пиктограммы могут удовлетворить. Но это уже личное дело заменить их другими и добавить пиктограммы для действий, автоматически с пиктограммами не связанных. Автоматическое занесение пиктограмм в список действий произойдет только в том случае, если до создания соответствующих объектов событий компонент ActionList был подключен к ImageList. В противном случае объекты появятся в ActionList без пиктограмм. Именно поэтому нужно с самого начала связать с компонентом ActionList пусть даже пустой список ImageList.
Теперь выделите в окне какое-то действие и посмотрите в Инспекторе Объектов его свойства. Во-первых, класс объектов стандартных действий будет не TAction. Каждый вид стандартного действия имеет класс, производный от TAction. В Инспекторе Объектов можно увидеть, что в стандартные действия заложены общепринятые значения множества свойств: надписи (Caption), подсказки (Hint), «горячие» клавиши (Shortcut).
Впрочем, если делать приложение для отечественного пользователя, то от этих значений мало проку: все равно надписи и подсказки надо переводить на русский язык, а «горячие» клавиши не всегда те, которые нужны, и их тоже может потребоваться изменять.
Но самое главное отличие стандартных объектов действий от нестандартных заключается в том, что для стандартных действий не надо писать обработчики событий OnExecute. Все операции, необходимые для выполнения стандартных действий уже заложены в их объекты. Они не только не требуют обработчиков событий OnExecute, но могут реализоваться через «горячие» клавиши даже без инициаторов действий разделов меню, кнопок и т.п.
Добавьте на форму инструментальную панель ToolBar и свяжите ее свойством Images со списком изображений ImageList. Установите в ToolBar в true свойство ShowHint. А теперь создайте на инструментальной панели быстрые клавиши для всех действий, имеющих пиктограммы. В каждой новой кнопке ссылайтесь в свойстве Action на соответствующее действие.
Добавьте на форму тестового приложения какие-нибудь окна редактирования, например, Edit1 и RichEdit1. Теперь выполните приложение. В начале будет, что все кнопки, кроме кнопки выхода, недоступны. Это оправдано, поскольку никакой текст не выделен, так что нечего копировать или вырезать, и никакого редактирования не было, так что нечего отменять. Может оказаться доступной только кнопка Вставить (Paste, если не переводили подсказки на русский язык). Доступной она будет, если в буфере обмена в данный момент находится текст. Но нажмите, например, клавишу компьютера Print Screen, занеся в буфер обмена изображение экрана, и кнопка Вставить станет недоступной. Чувствуете, какое умное поведение. Если выделить текст в одном из окон редактирования, то, пока это окно в фокусе, будут доступны кнопки Копировать (Сору), Вырезать (Cut), Удалить (Delete). Если провести какую-то операцию редактирования, станет доступна кнопка Отменить (Undo). Но стоит переместить курсор в другое окно редактирования, где нет выделения и не было редактирования, как эти кнопки станут недоступны.
Таким образом, в стандартные действия заложено достаточно интеллектуальное поведение. Они относятся всегда к тому элементу, который находится в фокусе (в данном примере к находящемуся в фокусе окну редактирования), и доступность их в каждый момент автоматически определяется возможностью выполнения того или иного действия. Представляете, сколько кода надо было бы написать, чтобы реализовать подобное поведение, включая тестирование формата, занесенного в буфер обмена, определение окна, находящегося в фокусе, и определение выделения в нем? Было не написано ни одного оператора, а получен такой эффект благодаря возможностям, заложенным в стандартных действиях. Но учтите, что почти весь «интеллект» стандартного действия может исчезнуть, если вести для такого действия свой обработчик события OnExecute. Тогда придется все реализовывать самому. Так что для многих стандартных действий не следует писать обработчиков событий OnExecute.
Интересно, что доступ к стандартным действиям через «горячие» клавиши сохраняется, даже если в приложении отсутствуют их инициаторы или они недоступны. Например, задайте для действия FileExit1, обеспечивающего выход из приложения, «горячие» клавиши Ctrl-E. Сделайте невидимой инструментальную панель ToolBar1 (Visible = false) и снова запустите приложение. Ни один управляющий элемент не будет доступен. Но все «горячие» клавиши будут действовать. В частности, если нажать Ctrl-E, приложение закроется. Так что стандартные действия могут работать и «за кадром».
Отметим одно свойство действий, связанных с вызовом стандартных диалогов Windows. Эти действия (классы TFileOpen, TFileSaveAs, TFilePrintSetup, TSearchFind, TSearchReplace, TSearchFindFirst, TOpenPicture, TSavePicture, TColorSelect, TFontEdit, TPrintDlg) имеют свойство Dialog объект соответствующего диалога. Таким образом, эти стандартные действия не требуют явного ввода в приложение компонентов-диалогов и явного их вызова. Но зато они имеют события BeforeExecute (наступает перед вызовом диалога), OnAccept (наступает, если пользователь в диалоге произвел выбор и нажал OK) и OnCancel (наступает, если пользователь в диалоге не произвел выбор и нажал кнопку Отказ или клавишу Esc). Из этих событий важнейшим является OnAccept, в обработчике которого можно прочитать выбор пользователя. Например, если в приложении имеется компонент RichEdit1 и стандартное действие FileOpen1, загружающее в RichEdit1 текст из выбранного пользователем файла, то обработчик события OnAccept этого действия должен иметь вид:
RichEdit1->Lines->LoadFromFile(FileOpen1->Dialog->Filename);
Чтобы обеспечить в диалоге фильтры типов файлов, надо залить их в свойстве Filter объекта Dialog, являющегося свойством действия FileOpen1.