软件实现监听键盘事件.docx
《软件实现监听键盘事件.docx》由会员分享,可在线阅读,更多相关《软件实现监听键盘事件.docx(7页珍藏版)》请在冰豆网上搜索。
软件实现监听键盘事件
软件实现监听键盘事件
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
usingSystem.Runtime.InteropServices;
usingSystem.Windows.Forms;
usingSystem.Reflection;
classKeyboardHook
{
publiceventKeyEventHandlerKeyDownEvent;
publiceventKeyPressEventHandlerKeyPressEvent;
publiceventKeyEventHandlerKeyUpEvent;
publicdelegateintHookProc(intnCode,Int32wParam,IntPtrlParam);
staticinthKeyboardHook=0;//声明键盘钩子处理的初始值
//值在MicrosoftSDK的Winuser.h里查询
publicconstintWH_KEYBOARD_LL=13;//线程键盘钩子监听鼠标消息设为2,全局键盘监听鼠标消息设为13
HookProcKeyboardHookProcedure;//声明KeyboardHookProcedure作为HookProc类型
//键盘结构
[StructLayout(LayoutKind.Sequential)]
publicclassKeyboardHookStruct
{
publicintvkCode;//定一个虚拟键码。
该代码必须有一个价值的范围1至254
publicintscanCode;//指定的硬件扫描码的关键
publicintflags;//键标志
publicinttime;//指定的时间戳记的这个讯息
publicintdwExtraInfo;//指定额外信息相关的信息
}
//使用此功能,安装了一个钩子
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
publicstaticexternintSetWindowsHookEx(intidHook,HookProclpfn,IntPtrhInstance,intthreadId);
//调用此函数卸载钩子
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
publicstaticexternboolUnhookWindowsHookEx(intidHook);
//使用此功能,通过信息钩子继续下一个钩子
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
publicstaticexternintCallNextHookEx(intidHook,intnCode,Int32wParam,IntPtrlParam);
//取得当前线程编号(线程钩子需要用到)
[DllImport("kernel32.dll")]
staticexternintGetCurrentThreadId();
//使用WINDOWSAPI函数代替获取当前实例的函数,防止钩子失效
[DllImport("kernel32.dll")]
publicstaticexternIntPtrGetModuleHandle(stringname);
publicvoidStart()
{
//安装键盘钩子
if(hKeyboardHook==0)
{
KeyboardHookProcedure=newHookProc(KeyboardHookProc);
hKeyboardHook=SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardHookProcedure,GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName),0);
//hKeyboardHook=SetWindowsHookEx(WH_KEYBOARD_LL,KeyboardHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
//************************************
//键盘线程钩子
SetWindowsHookEx(13,KeyboardHookProcedure,IntPtr.Zero,GetCurrentThreadId());//指定要监听的线程idGetCurrentThreadId(),
//键盘全局钩子,需要引用空间(usingSystem.Reflection;)
//SetWindowsHookEx(13,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
//
//关于SetWindowsHookEx(intidHook,HookProclpfn,IntPtrhInstance,intthreadId)函数将钩子加入到钩子链表中,说明一下四个参数:
//idHook钩子类型,即确定钩子监听何种消息,上面的代码中设为2,即监听键盘消息并且是线程钩子,如果是全局钩子监听键盘消息应设为13,
//线程钩子监听鼠标消息设为7,全局钩子监听鼠标消息设为14。
lpfn钩子子程的地址指针。
如果dwThreadId参数为0或是一个由别的进程创建的
//线程的标识,lpfn必须指向DLL中的钩子子程。
除此以外,lpfn可以指向当前进程的一段钩子子程代码。
钩子函数的入口地址,当钩子钩到任何
//消息后便调用这个函数。
hInstance应用程序实例的句柄。
标识包含lpfn所指的子程的DLL。
如果threadId标识当前进程创建的一个线程,而且子
//程代码位于当前进程,hInstance必须为NULL。
可以很简单的设定其为本应用程序的实例句柄。
threaded与安装的钩子子程相关联的线程的标识符
//如果为0,钩子子程与所有的线程关联,即为全局钩子
//************************************
//如果SetWindowsHookEx失败
if(hKeyboardHook==0)
{
Stop();
thrownewException("安装键盘钩子失败");
}
}
}
publicvoidStop()
{
boolretKeyboard=true;
if(hKeyboardHook!
=0)
{
retKeyboard=UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook=0;
}
if(!
(retKeyboard))thrownewException("卸载钩子失败!
");
}
//ToAscii职能的转换指定的虚拟键码和键盘状态的相应字符或字符
[DllImport("user32")]
publicstaticexternintToAscii(intuVirtKey,//[in]指定虚拟关键代码进行翻译。
intuScanCode,//[in]指定的硬件扫描码的关键须翻译成英文。
高阶位的这个值设定的关键,如果是(不压)
byte[]lpbKeyState,//[in]指针,以256字节数组,包含当前键盘的状态。
每个元素(字节)的数组包含状态的一个关键。
如果高阶位的字节是一套,关键是下跌(按下)。
在低比特,如果设置表明,关键是对切换。
在此功能,只有肘位的CAPSLOCK键是相关的。
在切换状态的NUM个锁和滚动锁定键被忽略。
byte[]lpwTransKey,//[out]指针的缓冲区收到翻译字符或字符。
intfuState);//[in]Specifieswhetheramenuisactive.Thisparametermustbe1ifamenuisactive,or0otherwise.
//获取按键的状态
[DllImport("user32")]
publicstaticexternintGetKeyboardState(byte[]pbKeyState);
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
privatestaticexternshortGetKeyState(intvKey);
privateconstintWM_KEYDOWN=0x100;//KEYDOWN
privateconstintWM_KEYUP=0x101;//KEYUP
privateconstintWM_SYSKEYDOWN=0x104;//SYSKEYDOWN
privateconstintWM_SYSKEYUP=0x105;//SYSKEYUP
privateintKeyboardHookProc(intnCode,Int32wParam,IntPtrlParam)
{
//侦听键盘事件
if((nCode>=0)&&(KeyDownEvent!
=null||KeyUpEvent!
=null||KeyPressEvent!
=null))
{
KeyboardHookStructMyKeyboardHookStruct=(KeyboardHookStruct)Marshal.PtrToStructure(lParam,typeof(KeyboardHookStruct));
//raiseKeyDown
if(KeyDownEvent!
=null&&(wParam==WM_KEYDOWN||wParam==WM_SYSKEYDOWN))
{
KeyskeyData=(Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgse=newKeyEventArgs(keyData);
KeyDownEvent(this,e);
}
//键盘按下
if(KeyPressEvent!
=null&&wParam==WM_KEYDOWN)
{
byte[]keyState=newbyte[256];
GetKeyboardState(keyState);
byte[]inBuffer=newbyte[2];
if(ToAscii(MyKeyboardHookStruct.vkCode,MyKeyboardHookStruct.scanCode,keyState,inBuffer,MyKeyboardHookStruct.flags)==1)
{
KeyPressEventArgse=newKeyPressEventArgs((char)inBuffer[0]);
KeyPressEvent(this,e);
}
}
//键盘抬起
if(KeyUpEvent!
=null&&(wParam==WM_KEYUP||wParam==WM_SYSKEYUP))
{
KeyskeyData=(Keys)MyKeyboardHookStruct.vkCode;
KeyEventArgse=newKeyEventArgs(keyData);
KeyUpEvent(this,e);
}
}
//如果返回1,则结束消息,这个消息到此为止,不再传递。
//如果返回0或调用CallNextHookEx函数则消息出了这个钩子继续往下传递,也就是传给消息真正的接受者
returnCallNextHookEx(hKeyboardHook,nCode,wParam,lParam);
}
~KeyboardHook()
{
Stop();
}
}
1
2.调用方法
2.1启动监听
首先定义按键钩子及工具类
privateKeyEventHandlermyKeyEventHandeler=null;//按键钩子
privateKeyboardHookk_hook=newKeyboardHook();
1
2
其次,定义监听后需要实现的方法
privatevoidhook_KeyDown(objectsender,KeyEventArgse)
{
//这里写具体实现
writeLog("按下按键"+e.KeyValue);
}
1
最后开启监听
publicvoidstartListen()
{
myKeyEventHandeler=newKeyEventHandler(hook_KeyDown);
k_hook.KeyDownEvent+=myKeyEventHandeler;//钩住键按下
k_hook.Start();//安装键盘钩子
}
1
2.2关闭监听
publicvoidstopListen()
{
if(myKeyEventHandeler!
=null)
{
k_hook.KeyDownEvent-=myKeyEventHandeler;//取消按键事件
myKeyEventHandeler=null;
k_hook.Stop();//关闭键盘钩子
}
}