Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 仅触发一次热键/快捷方式事件_Delphi_Firemonkey_Hotkeys_Shortcuts - Fatal编程技术网

Delphi 仅触发一次热键/快捷方式事件

Delphi 仅触发一次热键/快捷方式事件,delphi,firemonkey,hotkeys,shortcuts,Delphi,Firemonkey,Hotkeys,Shortcuts,我正在开发一个DelphiXe7多平台应用程序,希望使用一些热键/快捷键 TActionList、TMainMenu和TMenuBar都具有分配快捷方式的属性 我正在使用快捷方式在TTabControl上添加新的TTabItem。快捷键是Ctrl+T 因此,如果用户按Ctrl+T,则在所述TTabControl上会添加一个新选项卡,该选项卡工作正常 但是,如果用户一直按住这两个键,也会创建多个选项卡 只要用户一直按住这些键,就会触发快捷方式事件 添加新选项卡只是一个示例。我正在使用多个我只想触发

我正在开发一个DelphiXe7多平台应用程序,希望使用一些热键/快捷键

TActionList
TMainMenu
TMenuBar
都具有分配快捷方式的属性

我正在使用快捷方式在
TTabControl
上添加新的
TTabItem
。快捷键是Ctrl+T

因此,如果用户按Ctrl+T,则在所述
TTabControl
上会添加一个新选项卡,该选项卡工作正常

但是,如果用户一直按住这两个键,也会创建多个选项卡

只要用户一直按住这些键,就会触发快捷方式事件

添加新选项卡只是一个示例。我正在使用多个我只想触发一次的快捷方式

有没有办法只触发一次快捷方式事件

我试过定时器/等待特定的时间。但是,如果用户想要快速执行2个热键,则会出现问题


感谢阅读并感谢所有帮助。

下面是一个如何使用计时器解决此问题的示例,以便它不会阻止用户连续使用多个不同的操作。使用相同操作的速度取决于您的配置,但受系统键自动回复延迟间隔的限制。请参见代码注释中的

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;

注意:将计时器间隔设置为1毫秒。不要忘记将ActionCooldownValue设置为大于系统键自动回复延迟间隔

这不仅仅与Firemonkey有关。这是VCL应用程序中的默认行为。也它是,但你将无法使用FMX的公认解决方案。我认为除了使用计时器之外,没有其他解决方案,因为热键不会检测何时按下键,而是定期检查特定时间是否按下了某些键的组合。如果事件被触发,这似乎不是一个值得花时间解决的问题。你的客户不是很快就会明白这一点,不再按住钥匙这么久吗?这是其他软件供应商解决的问题吗?如果没有,那你为什么要这样做?@RobKennedy我没有任何客户,因为这是我正在从事的个人项目(我是一名学生)。我问这个问题是出于好奇。但我想你是对的。如果它没有损坏,就不要修复它。你可以使用一个标志来禁用多重发射。仅在启用时执行此工作。在处理操作后设置此禁用标志,并清除右键启动事件。感谢您的努力。我不是在寻找计时器解决方案,但你的解决方案很好。我知道你不是在寻找这种解决方案,但因为我的一个项目中已经有类似的解决方案,我想我可以分享一下。无论如何,另一种可能的方法是完全省略内置热键功能,并在启用KeyPreviewEnabled时使用表单OnKeyDown和OnKeyUp事件重新实现类似的功能。在本例中,您将实现快捷方式功能,因为它通常用于Delphi的预览版本,而该版本中尚未内置此功能。实现这一点需要相当多的代码,而且不是那么容易使用。