2

Please assist me: How to assign an up arrow keyboard shortcut to action or menu item, and keep it actual for navigating the list control (e.g. ListBox/Virtual Treeview/other) at the same time?

Thanks!

menjaraz
  • 7,551
  • 4
  • 41
  • 81
  • So, you want that (1)the user presses Up arrow key (2) some Action assigned to this key is then fired (say, for example, you have some menu item "Edit | Up" *and* (3) the List control that has focus receives the key, too. Is that what you want? – PA. Feb 01 '10 at 13:25
  • Yes, I need the normal menu item with the normal shortcut assigned to the up arrow key. For example, "Volume Up" item and the shortcut's text "Up" at the right. Also I need the normal navigating behaviour in the list control when is is focused (when it is an active contol). – Dmitry Kramarov Feb 01 '10 at 14:11
  • Don't, you are breaking the User Interface Guidelines. To quote http://msdn.microsoft.com/en-us/library/aa511502.aspx#accessKeys: "Choose shortcut keys that don't have standard assignments. Never reassign standard shortcut keys." – mghie Feb 01 '10 at 19:05
  • And how about the Winamp player? It has Volume Up/Volume Down features assigned to the up arrow key and down arrow key correspondingly.. Okay, if that impossible in Delphi, then how can I display a custom shortcut's text at the right of menu item? – Dmitry Kramarov Feb 02 '10 at 02:34

2 Answers2

2

You comment:

And how about the Winamp player? It has Volume Up/Volume Down features assigned to the up arrow key and down arrow key correspondingly.. Okay, if that impossible in Delphi, then ...

but it certainly is possible, it just isn't a good idea to do it, and against the Windows User Experience Interaction Guidelines.

But if you're set on implementing it, here's how. Override the following method in your form class that contains the action components:

function IsShortCut(var Message: TWMKey): Boolean; override;

and in it you can prevent the Up and Down key from triggering the actions they are shortcuts for:

function TWeirdForm.IsShortCut(var Message: TWMKey): Boolean;
begin
  if (Message.CharCode in [VK_UP, VK_DOWN])
    // insert test whether message needs to go to the focused control instead
    and (...)
  then begin
    // insert calls to code that should be executed instead
    Result := False;
    exit;
  end;
  inherited;
end;

Note that you should test for the correct shift state too, and check that your code doesn't break any other window behaviour users expect, like moving of the window with the arrow keys.

mghie
  • 32,028
  • 6
  • 87
  • 129
0

On the form properties set KeyPreview := true

then on KeyUp event of the form write event to check if you Up key is pressed and make it call the menu item (on this case menu item called Action1):

procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (Key = VK_UP) and (ActiveControl = ListBox1)then
    Action11.Click;
end;

procedure TForm1.Action11Click(Sender: TObject);
begin
  if ListBox1.ItemIndex >=0  then
    ShowMessage(ListBox1.Items[ListBox1.ItemIndex]);
end;

If you need the Action1 to be executed even if they Current Control isn't the listbox, remove the and part of the IF statement

Mohammed Nasman
  • 10,992
  • 7
  • 43
  • 68
  • This is not so suitable in my case: I need the normal action and menu item with shortcut's text ("Up" or "Up Arrow") at right. Is is possible in Delphi to not override the "shortcuted" key and pass it to the list control if it is currently active? – Dmitry Kramarov Feb 01 '10 at 14:36