Как программно добавить подменю в TActionMainMenuBar?

Я занимаюсь разработкой программы VCL и добавляю код для размещения выпадающего подменю "Последние файлы", в котором перечислены группы файлов. Для этой программы я заполнил tActionManager и tActionMainMenuBar. Я создал подобные меню перед использованием tmenuitems в стандартном компоненте tMainMenu, генерирующем список последних элементов подменю файлов в процедуре события FormCreate. Однако я не уверен, как это сделать динамически, используя компоненты Action, и я не нашел примеров, которые могли бы служить моделью.

Кто-нибудь может привести пример того, как это делается

1 ответ

Решение

Чтобы проиллюстрировать это, я создал простое приложение с менеджером действий под названием TActionMainToolBar и добавил простое файловое меню, используя стандартные пункты "Открыть", "Сохранить как" и "Выход" (без разделителей) плюс кнопку скорости.

Кнопка "Скорость" добавляет два разделителя и действие с файлом, и ее событие OnClick выглядит следующим образом...

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  iActionClientItem : TActionClientItem;
  iFileAction : TCustomAction;
begin
  //  Edit2.Text := BaseToBase( Edit1.Text, SpinEdit1.Value , SpinEdit2.Value );
  ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1), FALSE );
  iActionClientItem := ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1) );
  iFileAction :=  TCustomAction.Create( self ); // we want to put in same collection
  iFileAction.Caption := 'Fred';
  // etc.. to build what is wanted
  iActionClientItem := ActionManager1.AddAction( iFileAction, iActionClientItem )  ;
end;

Запуск программы и открытие меню файла показывает три ожидаемые записи. После нажатия кнопки (не делайте это дважды - просто продемонстрируйте, как она работает), вы получите два разделителя и новый подпункт меню с надписью "Fred". Обратите внимание, что вам может потребоваться дать ему уникальное имя, если Вы должны сделать любую обработку этого.

редактировать

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

Этот код показывает, как этого добиться:

procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  iActionClientItem : TActionClientItem;
  iSubMenuItem : TActionClientItem;
  iFileAction : TCustomAction;
  iChildMenu : TActionBarItem;
begin
  ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1), FALSE );
  iActionClientItem := ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1) );
  iFileAction :=  TCustomAction.Create( self ); // we want to put in same collection
  iFileAction.Caption := 'Fred';
  // etc.. to build what is wanted
  iActionClientItem := ActionManager1.AddAction( iFileAction, iActionClientItem )  ;

  //*********************************
  // Build sub menu (from Fred) - stage 1 add the visual element - a new action bar
  iChildMenu :=  ActionManager1.ActionBars.Add;
  iActionClientItem.ChildActionBar := iChildMenu.ActionBar;

  // we add a dummy entry that we can build from.
  // We could set the properties manually, but when we use the action manager
  // it does that automatically, so it is easier just to set this item to not visible
  // then use action manager to do the rest.
  iSubMenuItem := iActionClientItem.Items.Add;
  iSubMenuItem.Visible := FALSE;

  // Now the real build...

  iFileAction :=  TCustomAction.Create( self ); // we want to put in same collection
  iSubmenuItem := ActionManager1.AddAction( iFileAction, iSubMenuItem );
  iSubmenuItem.Caption := 'Fred 1';
  // etc

  iFileAction :=  TCustomAction.Create( self ); // we want to put in same collection
  iSubmenuItem := ActionManager1.AddAction( iFileAction, iSubMenuItem );
  iSubmenuItem.Caption := 'Fred 2';
  // etc
end;
Другие вопросы по тегам