当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > 利用底层键盘钩子拦载任意按键(回调版)

ASP.NET
赫赫大名的A*寻路算法(vb.net版本)
asp.net(c#)下Jmai去说明 使用与下载
[原创]完美解决Could not load file or assembly ''AjaxPro.2'' or one of its dependencies. 拒绝访问。
asp.net下gridview 批量删除的实现方法
用CSS实现图片倾斜 只支持IE
.net get set用法小结
vs 不显示行号的操作方法
ASP.NET页面进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)
ASP.Net不执行问题一解
asp.net 无限分类
让VS2008对JQuery语法的智能感知更完美一点
扩展方法ToJSON() and ParseJSON()
asp.net下PageMethods使用技巧
Linq to SQL Delete时遇到问题的解决方法
实现ASP.NET多文件上传程序代码
ASP.NET AJAX 1.0 RC开发10分钟图解
asp.net get set用法
ASP.NET下使用WScript.Shell执行命令
asp.net2.0实现邮件发送(测试成功)
Asp.net 无限级分类实例代码

ASP.NET 中的 利用底层键盘钩子拦载任意按键(回调版)


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 110 ::
收藏到网摘: n/a

前段时间我曾经写过一篇《利用底层键盘钩子屏蔽任意按键》,并放到了我的blog上。这篇文章的题目中把“屏蔽”改成了“拦截”,显然要比以前的版本强一些了。对于以前写的那个DLL,有一个不够理想的地方,就是仅仅能实现屏蔽。如果想在屏蔽之前加入一些“小动作”,就只能修改DLL,在LowLevelKeyboardProc函数中添加代码,实现新的功能。但这样显然不够灵活,这样的DLL也不具备一般性了。所以我自然而然地想到了回调,Windows中有很多需要回调函数的API,我们当然也可以写出这样的API,这样做的好处就是可以给DLL调用程序留下足够的接口。此时,DLL就像一个阀门,我们不关心的按键消息就把它放过去,只把我们关心的按键消息拦截下来,然后进一步处理,而这些处理的代码就写在DLL调用程序的回调函数中,这样做是最理想不过的了。 相对于前一个版本,修改后的DLL源代码如下: /********************************************************************//* 文件名: MaskKey.cpp *//* *//* 功能: 标准 DLL ---- 利用底层键盘钩子实现拦截键盘任意按键 *//* *//* 作者: 卢培培 (goodname008) 时间: 2005.1.18 *//* *//* BLOG: http://blog.csdn.net/goodname008 *//********************************************************************/ // 导出函数列表// StartMaskKey// StopMaskKey #define _WIN32_WINNT 0x0500 // 设置系统版本, 确保可以使用底层键盘钩子 #include "windows.h" // 回调函数指针typedef BOOL (CALLBACK* LPFNKEYBOARDPROC)(WPARAM, KBDLLHOOKSTRUCT*); // 全局变量LPDWORD g_lpdwVirtualKey = NULL; // Keycode 数组的指针int g_nLength = 0; // Keycode 数组的大小BOOL g_bDisableKeyboard = FALSE; // 是否屏蔽整个键盘HINSTANCE g_hInstance = NULL; // 模块实例句柄HHOOK g_hHook = NULL; // 钩子句柄LPFNKEYBOARDPROC g_lpfnKeyboardProc; // 键盘钩子回调函数指针 // DLL 入口函数BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved){ // 保存模块实例句柄 g_hInstance = (HINSTANCE)hModule; // 在进程结束或线程结束时卸载钩子 switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: break; case DLL_THREAD_ATTACH: break; case DLL_PROCESS_DETACH: case DLL_THREAD_DETACH: free(g_lpdwVirtualKey); if (g_hHook != NULL) UnhookWindowsHookEx(g_hHook); break; } return TRUE;} // 底层键盘钩子函数LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam){ // 拦截键盘的某些按键, 如果 g_bDisableKeyboard 为 TRUE 则拦截整个键盘按键if (nCode >= HC_ACTION) { KBDLLHOOKSTRUCT* pStruct = (KBDLLHOOKSTRUCT*)lParam; if (g_bDisableKeyboard) if (g_lpfnKeyboardProc(wParam, pStruct)) return CallNextHookEx(g_hHook, nCode, wParam, lParam); else return true; LPDWORD tmpVirtualKey = g_lpdwVirtualKey; for (int i = 0; i < g_nLength; i++) { if (pStruct->vkCode == *tmpVirtualKey++) if (g_lpfnKeyboardProc(wParam, pStruct)) return CallNextHookEx(g_hHook, nCode, wParam, lParam); else return true; } } // 调用系统中的下一个钩子 return CallNextHookEx(g_hHook, nCode, wParam, lParam);} /********************************************************************//* 开始拦截键盘按键 *//* *//* 参数: *//* lpdwVirtualKey Keycode 数组的指针 *//* nLength Keycode 数组的大小 *//* bDisableKeyboard 是否拦截整个键盘 *//* *//* 返回值: TRUE 成功, FALSE 失败 *//********************************************************************/BOOL WINAPI StartMaskKey(LPDWORD lpdwVirtualKey, int nLength, LPFNKEYBOARDPROC lpfnKeyboardProc, BOOL bDisableKeyboard = FALSE){ // 如果已经安装键盘钩子则返回 FALSE if (g_hHook != NULL || nLength == 0) return FALSE; // 将用户传来的 keycode 数组保存在全局变量中 g_lpdwVirtualKey = (LPDWORD)malloc(sizeof(DWORD) * nLength); LPDWORD tmpVirtualKey = g_lpdwVirtualKey; for (int i = 0; i < nLength; i++) { *tmpVirtualKey++ = *lpdwVirtualKey++; } g_nLength = nLength; g_bDisableKeyboard = bDisableKeyboard; g_lpfnKeyboardProc = lpfnKeyboardProc; // 安装底层键盘钩子 g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, g_hInstance, NULL); if (g_hHook == NULL) return FALSE; return TRUE; } /********************************************************************//* 停止拦截键盘按键 *//* *//* 参数: (无) *//* *//* 返回值: TRUE 成功, FALSE 失败 *//********************************************************************/BOOL WINAPI StopMaskKey(){ // 卸