我在Form1的顶部做了这个:
globalKeyboardHook gkh;
在加载事件中:
private void Form1_Load(object sender, EventArgs e)
{
gkh = new globalKeyboardHook();
gkh.HookedKeys.Add(Keys.M);
gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
}
然后在底部:
void gkh_KeyDown(object sender, KeyEventArgs e)
{
// e.KeyCode.ToString() is the KeyCode of the pressed key
e.Handled = true;
if ((e.KeyCode == System.Windows.Forms.Keys.LControlKey) || (e.KeyCode == System.Windows.Forms.Keys.RControlKey))
{
controlDown = true;
}
if (e.KeyCode == System.Windows.Forms.Keys.M && controlDown)
{
// Do CTRL-M action
if (mf == null)
{
//mf = new MagnifierMainForm();
mf = new MagnifierMainForm(false);
mf.StartPosition = FormStartPosition.Manual;
mf.Location = Control.MousePosition;
//mf.Show();
this.Select();
}
else if (mf.IsDisposed)
{
mf = new MagnifierMainForm(false);
mf.StartPosition = FormStartPosition.Manual;
mf.Location = Control.MousePosition;
//mf.Show();
}
else
{
mf.Close();
mf = null;
}
}
}
void gkh_KeyUp(object sender, KeyEventArgs e)
{
controlDown = false;
}
当我运行我的应用程序并单击提示命令窗口时,例如然后单击CTRL + M,或者甚至在几秒钟之后没有点击任何内容我得到例外:
CallbackOnCollectedDelegate 在“ScreenVideoRecorder!Utilities.globalKeyboardHook + keyboardHookProc :: Invoke”类型的垃圾收集委托上进行了回调。这可能会导致应用程序崩溃,损坏和数据丢失。将委托传递给非托管代码时,托管应用程序必须保持活动状态,直到确保它们永远不会出现
检测到CallbackOnCollectedDelegate 消息:对类型为“ScreenVideoRecorder!Utilities.globalKeyboardHook + keyboardHookProc :: Invoke”的垃圾回收委托进行了回调。这可能会导致应用程序崩溃,损坏和数据丢失。将委托传递给非托管代码时,托管应用程序必须将它们保持活动状态,直到确保它们永远不会被调用为止。
答案 0 :(得分:1)
我相信你正在寻找全球键盘钩子。 这是simple C# example of usage
如果你使用上面例子中的globalKeyboardHook
类,你需要做4件事:
首先将自我标题的.cs文件添加到您的项目中(由于该代码中存在错误,至少在2007年5月30日的版本中,以下列方式修改它 - 根据成员4120854的评论):
在线下
public delegate int keyboardHookProc(int code, int wParam, ref keyboardHookStruct lParam);
添加此行
private keyboardHookProc _keyboardHookProc;
并将hook方法更改为:
public void hook()
{
IntPtr hInstance = LoadLibrary("User32");
_keyboardHookProc = new keyboardHookProc(hookProc);
hhook = SetWindowsHookEx(WH_KEYBOARD_LL, _keyboardHookProc, hInstance, 0);
}
第二次,在您的Form类中添加一个像这样的私有成员变量
globalKeyboardHook gkh = new globalKeyboardHook();
第三次,在您的Form_Load(或您想要开始挂锁的其他地方)上,将您想要的密钥添加到gkh类的HookedKeys集合属性中,并订阅KeyDown和/或gkh类的KeyUp事件,如下所示:
private void Form1_Load(object sender, EventArgs e) {
gkh.HookedKeys.Add(Keys.LControlKey);
gkh.HookedKeys.Add(Keys.RControlKey);
gkh.HookedKeys.Add(Keys.M);
gkh.KeyDown += new KeyEventHandler(gkh_KeyDown);
gkh.KeyUp += new KeyEventHandler(gkh_KeyUp);
}
第四,然后您可以在KeyUp或KeyDown处理程序中执行您想要的操作,将e.Handled设置为true以停止在系统上传播键事件,如下所示:
void gkh_KeyUp(object sender,KeyEventArgs e){ // e.KeyCode.ToString()是已释放密钥的KeyCode e.Handled = true; }
void gkh_KeyDown(object sender, KeyEventArgs e) {
// e.KeyCode.ToString() is the KeyCode of the pressed key
e.Handled = true;
}
要对特定的键组合执行某些操作,您需要在变量中记录键的状态,并在KeyDown上检查两个(或所有)键是否都已关闭。因此,对于“CTRL-M”,您将添加成员变量
bool controlDown = false;
然后您将此代码添加到您的KeyDown事件处理程序
if ((e.KeyCode == System.Windows.Forms.Keys.LControlKey) || (e.KeyCode == System.Windows.Forms.Keys.RControlKey))
{
controlDown = true;
}
if (e.KeyCode == System.Windows.Forms.Keys.M && controlDown)
{
// Do CTRL-M action
}
并且在KeyUp事件处理程序中,您需要添加此
if ((e.KeyCode == System.Windows.Forms.Keys.LControlKey) || (e.KeyCode == System.Windows.Forms.Keys.RControlKey))
{
controlDown = false;
}