C#使用钩子获得按键信息的方法
本文实例讲述了C#使用钩子获得按键信息的方法。分享给大家供大家参考。具体如下:
窗体相关代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Data;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
usingSystem.Runtime.InteropServices;
usingSystem.Threading;
usingReadBadCode;
namespacegouzi
{
publicpartialclassForm2:Form
{
BarCodeHookBarCode=newBarCodeHook();
publicForm2()
{
InitializeComponent();
BarCode.BarCodeEvent+=newBarCodeHook.BarCodeDelegate(BarCode_BarCodeEvent);
}
privatedelegatevoidShowInfoDelegate(BarCodeHook.BarCodesbarCode);
privatevoidShowInfo(BarCodeHook.BarCodesbarCode)
{
if(this.InvokeRequired)
{
this.BeginInvoke(newShowInfoDelegate(ShowInfo),newobject[]{barCode});
}
else
{
textBox1.Text=barCode.KeyName;//键名
textBox2.Text=barCode.VirtKey.ToString();//虚拟码
textBox3.Text=barCode.ScanCode.ToString();//扫描码
textBox4.Text=barCode.AscII.ToString();//AscII
textBox5.Text=barCode.Chr.ToString();//字符
textBox6.Text=barCode.IsValid?barCode.BarCode:"";
//在这里进行键入值
}
}
voidBarCode_BarCodeEvent(BarCodeHook.BarCodesbarCode)
{
ShowInfo(barCode);
}
privatevoidForm2_Load(objectsender,EventArgse)
{
BarCode.Start();
}
privatevoidForm2_StyleChanged(objectsender,EventArgse)
{
BarCode.Stop();
}
}
}
后台类代码:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Runtime.InteropServices;
usingSystem.Reflection;
namespaceReadBadCode
{
classBarCodeHook
{
publicdelegatevoidBarCodeDelegate(BarCodesbarCode);
publiceventBarCodeDelegateBarCodeEvent;
publicstructBarCodes
{
publicintVirtKey;//虚拟码
publicintScanCode;//扫描码
publicstringKeyName;//键名
publicuintAscII;//AscII
publiccharChr;//字符
publicstringBarCode;//条码信息
publicboolIsValid;//条码是否有效
publicDateTimeTime;//扫描时间
}
privatestructEventMsg
{
publicintmessage;
publicintparamL;
publicintparamH;
publicintTime;
publicinthwnd;
}
//安装钩子
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
privatestaticexternintSetWindowsHookEx(intidHook,HookProclpfn,IntPtrhInstance,intthreadId);
//卸载钩子
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
privatestaticexternboolUnhookWindowsHookEx(intidHook);
//继续下一个钩子
[DllImport("user32.dll",CharSet=CharSet.Auto,CallingConvention=CallingConvention.StdCall)]
privatestaticexternintCallNextHookEx(intidHook,intnCode,Int32wParam,IntPtrlParam);
//获取键名的字符串
[DllImport("user32",EntryPoint="GetKeyNameText")]
privatestaticexternintGetKeyNameText(intlParam,StringBuilderlpBuffer,intnSize);
//将256个虚拟键复制到指定的缓冲区中
[DllImport("user32",EntryPoint="GetKeyboardState")]
privatestaticexternintGetKeyboardState(byte[]pbKeyState);
//将指定的虚拟键码和键盘状态为相应的字符串
[DllImport("user32",EntryPoint="ToAscii")]
privatestaticexternboolToAscii(intVirtualKey,intScanCode,byte[]lpKeyState,refuintlpChar,intuFlags);
//声明定义回调函数
delegateintHookProc(intnCode,Int32wParam,IntPtrlParam);
BarCodesbarCode=newBarCodes();
inthKeyboardHook=0;
stringstrBarCode="";
privateintKeyboardHookProc(intnCode,Int32wParam,IntPtrlParam)
{
if(nCode==0)
{
EventMsgmsg=(EventMsg)Marshal.PtrToStructure(lParam,typeof(EventMsg));
if(wParam==0x100)//WM_KEYDOWN=0x100
{
barCode.VirtKey=msg.message&0xff;//虚拟码
barCode.ScanCode=msg.paramL&0xff;//扫描码
StringBuilderstrKeyName=newStringBuilder(255);
if(GetKeyNameText(barCode.ScanCode*65536,strKeyName,255)>0)
{
barCode.KeyName=strKeyName.ToString().Trim(newchar[]{'','\0'});
}
else
{
barCode.KeyName="";
}
byte[]kbArray=newbyte[256];
uintuKey=0;
GetKeyboardState(kbArray);
if(ToAscii(barCode.VirtKey,barCode.ScanCode,kbArray,refuKey,0))
{
barCode.AscII=uKey;
barCode.Chr=Convert.ToChar(uKey);
}
if(DateTime.Now.Subtract(barCode.Time).TotalMilliseconds>50)
{
strBarCode=barCode.Chr.ToString();
}
else
{
if((msg.message&0xff)==13&&strBarCode.Length>3)
//回车
{
barCode.BarCode=strBarCode;
barCode.IsValid=true;
}
strBarCode+=barCode.Chr.ToString();
}
barCode.Time=DateTime.Now;
if(BarCodeEvent!=null)BarCodeEvent(barCode);
//触发事件
barCode.IsValid=false;
}
}
returnCallNextHookEx(hKeyboardHook,nCode,wParam,lParam);
}
//安装钩子
publicboolStart()
{
if(hKeyboardHook==0)
{
//WH_KEYBOARD_LL=13
hKeyboardHook=SetWindowsHookEx(13,newHookProc(KeyboardHookProc),Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
}
return(hKeyboardHook!=0);
}
//卸载钩子
publicboolStop()
{
if(hKeyboardHook!=0)
{
returnUnhookWindowsHookEx(hKeyboardHook);
}
returntrue;
}
}
}
【注意】要想测试实际的效果,必须执行编译后的Exe文件,在开发环境直接运行会没有效果的。
希望本文所述对大家的C#程序设计有所帮助。