Trigger Hotkey / Shortcut Event only once
I am developing a Delphi XE7 multi-platform application and want to use some hotkeys / shortcuts.
TActionList
, TMainMenu
and TMenuBar
all have properties for assigning ShortCuts.
I am using a shortcut to add a new one TTabItem
to TTabControl
. This is ShortCut Ctrl+ T.
So, if the user clicks Ctrl+ T, a new tab is added in the specified one TTabControl
- works correctly.
However, if the user continues to hold down these 2 keys, multiple tabs are also created.
The shortcut event fires as long as the user continues to hold down these keys.
Adding a new tab is just an example. I am using multiple shortcuts which I only want to run once.
Is there a way to only trigger the shortcut event once?
I've tried timers / waited for a certain amount of time. But this causes problems if the user wants to quickly execute 2 hotkeys.
Thanks for reading and I appreciate all the help.
source to share
Here's an example of how to solve this with a timer so that it blocks users from using several different actions in a row. The speed of using the same action depends on your configuration, but is limited by the delay interval for the system autostart. See Code Comments.
const
//Interval after which the action can be fired again
//This needs to be greater than system key autorepeat delay interval othervise
//action event will get fired twice
ActionCooldownValue = 100;
implementation
...
procedure TForm2.MyActionExecute(Sender: TObject);
begin
//Your action code goes here
I := I+1;
Form2.Caption := IntToStr(I);
//Set action tag to desired cooldown interval (ms before action can be used again )
TAction(Sender).Tag := ActionCooldownValue;
end;
procedure TForm2.ActionList1Execute(Action: TBasicAction; var Handled: Boolean);
begin
//Check to see if ActionTag is 0 which means that action can be executed
//Action tag serves for storing the cooldown value
if Action.Tag = 0 then
begin
//Set handled to False so that OnExecute event for specific action will fire
Handled := False;
end
else
begin
//Reset coldown value. This means that user must wait athleast so many
//milliseconds after releasing the action key combination
Action.Tag := ActionCooldownValue;
//Set handled to True to prevent OnExecute event for specific action to fire
Handled := True;
end;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
var Action: TContainedAction;
begin
//Itearate through all actions in the action list
for Action in ActionList1 do
begin
//Check to see if our cooldown value is larger than zero
if Action.Tag > 0 then
//If it is reduce it by one
Action.Tag := Action.Tag-1;
end;
end;
NOTE. Set the timer interval to 1ms. And don't forget to set ActionCooldownValue greater than the keyword autorepeat delay interval
source to share