C#使用钩子获得按键信息的方法
程序员文章站
2022-07-01 17:02:49
本文实例讲述了c#使用钩子获得按键信息的方法。分享给大家供大家参考。具体如下:
窗体相关代码:
using system;
using system.coll...
本文实例讲述了c#使用钩子获得按键信息的方法。分享给大家供大家参考。具体如下:
窗体相关代码:
using system; using system.collections.generic; using system.componentmodel; using system.data; using system.drawing; using system.linq; using system.text; using system.windows.forms; using system.runtime.interopservices; using system.threading; using readbadcode; namespace gouzi { public partial class form2 : form { barcodehook barcode = new barcodehook(); public form2() { initializecomponent(); barcode.barcodeevent += new barcodehook.barcodedelegate(barcode_barcodeevent); } private delegate void showinfodelegate(barcodehook.barcodes barcode); private void showinfo(barcodehook.barcodes barcode) { if (this.invokerequired) { this.begininvoke(new showinfodelegate(showinfo), new object[] { 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 : ""; //在这里进行键入值 } } void barcode_barcodeevent(barcodehook.barcodes barcode) { showinfo(barcode); } private void form2_load(object sender, eventargs e) { barcode.start(); } private void form2_stylechanged(object sender, eventargs e) { barcode.stop(); } } }
后台类代码:
using system; using system.collections.generic; using system.linq; using system.text; using system.runtime.interopservices; using system.reflection; namespace readbadcode { class barcodehook { public delegate void barcodedelegate(barcodes barcode); public event barcodedelegate barcodeevent; public struct barcodes { public int virtkey; //虚拟码 public int scancode; //扫描码 public string keyname; //键名 public uint ascii; //ascii public char chr; //字符 public string barcode; //条码信息 public bool isvalid; //条码是否有效 public datetime time; //扫描时间 } private struct eventmsg { public int message; public int paraml; public int paramh; public int time; public int hwnd; } // 安装钩子 [dllimport("user32.dll", charset = charset.auto, callingconvention = callingconvention.stdcall)] private static extern int setwindowshookex(int idhook, hookproc lpfn, intptr hinstance, int threadid); // 卸载钩子 [dllimport("user32.dll", charset = charset.auto, callingconvention = callingconvention.stdcall)] private static extern bool unhookwindowshookex(int idhook); // 继续下一个钩子 [dllimport("user32.dll", charset = charset.auto, callingconvention = callingconvention.stdcall)] private static extern int callnexthookex(int idhook, int ncode, int32 wparam, intptr lparam); //获取键名的字符串 [dllimport("user32", entrypoint = "getkeynametext")] private static extern int getkeynametext(int lparam, stringbuilder lpbuffer, int nsize); //将256个虚拟键复制到指定的缓冲区中 [dllimport("user32", entrypoint = "getkeyboardstate")] private static extern int getkeyboardstate(byte[] pbkeystate); //将指定的虚拟键码和键盘状态为相应的字符串 [dllimport("user32", entrypoint = "toascii")] private static extern bool toascii(int virtualkey, int scancode, byte[] lpkeystate, ref uint lpchar, int uflags); //声明定义回调函数 delegate int hookproc(int ncode, int32 wparam, intptr lparam); barcodes barcode = new barcodes(); int hkeyboardhook = 0; string strbarcode = ""; private int keyboardhookproc(int ncode, int32 wparam, intptr lparam) { if (ncode == 0) { eventmsg msg = (eventmsg)marshal.ptrtostructure(lparam, typeof(eventmsg)); if (wparam == 0x100) //wm_keydown = 0x100 { barcode.virtkey = msg.message & 0xff; //虚拟码 barcode.scancode = msg.paraml & 0xff; //扫描码 stringbuilder strkeyname = new stringbuilder(255); if (getkeynametext(barcode.scancode * 65536, strkeyname, 255) > 0) { barcode.keyname = strkeyname.tostring().trim(new char[] { ' ', '\0' }); } else { barcode.keyname = ""; } byte[] kbarray = new byte[256]; uint ukey = 0; getkeyboardstate(kbarray); if (toascii(barcode.virtkey, barcode.scancode, kbarray, ref ukey, 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; } } return callnexthookex(hkeyboardhook, ncode, wparam, lparam); } // 安装钩子 public bool start() { if (hkeyboardhook == 0) { //wh_keyboard_ll = 13 hkeyboardhook = setwindowshookex(13, new hookproc(keyboardhookproc), marshal.gethinstance(assembly.getexecutingassembly().getmodules()[0]), 0); } return (hkeyboardhook != 0); } // 卸载钩子 public bool stop() { if (hkeyboardhook != 0) { return unhookwindowshookex(hkeyboardhook); } return true; } } }
【注意】要想测试实际的效果,必须执行编译后的exe文件,在开发环境直接运行会没有效果的。
希望本文所述对大家的c#程序设计有所帮助。