在C#中处理KeyDown和KeyPress事件#
我试图制作一个“键盘记录器”......好吧,它不完全是一个键盘记录程序,因为它只显示击键并且不会将它们记录到文件中。我打算在我的Google+环聊中使用它,所以我仍然可以在不用视频录制软件的情况下显示我的按键。在C#中处理KeyDown和KeyPress事件#
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();
}
[上下文:lblText
是包含关键文本的标签,boxSpKey
为特殊键,如ESC,我已完成针对每一个图标的PictureBox
。 boxCtrl
,boxAlt
,boxWin
和boxShift
也PictureBox
ES是相当不言自明]
问题:
看来的
e.Control
,e.Alt
和e.Shift
值始终是假的,所以相应的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键,或移单独引起
Control
,Alt
和Shift
在我KeyDown
事件处理程序返回true
。单独按下这些键中的每一个导致在我的KeyUp
事件处理程序中返回false
。你确定你没有处理KeyUp
事件吗?正如@sean伍德沃德表示,应该映射到任何
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);
};
怎么样使用密钥对e.Modifiers财产比较,http://msdn.microsoft.com/ EN-US /库/ system.windows.forms.keys.aspx?请参阅LWin和RWin以获取Windows键。 – 2013-02-17 02:55:01
在我的键盘上按下'Alt'键会在我的处理程序中产生'Keys.Menu'的'KeyCode'值。它似乎没有区分左侧和右侧。不幸的是,我没有其他键盘可以测试。 – gowansg 2013-02-17 18:24:43
@gowansg奇怪的......'LMenu'和'RMenu'键应该检查两侧的Alt键,但似乎只是'Keys.Menu'工作。谢谢〜 – 2013-02-17 19:18:55