我目前正在开发一个项目来处理设置热键以执行操作。我有热键功能,但如果键只由修饰符组成,我不想允许设置热键。例如, Ctrl + F 是有效的热键,但 Ctrl + Alt 不是。
我尝试了几种方法从实际的Keys枚举对象中剥离修改键,然后根据Keys.None检查它以确定它是否仅由修饰键组成。然而,在实践中,这并没有那么好。
我首先尝试了这个方法:
private Keys StripModifiers(Keys Key)
{
return Key & ~Keys.Modifiers;
}
这不起作用,因为我的Ctrl键似乎是调用具有LButton的KeyData属性的PreviewKeypress方法。 ShiftKey |控件,Keys.Modifiers位掩码显然没有完全捕获。
我尝试编写自己的,更复杂的:
private Keys StripModifiers(Keys Key)
{
return Key &
~Keys.Alt &
~Keys.CapsLock &
~Keys.Control &
~Keys.ControlKey &
~Keys.LControlKey &
~Keys.LMenu &
~Keys.LShiftKey &
~Keys.LWin &
~Keys.MButton &
~Keys.Menu &
~Keys.NumLock &
~Keys.RButton &
~Keys.RControlKey &
~Keys.RMenu &
~Keys.RShiftKey &
~Keys.RWin &
~Keys.Scroll &
~Keys.Shift &
~Keys.ShiftKey;
}
然而,这不起作用,因为按下A键,它只是调用KeyData属性为65的事件,将其减少为Keys.None,因此限制性太强。
此时此刻我很茫然,有没有人遇到或解决过这个问题?
答案 0 :(得分:2)
您的原始代码是正确的。您可以使用Key & Keys.KeyCode
使其更清晰,但会产生相同的结果。因此,您需要在“选项”窗口中使用此方法:
private static IsValidShortcutKey(Keys key) {
return (key & Keys.KeyCode) != Keys.None;
}
你在谈论ProcessKeyPreview()时会有点迷失。您应该使用ProcessCmdKey()而不是btw。在用户选择了被IsValidShortcutKey()认为有效的密钥之后很久,以后。是的,任何键都会使该方法运行,无论它是否与您选择的快捷方式匹配。由于Keys.ToString()方法在显示真实键击时做了很糟糕的工作,因为Keys枚举具有[Flags]属性,因此会产生额外的混乱。转换为int以查看实际值。
所以你应该有两个非常不同的代码块。 “选项”菜单中的一个块,用于检查请求的键击是否有效。它应该使用IsValidShortcutKey()。
另一个块检查按键是否被按下。哪个应该像这样:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == keySelectedInConfig) {
RunOperationSelectedInConfig();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}