Delphi 2010 Action Manager & Main Menu Bar - delphi

I'm trying to use the Action Manager and Action Main Menu Bar in Delphi 2010 an I have no idea how to make this work. I've tried looking at the examples that come with Delphi 2010 and I can't seem to figure this out.
I've tried playing around with the examples. I've been able to add an image to the Image List component and set that item to the new item index. At design time it displays properly at runtime it reverts back to the original.
I'd like to learn how to use the Action Manager and Action Main Menu Bar but I can find any help on these topics. Is there a tutorial on how to use the Action Manager and Action Main Menu Bar?

Drag and drop a ActionManager, a ActionMainMenuBar and a ImageList on your form.
Doubleclick the ImageList, you get the Imagelist Editor. Use the Add-button to add your icons (make sure their sizes are the same as the Height and Width properties that are set in the ImageList-control).
Set the Images-property of the ActionManager to your ImageList and set the ActionManager-property of your ActionMainMenuBar to your ActionManager.
Doubleclick the ActionManager, go to the tab 'Actions' and add new actions by the 'New'-button.
Click each Action in the ActionManager and set each action's properties, at least: ImageIndex (to choose an Icon), Caption and Category.
Note: A Category will serve as a main item in the menu (like File, Edit and View) and each Action will serve as menu item (like Save, Save as, Load). So set the Category property of all actions you want to belong to one main menu item to the same name. For instance give the actions 'Save' and 'Load' the category 'File' and give the actions 'Undo' and 'Redo' the category 'Edit'.
Doubleclick each Action in the ActionManager. You'll get the code editor. Type the code you want to perform when the user clicks this menu item. If you don't type any code or comment, the menu item will automatically be disabled when the application is running.
Now drag the categories from the ActionManager to the ActionMainMenuBar.
That's it.

I think Actions, Action Lists And Action Managers by Brian Long is a great start to explore the realm of actions.

Related

Dynamically Modify ActionMenuBar Items When Category is Clicked

I am creating a menu using an ActionManager and an ActionMenuBar. I want to add and subtract items from the menu when the top-level menu node is clicked but I can't find a clean way to do this. For example, I want to create a top-level menu "Windows" that hosts items corresponding to every modeless form. I can create the top-level "Windows" menu by creating a Category named Windows in the ActionManager and dragging "Windows" to the menu bar. When "Windows" is clicked I would then like to populate Items property with TActionClientItems corresponding to the application's modeless forms. I do know the mechanics of dynamically adding action clients at runtime (for example, in the form's oncreate event) but I can't find an action that fires when a Category (in this case, "Windows") is clicked.
I could work around this by updating the menu whenever a form is hidden or shown, but this seems inelegant compared to updating the menu on demand. I tried attaching an action to the "Windows" actionclientitem but the action's onexecute doesn't fire (apparently because it is a Category).
The failure of the onexecute handler to be called can be demonstrated with the following steps:
In Actionmanager create action named "Action1" and assigned its
category property to "Windows".
Drag the "Windows" category to
the menubar.
Create an action named WindowAction and assigned no
category to it.
Add "Showmessage('x');" to the OnExecute of
WindowAction.
In designer click on ActionManager1->ActionBars->0->Items-."0-Windows" (which is TActionClients[0]). Set TActionClients[0].Action := WindowAction.
Correct the caption of TActionClients[0] so that it is again "Windows".
Run program, click "Windows" on menu and showmessage not shown.

Delphi TActionMainenuBar - 2nd-level submenu menu item is disabled

With Delphi XE5 I am converting a TMainMenu to a TActionMainMenuBar but I am having issues with a submenu node within a category being disabled at runtime, for example in my 'File' category. Most 'File' category items are actions dragged over from the Action Manager, but I also want to group two of those actions under a submenu node within the File menu. With TMainMenu I would simply use Create submenu and edit the resulting TMenuItem caption, but I see that the TActionMainMenuBar has context items for each client item, and this is what I've tried to use. The result is that the layout looks ok but the submenu item is disabled at runtime (presumably because it does not have an action).
This is what I see at design time - I've created the 'Batch Reporting' item myself using 'Add item' in the object inspector.
This is what I see at run time, the item is disabled.
This is what I see in the object inspector with my context items included.
Should I be setting a special property on the 'Batch Reporting' item to give it a 'no action' status? Or am I forced to use an action with a 'do nothing' OnExecute?
I've found the answer - I was using the 'Context Items' of the submenu, I should have been using 'Items' as shown below. Very confusing!

How to disable menu, sub-menu in ActionMainMenuBar?

Using: Delphi XE3, VCL Forms application
I have a menu containing a sub-menu in a ActionMainMenuBar. How can I via code:
disable the menu
disable the sub-menu
Create a 'TAction' per menu/submenu that you want to enable disable. Do not assign them to any category.
Create an 'OnExecute' event handler for these actions, so that these can be enabled. You don't have to put any code in the handler, a comment ('//') is enough for the IDE to not to delete the handlers.
Select the 'TActionClient' that represents the menu/submenu from the form designer, just click on the item.
Assign one of the actions to its 'Action' property in the object inspector.
Enable/disable the action associated with the 'TActionClient' that represents the menu/submenu at run time for the menu/submenu to be enabled/disabled accordingly.
By using the 'enabled' property of the menu? or the menu-item that is the starting point of the submenu...
You can actually disable it at runtime (in Delphi 7 anyway) if you know the index of the top-level menu item for the category as follows:
ActionMainMenuBar.ActionControls[2].Enabled := False;
ActionControls[2] would be the category showing as a top-level menu item (after dragging the category onto ActionMainMenuBar from ActionManager.

Delphi IDE wizard to automatically generate actions from menu items?

At design-time inside the IDE, is there a quick 'n' easy trick to automatically generate actions from several menu items and then apply these actions back to the menu items?
The drop down of the action inside the Object Inspector allows you to create a new action which will automatically be connected, but you have to set the actions properties manually and implement the event handles separately.

Delphi - Duplicate tpanel and tbuttons on second form

On my main form I have a TPanel containing buttons that act as a toolbar. I want to clone/copy this toolbar and the buttons and their functionality to a second form.
Cloning the menu was simple using newmenu.merge(mainmenu). That was an excellent shortcut to duplicating a Tmainmenu.
But I am at a loss on how to easily duplicate my toolbar without having to manually assign the events and keep a timer to compare and track which buttons are enabled and disabled in comparison to the real mainmenu on the main form. Depending on what the application is doing the main toolbar buttons will be enabled and disabled at various times.
Any ideas here? Thanks for any suggestions or tips to make this easier.
Duplicating the controls
In the Form Designer, select the panel and press Ctrl+C to copy it and all its children to the clipboard. Go to the second form and press Ctrl+V to paste.
If you're still working on the design and want to keep it consistent between both forms, then create a TFrame and design your toolbar layout there. Then put an instance of that frame on both your forms. Changes to the frame design will be reflected in the forms.
See Working with frames in the help.
Making sure both sets of buttons are enabled consistently
Create a data module. Put a TActionList on it. Add an action to it for each button on your main form. Assign event handlers to the actions' OnUpdate events. In them, set the actions' Enabled properties. Finally, assign each button's Action property to refer to the corresponding action object. The buttons will automatically get enabled and disabled with the actions. No timer required.
Furthermore, you can handle the actions' OnExecute events, too. Clear each button's OnClick property, and then move the button's OnClick code into the corresponding action's OnExecute handler. It will automatically get called when you click the button, even though the OnClick property is empty.
When you assign the Caption or Hint property of a TAction, the corresponding properties of any associated controls also change. Likewise for images, if the control supports them. Actions can be assigned to menu items, too.
See Using action lists in the help.
Acting like a toolbar
Just use TToolbar. That's what it's for.
Or, once you're used to actions, put a TActionManager in your project and use it with TActionToolbar and TActionMainMenuBar. See Organizing actions for toolbars and menus in the help.
Are the buttons attached to actions? If so, you can use the OnUpdate event of the TActionList to specify what should and should not be enabled. If not, it isn't too much work to convert to using actions.
If you go this route to convert to using a ActionList, consider putting the ActionList in a datamodule where different units and forms could reference it.
You can Use ClipBoard Object For Copy Your Panel.
Clipboard.SetComponent(Panel1);
Clipboard.GetComponent(Form2,GroupBox1);

Resources