GetAsyncKeyState"奇怪"的行为

Guy*_*ush 1 delphi winapi

我有2个简单的表单,Form1和Form2(Delphi 7).Form1打开Form2,然后我等待特定的组合键(Ctrl + F2).一旦我关闭Form2并返回到Form1,我需要检查是否按下了Ctrl键.这是一个例子:

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;
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

问题是,每次我在Form2上按Ctrl + F2时,似乎Ctrl键卡住了,(GetAsyncKeyState(VK_Control)<> 0)总是返回true.

请问,你知道发生了什么(以及如何解决)?

Dav*_*nan 6

你的测试是错误的.从文档:

如果函数成功,则返回值指定自上次调用GetAsyncKeyState以来是否按下了键,以及该键当前是向上还是向下.如果设置了最高有效位,则键为关闭,如果设置了最低有效位,则在上一次调用GetAsyncKeyState之后按下该键.

要测试关键是否正在关闭,请查看正在设置的最重要位.也就是说,如果值为负:

if GetAsyncKeyState(VK_Control) < 0 then
Run Code Online (Sandbox Code Playgroud)

我还建议您应该调用GetKeyState,在按下按钮时获取状态,而不是GetAsyncKeyState在处理消息时的状态.