【问题标题】:How can I detect how long a key has been held down?如何检测按键被按住的时间?
【发布时间】:2012-10-10 00:16:57
【问题描述】:

我正在寻找一种方法来检测在 Delphi 项目中某个键被按住多长时间并警告用户。

我正在开发一个聊天程序,需要查看此人是否按住了某个字母(例如 W 键)来向该聊天框发送垃圾邮件。我将举例说明在 Delphi 7 中尝试做的事情:

//Looking up if key in use and held for lets say 20 seconds
if (GetAsyncKeyState(Byte(VkKeyScan('W'))) shl 20) <> 0 then
begin
  ShowMessage('W Key Held down too long!');
end;

不过,我不确定 GetAsyncKeyState 是否会给我这些信息。如果没有,那会怎样?

【问题讨论】:

  • 收听WM_KEYDOWNWM_KEYUP消息不是更方便吗?
  • 有一个键盘重复率/重复延迟(系统范围的参数),可能因每个用户而异。我认为你应该考虑到这一点。
  • 如果有人通过从剪贴板粘贴长文本来破解您的保护怎么办?
  • 评论是有效的,但我觉得这个问题很有趣..
  • @mj2008:MSDN 说重复计数不是累积的。但是,您实际上并不需要实际计数,只需要知道消息是否重复即可。您可以从消息的wParam 的第 30 位获取该信息。

标签: delphi winapi keyboard delphi-7


【解决方案1】:

Windows 不会报告某个键被按住的持续时间,只是会针对按住的键重复相同的WM_KEY... 消息。您必须自己手动跟踪持续时间。当您检测到 WM_KEYDOWN 消息并将其 wParam 位 30 设置为 1 时,如果您尚未跟踪该密钥,请开始跟踪它并使用它存储当前系统/刻度,否则获取当前系统/刻度时间,计算持续时间,并采取相应的行动。当您收到WM_KEYUP 消息时,如果您正在跟踪它,请停止跟踪它。

【讨论】:

    【解决方案2】:

    我使用 StopWatch 单元中的 StopWatch 类来检查时间。以下是您可以尝试将其用于您想做的事情的方法:

    uses StopWatch;
    
    //in the Form's private declaration:
      StopWatch : TStopWatch;
    
    //in the Form's onCreate:
      StopWatch := TStopWatch.Create(nil);
    
    //in the Form's onDestroy:
      StopWatch.Free();
    
    //in the form/box onKeyDown:
      StopWatch.Start();
    
    //in the form/box onChange:
      if (StopWatch.ElapsedMiliseconds > 1000)
        ShowMessage('W Key Held down too long!');
    
    //in the form/box onKeyUp:
      StopWatch.Stop();
      StopWatch.Start();
      StopWatch.Stop();
    

    可能还有很多其他方法可以完成您正在尝试做的事情。但是为了快速尝试,这应该可以工作。

    我在 onKeyUp 上停止并再次启动秒表的原因是清除 ElapsedMiliseconds,以防用户在收到警报后使用键盘以外的其他方法更改框 - 所以他们不会收到两次警报。

    【讨论】:

      猜你喜欢
      • 2019-10-14
      • 1970-01-01
      • 2012-04-04
      • 1970-01-01
      • 1970-01-01
      • 2021-09-23
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      相关资源
      最近更新 更多