我正在尝试制作一个“键盘记录器”...好吧,它不完全是一个键盘记录器,因为它只显示击键而不将它们记录到文件中。我计划在我的 Google+ 环聊中使用它,这样我仍然可以显示我的按键操作,而无需将其与视频录制软件一起使用。
private void OnKeyDown(object sender, KeyEventArgs e)
{
lblText.Text = "";
lblText.Visible = false;
boxSpKey.Image = null;
boxSpKey.Visible = false;
boxCtrl.Visible = e.Control;
boxAlt.Visible = e.Alt;
boxWin.Visible = false;
boxShift.Visible = e.Shift;
Keys pKey = e.KeyData;
if (btnIcons.ContainsKey(pKey))
{
boxSpKey.Visible = true;
boxSpKey.Image = btnIcons[pKey];
}
// this part I haven't figured out either, but is irrelevant to my question.
}
private void OnKeyPress(object sender, KeyPressEventArgs e)
{
lblText.Visible = true;
lblText.Text = ((char)e.KeyChar).ToString();
}
[Context: lblText
是包含按键文本的标签,boxSpKey
是用于 ESC 等特殊按键的 PictureBox
,为此我我们把每一个都做成了一个图标。 boxCtrl
、boxAlt
、boxWin
和 boxShift
也是 PictureBox
es 相当自定的解释。]
问题:
看起来
e.Control
、e.Alt
和e.Shift
的值总是False,所以相应的PictureBox
es 将不会显示。如何检查
Win
键的状态?我不想使用低级VK_*
常量。当
OnKeyPress
处理事件时(主要是使用修饰键),我会得到随机字符...我如何准确地从中获取原始击键?即我想要使用Ctrl+Shift+B
而不是┐
。
更新:我决定使用修饰键进行低级别操作,因此我使用了 P/Invoke:
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool GetKeyboardState(byte[] lpKeyState);
public static byte code(Keys key)
{
return (byte)((int)key & 0xFF);
}
private void OnKeyDown(object sender, KeyEventArgs e)
{
var array = new byte[256];
GetKeyboardState(array);
// ...
if ((array[code(Keys.ControlKey)] & 0x80) != 0)
boxCtrl.Visible = true;
if ((array[code(Keys.LMenu)] & 0x80) != 0 || (array[code(Keys.RMenu)] & 0x80) != 0)
boxAlt.Visible = true;
if ((array[code(Keys.LWin)] & 0x80) != 0 || (array[code(Keys.RWin)] & 0x80) != 0)
boxWin.Visible = true;
if ((array[code(Keys.ShiftKey)] & 0x80) != 0)
boxShift.Visible = true;
// ...
}
好消息是我可以使用 Ctrl
、Win
和 Shift
键,但不能使用 Alt
;除非 Alt
≠ LMenu
和 RMenu
。给出了什么?
最佳答案
按 Ctrl、Alt 或 Shift 分别导致
Control
、Alt
和Shift
在我的KeyDown
事件处理程序中返回true
。单独按下这些键中的每一个都会导致我的KeyUp
事件处理程序返回false
。您确定没有处理KeyUp
事件吗?正如 @sean woodward 所说, 应映射到
Keys.LWin
或Keys.RWin
KeyPress
事件仅在按下其中一个字符键时引发,并将返回由按下的按键或按下的按键组合产生的字符。Ctrl+Shift+B
不是字符,因此您不能单独使用KeyChar
来获取该信息。尝试使用KeyDown
或KeyUp
事件并查看Modifiers
属性以获取正在按下的修改键的逗号分隔字符串。如果顺序很重要,您需要跟踪它,因为Modifiers
始终以相同的顺序返回按键,即Shift、Control、Alt
,即使这不是按下它们的方式。
这是我使用的代码,您可以尝试使用它:
KeyDown += (o, ea) =>
{
System.Diagnostics.Debug.WriteLine("KeyDown => CODE: " + ea.KeyCode +
", DATA: " + ea.KeyData +
", VALUE: " + ea.KeyValue +
", MODIFIERS: " + ea.Modifiers +
", CONTROL: " + ea.Control +
", ALT: " + ea.Alt +
", SHIFT: " + ea.Shift);
};
KeyUp += (o, ea) =>
{
System.Diagnostics.Debug.WriteLine("KeyUp => CODE: " + ea.KeyCode +
", DATA: " + ea.KeyData +
", VALUE: " + ea.KeyValue +
", MODIFIERS: " + ea.Modifiers +
", CONTROL: " + ea.Control +
", ALT: " + ea.Alt +
", SHIFT: " + ea.Shift);
};
KeyPress += (o, ea) =>
{
System.Diagnostics.Debug.WriteLine("KeyPress => CHAR: " + ea.KeyChar);
};
关于c# - 在 C# 中处理 KeyDown 和 KeyPress 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14917422/