如何捕获组合键事件?

时间:2015-11-14 04:37:58

标签: windows delphi winapi events

C#中,它是这样写的:

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Control && e.Shift && e.KeyCode == Keys.P)
    {
        MessageBox.Show("Hello");
    }
}

Capturing Ctrl + Shift + P key stroke in a C# Windows Forms application [duplicate]

我试图模仿他们在 C#中将方式写入 Delphi XE8 ,但它似乎无效:

procedure TForm12.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin
  if (GetKeyState(VK_CONTROL) < 0) and (Key = 53) then
    ShowMessage('You pressed "ctrl + s"');
end;
  

注意: TForm.KeyPreview Troperty 设置为 true

如何捕获该组合键事件?

3 个答案:

答案 0 :(得分:2)

您正在寻找的密钥 S ,代码为$53。您指定的密钥具有代码53,并且数字 5 。区别在于$表示十六进制。

如果你让编译器完成工作,你可以避免这些愚蠢的错误,让代码更清晰:

Key = ord('S')

你真的不想在你的程序中使用魔术常量。这非常重要。

请注意Keyvirtual key code,约定是拉丁字母的26个键,它们由大写字母的序数值表示。

消息已经传递了Shift参数中修饰键的状态,因此按照以下方式编写测试是惯用的:

if (ssCtrl in Shift) and (Key = ord('S')) then

使用GetKeyState进行的测试确实效果很好,但这并不是惯用的。

请注意,此测试与问题中的测试匹配,将忽略其他修饰键的状态。实际上,问题中的C#代码也忽略了 ALT 修饰符的状态。

所以你可能想要对 CTRL + S 进行真正的测试,你还必须检查其他修饰符是否已启动:

if ([ssCtrl] = Shift*[ssCtrl, ssShift, ssAlt]) and (Key = ord('S')) then

所有这些说,使用操作管理快捷方式通常要容易得多。这将允许您直接指定快捷方式,并让框架检测构成快捷方式的低级别键事件。更多动作允许您集中处理按钮和菜单背后的操作,而无需重复自己。

答案 1 :(得分:1)

您可以使用操作自动执行快捷方式。放入TActionManager并为其添加TAction。在该操作上,指定NameCaptionOnExecute事件处理程序,最重要的是ShortCut的值。在您的案例Ctrl+Shift+P中,这可以是表示击键的字符串。然后,您可以将该操作分配给各种控件,也可以将其称为MyAction.Execute

答案 2 :(得分:1)

在Delphi中,您可以使用Shift: TShiftState来检查按下了哪个&#39; -key键。

正如评论中所指出的,您的错误是字母s的键值不是十进制53,而是十六进制53,在Delphi语法中是$53。< / p>

我首先想到您还想检查shift密钥,如同您的灵感的参考来源,在这种情况下,您可以测试独占组合,如下所示:

procedure TForm15.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  if (Key = $53) and ([ssCtrl, ssShift] = Shift) then
  begin
    ShowMessage('You pressed "ctrl + shift + s"');
    Key := 0; // optional
  end;
end;

您可能想要或不想清除Key参数,以防止控件进一步采取行动。

在另一条评论之后重新阅读您的问题,您似乎只想检测Ctrl + s组合,在这种情况下,独占条件测试变为

  if (Key = $53) and ([ssCtrl] = Shift) then

我建议在换档状态测试中做到精确(独占),因为换档状态不仅包括ShiftCtrlAlt键,还包括鼠标按钮和一些手势

TShiftState上的documentation提供了Shift要检查的其他可能值。

最后,正如@David Heffernan在答案中指出的那样,使用$53而不是关键测试的魔术常量(Ord('S'))。