user1624498
user1624498

Reputation: 29

How can I detect how long a key has been held down?

I'm looking for a way to detect how long a key has been held down in a Delphi project and warn user.

I'm working on a chat program and need to see if the person is holding down a letter, like the W key, to spam that chat box. I'll give sample what trying to do in 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;

I'm not sure whether GetAsyncKeyState will give me that information, though. If it doesn't, what will?

Upvotes: 2

Views: 979

Answers (2)

Remy Lebeau
Remy Lebeau

Reputation: 596823

Windows does not report the duration of how long a key has been held down, only that the same WM_KEY... message is being repeated for a key that is held down. You have to keep track of the duration yourself manually. When you detect a WM_KEYDOWN message with its wParam bit 30 set to 1, if you are not tracking that key yet, start tracking it and store the current system/tick with it, otherwise grab the current system/tick time, calculate the duration, and act accordingly. When you receive a WM_KEYUP message, stop tracking that key if you are tracking it.

Upvotes: 4

Ben C
Ben C

Reputation: 395

I use the StopWatch class in the StopWatch unit to check for timing. Here's how you could try using it for what you're trying to do:

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();

There are likely lots of other ways to accomplish what you're trying to do though. But for a quick try this should work.

The reason I stop and start the stopwatch again onKeyUp is to clear out ElapsedMiliseconds, in case the user changes the box with some method other than the keyboard, after having been alerted -- so they won't get alerted twice.

Upvotes: 1

Related Questions