Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GetAsyncKeyState "strange" behavior

Tags:

winapi

delphi

I have 2 simple forms, Form1 and Form2 (Delphi 7). Form1 opens Form2, and there I wait for a specific key combination (Ctrl + F2). Once I close Form2 and back to Form1, I need to check if Ctrl key is pressed. Here is an example:

FORM2

procedure TForm2.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Shift = [ssCtrl]) and (Key = VK_F2) then
    ShowMessage('Ctrl + F2 pressed!');
end;

FORM1

procedure TForm1.btn1Click(Sender: TObject);
begin
  Try
    Application.CreateForm(TForm2, Form2);
    Form2.ShowModal;
  Finally
    Form2.Release;
    Form2 := nil;
  end;
end;

procedure TForm1.btn2Click(Sender: TObject);
begin
  if (GetAsyncKeyState(VK_Control) <> 0) then
    ShowMessage('Ctrl is pressed!');
end;

Problem is, everytime I press Ctrl + F2 on Form2, it seems Ctrl key got stuck, and (GetAsyncKeyState(VK_Control) <> 0) always return true.

Please, do you know what is going on (and how to solve)?

like image 961
Guybrush Avatar asked Jul 25 '26 09:07

Guybrush


1 Answers

Your test is wrong. From the documentation:

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.

To test just for the key being down, look at the most significant bit being set. That is, if the value is negative:

if GetAsyncKeyState(VK_Control) < 0 then

I would also suggest that you should be calling GetKeyState instead, to get the state when the button is pressed rather than GetAsyncKeyState which is the state later when you process the message.

like image 117
David Heffernan Avatar answered Jul 28 '26 05:07

David Heffernan