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

ASP.NET
如何在ASP.NET中使用SmtpMail发送邮件
在VB.NET中利用Split和Replace函数计算字数
Attribute应用:简化ANF自定义控件初始化过程
ASP.NET 2.0移动开发入门之使用样式
ASP.NET 2.0中使用OWC生成图表
ASP.NET 2.0中控件的简单异步回调
一个无法捕获ADO.NET Dataset的内存错误
深入解读ADO.NET2.0的十大最新特性
.Net平台下的分布式缓存设计
ASP.NET全局异常处理浅析
ASP.NET 2.0中文验证码的实现
浅析.NET平台编程语言的未来走向
.net 框架程序设计收藏
使用ASP.NET MVC Futures 中的异步Action
详解.NET中的XmlReader与XmlWriter
关于.NET中的Server push技术
asp.net页面执行机制
对比JSP和ASP.NET的存储过程
.NET 4.0不会包含System.Shell.CommandLine
ASP.NET十个有效性能优化的方法

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


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