views:

339

answers:

2

I have an application with a main form. In this form I have placed three TActionMainMenuBars, because the application essentially runs in three different modes.

The menu bars are all constructed from actions stored(proxied) in an TActionManager on the main form. The ActionManager actually references actionlists on various other forms.

The menu bars are then shown+enabled and hidden+disabled such that only one is visible at a time. This works well, with the actions operating if clicked on or if navigated through using ALT and then the arrow keys or the character underlined in their caption.

The problem is however that the actions do not seem to respond to any shortcut key presses.

Does anyone know what could be causing the actions not to fire?

I will happily provide more information if needed, I am programming in C++Builder 2007 RAD Studio in WinXP SP3.

Thanks to anyone who reads this, or even reads this and comes up with a solution!

PeterMJ

Update: I failed to stated that the shortcuts in the different menus overlap in that the same shortcuts are used in the different menus for different actions, but all shortcuts are unique in there own menu.

I have also since simplified the problem in a test application, with two TActionMainMenuBars, and all actions shared a single action manager. In this case I have two actions with the same shortcut. They are placed on different menus. Then one menu is enabled at a time. In this case the shortcuts do work, BUT when using the common shortcut only the action in the first menu is fired, even when the holding menu is disabled.

This is slightly better than my actual problem in that some actions do fire, but highlights that the actions are not being triggered correctly. Does anyone no of a solution?

A: 

Be sure that the actions you want to use are actually enabled.
If you disable every action within an ActionMainMenuBar when you disable the bar, then you have a problem.
Be sure also to use available shortcuts, not conflicting with Windows global shortcuts.
Other than that I don't see why it wouldn't work. I tried with 2 ActionMainMenuBars in Delphi and the shortcuts worked.

François
Thank you for trying it, it spurred me to write a test application with two menu bars and actions in a single action manager. As you can see from the update, this also does not work either.
+2  A: 

Enabling/disabling or showing/hiding of a ActioneMenuBar has no consequences for the actions on the menu bar. If you want to make some actions not available in a certain context/situation, you need to implement the "OnUpdate" event of either the action itself or the action list or action manager it is part of.

For example, using the following OnUpdate event of your action manager, you can use a TCheckBox to decide which of two actions is currently activated.

  if CheckBox1.Checked then
  begin
    Action1.Enabled:= False;
    Action2.Enabled:= True;
  end
  else
  begin
    Action1.Enabled:= True;
    Action2.Enabled:= False;
  end;

Imagine, both actions have the shortcut "Ctrl+A" assigned, this will mean that pressing Ctrl+A will only activate Action1 when CheckBox1 is not checked.

However, there is still a problem. The VCL will stop looking for actions with a certain shortcut once it has found an action with the shortcut in an action manager or action list in the current form, even when the found action is not enabled.

To solve this problem, you can use the OnUpdate event to dynamically set and reset the ShortCut property of actions like this:

  if CheckBox1.Checked then
  begin
    Action1.Enabled:= False;
    Action1.ShortCut:= scNone;

    Action2.Enabled:= True;
    Action2.ShortCut:= ShortCut(ord('A'), [ssCtrl]);
  end
  else
  begin
    Action2.Enabled:= False;
    Action2.ShortCut:= scNone;

    Action1.Enabled:= True;
    Action1.ShortCut:= ShortCut(ord('A'), [ssCtrl]);
  end;

Using this code, pressing Ctrl+A will activate Action2, if CheckBox1 is checked and will activate Action1, if CheckBox1 is not checked. You don't need to explicitly call the OnUpdate event of an action list or action manager. The event is fired regularly when the application is idle and waiting for user input.

NineBerry