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

ASP.NET
ASP.NET在上传文件时对文件类型的高级判断的代码
JQuery运用ajax注册用户实例(后台asp.net)
Asp.net与SQLserver一起打包部署安装图文教程
asp.net 上传下载输出二进制流实现代码
asp.net(C#)解析Json的类代码
asp.net 截取字符串代码
asp.net ubb使用代码
asp.net XML文件操作实现代码
asp.net利用HttpModule实现防sql注入
ASP.NET(C#)中操作SQLite数据库实例
asp.net(c#)ref,out ,params的区别
asp.net(C#)防sql注入组件的实现代码
asp.net FCKeditor自定义非空验证
Asp.net TreeView来构建用户选择输入的方法 推荐
asp.net(C#)函数对象参数传递的问题
Asp.net中的GridView导出遇到的两个问题和解决方法
asp.Net 中获取一周第一天,一月第一天等实现代码
asp.net MaxLengthValidator 最大长度验证控件代码
C# 通用文件上传类
asp.net 自定义控件实现无刷新上传图片,立即显示缩略图,保存图片缩略图

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-11-03   浏览: 40 ::
收藏到网摘: 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(){ // 卸