C# WinForm键盘钩子

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# WinForm键盘钩子相关的知识,希望对你有一定的参考价值。

WinForm~~设置拦截鼠标和键盘,但是键盘的数字键盘和回车不拦家,热键全部拦截!该如何写??发送至850297396@q.c
那个是QQ邮箱的,写少了@qq.com

参考技术A 你把MyHookProc函数改一下就可以了,

IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)

if( code < 0 ) return CallNextHookEx(_nextHookPtr,code, wparam, lparam); //返回,让后面的程序处理该消息
return (IntPtr) 1; //直接返回了,该消息就处理结束


实现过程:
1、新建一个C#的WindowsApplication
2、在Form1中,添加下面一些变量:
internal enum HookType //枚举,钩子的类型

//MsgFilter = -1,
//JournalRecord = 0,
//JournalPlayback = 1,
Keyboard = 2,
//GetMessage = 3,
//CallWndProc = 4,
//CBT = 5,
//SysMsgFilter = 6,
//Mouse = 7,
//Hardware = 8,
//Debug = 9,
//Shell = 10,
//ForegroundIdle = 11,
//CallWndProcRet = 12,
//KeyboardLL = 13,
//MouseLL = 14,
;
IntPtr _nextHookPtr; //记录Hook编号

3、在Form1中引入必须的API
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId(); //取得当前线程编号的API
[DllImport("User32.dll")]
internal extern static void UnhookWindowsHookEx(IntPtr handle); //取消Hook的API

[DllImport("User32.dll")]
internal extern static IntPtr SetWindowsHookEx(int idHook, [MarshalAs(UnmanagedType.FunctionPtr)] HookProc lpfn, IntPtr hinstance, int threadID); //设置Hook的API

[DllImport("User32.dll")]
internal extern static IntPtr CallNextHookEx(IntPtr handle, int code, IntPtr wparam, IntPtr lparam); //取得下一个Hook的API
4、声明一个实现的委托

internal delegate IntPtr HookProc(int code, IntPtr wparam, IntPtr lparam);
5、添加自己的Hook处理过程

IntPtr MyHookProc(int code, IntPtr wparam, IntPtr lparam)

if( code < 0 ) return CallNextHookEx(_nextHookPtr,code, wparam, lparam); //返回,让后面的程序处理该消息
if( wparam.ToInt32() <96 || wparam.ToInt32()>105 || wparam.ToInt32()<>13 )
//如果用户输入的不是0-9和回车就拦截

return (IntPtr) 1; //直接拦截,该消息就处理结束了

else

return IntPtr.Zero; //返回,让后面的程序处理该消息



6、添加加入Hook链和从Hook链中取消的函数
public void SetHook()

if( _nextHookPtr != IntPtr.Zero ) //已经勾过了

return;
HookProc myhookProc = new HookProc(MyHookProc); //声明一个自己的Hook实现函数的委托对象
_nextHookPtr = SetWindowsHookEx((int)HookType.Keyboard, myhookProc , IntPtr.Zero , GetCurrentThreadId()); //加到Hook链中

public void UnHook()

if( _nextHookPtr != IntPtr.Zero )

UnhookWindowsHookEx(_nextHookPtr); //从Hook链中取消
_nextHookPtr = IntPtr.Zero;


7、在Form1的Load事件中添加 SetHook() , 在Form1的closing 事件中添加 UnHook()

private void Form1_Load(object sender, System.EventArgs e)

SetHook();

private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)

UnHook();
追问

你这代码不是原创的...网络上搜到的吧

追答

代码有几个原创的,都是抄微软的

参考技术B 写事件就可以了呀

用于 C# 和 WPF 的高级全局键盘钩子,用于读取键盘楔形卡扫描仪

【中文标题】用于 C# 和 WPF 的高级全局键盘钩子,用于读取键盘楔形卡扫描仪【英文标题】:High level global keyboard hook for C# and WPF for reading a keyboard wedge card scanner 【发布时间】:2010-01-26 01:59:30 【问题描述】:

.NET 托管代码支持的唯一键盘挂钩是低级键盘挂钩 (WH_KEYBOARD_LL)。

见Using global keyboard hook (WH_KEYBOARD_LL) in WPF / C#

目前,我的应用程序中有上述代码,因此当您刷卡时,您将获得所有击键的列表。问题在于键入分隔符,例如“%”和“;”它会向我发送 Alt+Numpad+?这些符号对应的 WPF Key 对象。

我的问题:有没有办法让这个行为更高级,即捕获从所有键盘命令生成的字符串?

干杯!

【问题讨论】:

【参考方案1】:

不知道发生了什么,但是从键盘钩子中获取像 % 这样的字符是非常重要的。该挂钩仅通知您虚拟键。但是 % 是一个打字键,通过在我的键盘上按 Shift + 5 产生(美国布局)。 Windows 通常通过处理 WM_KEYDOWN/UP 消息来生成这些字符,为键入键生成 WM_CHAR 消息。在你的情况下没有发生这种情况。执行此操作的低级 Windows 函数是 ToUnicodeEx()。

【讨论】:

感谢您的帮助 nobugz,我会看看 ToUnicodeEx()。发现了一个关于如何实现这个的问题***.com/questions/370754/…【参考方案2】:

我猜如果您正在刷卡,wpf 表单上的某处有输入,例如文本框?然后我会倾向于添加一个事件,也许是一个 KeyUp 事件处理程序,(键盘楔形卡扫描仪确实会发送一个处理结束信号,例如 ENTER 以指示刷卡成功是吗?),在 KeyUp 事件处理程序中,使用 StringBuilder 构建一个字符串,当捕获到 ENTER 等处理结束信号时,您可以删除“%”和“;”来自 StringBuilder 实例并做任何你必须做的事情。

使用状态系统可能更容易,当 KeyUp 事件处理程序收到“%”时,然后进入另一个状态,最终预期状态将是“;”

静态布尔 StartState = false; StringBuilder sbInput = new StringBuilder(); 私人无效文本框1_KeyUp(对象发送者,KeyEventArgs e) 如果(!StartState) if (e.KeyCode == Keys.D5) StartState = true; sbInput.Append((char)e.KeyValue); 别的 if (e.KeyCode == Keys.OemSemicolon) 开始状态 = 假; // sbInput 将包含来自扫描仪的数据, // 将其复制到其他地方并重置 sbInput // sbInput.Remove(0, sbInput.Length); sbInput.Append((char)e.KeyValue); e.Handled = true;

希望这会有所帮助, 最好的祝福, 汤姆。

【讨论】:

我的表单上没有输入。为了防止文本框或应用程序失去焦点的问题,我使用了一个键盘钩子,它应该对用户不可见地执行此任务。 @reckoner: 嗯……刷到的数据去了哪里?当然,您的表格上有类似“请刷卡”之类的东西,是吗? “防止文本框或应用程序失去焦点的问题”是什么意思?您是否使用第三方程序(可能与扫描仪一起提供)来读取刷过的数据? 该界面将是一个触摸屏,用户可以在 WPF 的所有酷炫中浏览信息页面。被刷过的数据被截获并存储在数据库中,并会显示一个不显眼的通知。这是为了参加活动。

以上是关于C# WinForm键盘钩子的主要内容,如果未能解决你的问题,请参考以下文章

C#如何全局禁用键盘的回车键

用于 C# 和 WPF 的高级全局键盘钩子,用于读取键盘楔形卡扫描仪

C#全局键盘钩子,从控制台应用程序打开一个表单[重复]

键盘钩子怎么 使用

delphi键盘钩子没效果

c++实现键盘记录仪(键盘钩子)