I have been developing a VCL program and am adding code for placing a 'Recent Files' dropdown submenu listing a group of files. For this program I have populated a tActionManager and a tActionMainMenuBar. I have created similar menus before using tmenuitems in a standard tMainMenu component generating the list of recent file submenu items in the FormCreate event procedure. However, I am uncertain how to go about this dynamically using the Action components and have not found any examples to serve as a model.
Can anyone provide an example of how this is done
To illustrate this I created a simple application with an action manager as TActionMainToolBar and added a simple file menu using standard items Open, Save As and Exit (no separators) plus a speed button.
The speed button adds two separators and a file action, and its OnClick event looks like this...
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;
Running the program and opening the file menu shows the three expected entries. After clicking the button (don't do it twice - it is justy to demonstrate how it works) you get the two separators and a new menu sub item with the caption 'Fred' Note that you may need to give it a unique name if you need to do any handling of it.
Building sub menus can be done basically the same way but with a little trick of adding an unused and not visible item not through the action manager. It doesn't have to be done this way - it is just a simple way to get what we want.
This code shows how to achieve this:
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;