delphidelphi-12-athens

What is GetAsyncKeyState(117) in Delphi?


I am looking through some code in a program and they have the following code in a TTimer:

procedure TMyMain.CaptureKeyTimerTimer(Sender: TObject);
var
  keyloop, KeyResult : Integer;
begin
  KeyResult := GetAsyncKeyState(117);
  if (KeyResult = -32767) then
    Button90Click(Sender);
end;

I am trying to understand what the code means and does, but it is confusing.

Can someone explain the code to me? What is GetAsyncKeyState(117)? What does the 117 mean that is passed to the function? What does it mean if it is equal to -32767?

Everything is confusing.


Solution

  • GetAsyncKeyState() takes a Virtual Key Code as input, where 117 (hex 0x75) represents the F6 key (the author should have used the VK_F6 constant in the Windows unit - stay away from magic numbers!).

    Per the GetAsyncKeyState() documentation:

    Return value

    Type: SHORT

    If the function succeeds, the return value specifies whether the key was pressed since the last call to GetAsyncKeyState, and whether the key is currently up or down. If the most significant bit is set, the key is down, and if the least significant bit is set, the key was pressed after the previous call to GetAsyncKeyState. However, you should not rely on this last behavior; for more information, see the Remarks.

    -32767 in decimal is 0x8001 in hex, and 1000000000000001 in binary. So you can see that the 2 bits mentioned in the doc above are both set to 1.

    Since the code is checking for this exact value, the author wants to know when both bits are set at the time same, IOW when the F6 key has transitioned from the UP state to the DOWN state since the previous call to GetAsyncKeyState().

    The author could have easily used the Form's OnKeyDown event to detect F6 presses, but they probably did it this way to detect the press even if the Form does not have keyboard focus. There are other ways to accomplish that more accurately, such as with a low-level keyboard hook or Raw Input, but they are a bit more complicated to code for than this simple timer.