Reputation: 29
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
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
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