1.扫描枪获取数据原理基本相当于键盘数据,获取扫描枪扫描出来的数据,一般分为两种实现方式。
a)文本框输入获取焦点,扫描后自动显示在文本框内。
b)使用键盘钩子,勾取扫描枪虚拟按键,根据按键频率进行手动输入和扫描枪扫描判断。
2.要实现系统钩子其实很简单,调用三个Win32的API即可。
SetWindowsHookEx 用于设置钩子。(设立一道卡子,盘查需要的信息)
CallNextHookEx 用于传递钩子(消息是重要的,所以从哪里来,就应该回到哪里去,除非你决定要封锁消息)
UnhookWindowsHookEx 卸载钩子(卸载很重要,卡子设多了会造成拥堵)
1 using System; 2 using System.Collections.Generic; 3 using System.Text; 4 using System.Runtime.InteropServices; 5 using System.Reflection; 6 using System.Diagnostics; 7 namespace SaomiaoTest2 8 { 9 /// <summary> 10 /// 获取键盘输入或者USB扫描枪数据 可以是没有焦点 应为使用的是全局钩子 11 /// USB扫描枪 是模拟键盘按下 12 /// 这里主要处理扫描枪的值,手动输入的值不太好处理 13 /// </summary> 14 public class BardCodeHooK 15 { 16 public delegate void BardCodeDeletegate(BarCodes barCode); 17 public event BardCodeDeletegate BarCodeEvent; 18 19 //定义成静态,这样不会抛出回收异常 20 private static HookProc hookproc; 21 22 23 public struct BarCodes 24 { 25 public int VirtKey;//虚拟吗 26 public int ScanCode;//扫描码 27 public string KeyName;//键名 28 public uint Ascll;//Ascll 29 public char Chr;//字符 30 31 public string BarCode;//条码信息 保存最终的条码 32 public bool IsValid;//条码是否有效 33 public DateTime Time;//扫描时间, 34 } 35 36 private struct EventMsg 37 { 38 public int message; 39 public int paramL; 40 public int paramH; 41 public int Time; 42 public int hwnd; 43 } 44 45 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 46 private static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId); 47 48 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 49 private static extern bool UnhookWindowsHookEx(int idHook); 50 51 [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] 52 private static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam); 53 54 [DllImport("user32", EntryPoint = "GetKeyNameText")] 55 private static extern int GetKeyNameText(int IParam, StringBuilder lpBuffer, int nSize); 56 57 [DllImport("user32", EntryPoint = "GetKeyboardState")] 58 private static extern int GetKeyboardState(byte[] pbKeyState); 59 60 [DllImport("user32", EntryPoint = "ToAscii")] 61 private static extern bool ToAscii(int VirtualKey, int ScanCode, byte[] lpKeySate, ref uint lpChar, int uFlags); 62 63 [DllImport("kernel32.dll")] 64 public static extern IntPtr GetModuleHandle(string name); 65 66 67 delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam); 68 BarCodes barCode = new BarCodes(); 69 int hKeyboardHook = 0; 70 string strBarCode = ""; 71 72 private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam) 73 { 74 if (nCode == 0) 75 { 76 EventMsg msg = (EventMsg)Marshal.PtrToStructure(lParam, typeof(EventMsg)); 77 if (wParam == 0x100)//WM_KEYDOWN=0x100 78 { 79 barCode.VirtKey = msg.message & 0xff;//虚拟吗 80 barCode.ScanCode = msg.paramL & 0xff;//扫描码 81 StringBuilder strKeyName = new StringBuilder(225); 82 if (GetKeyNameText(barCode.ScanCode * 65536, strKeyName, 255) > 0) 83 { 84 barCode.KeyName = strKeyName.ToString().Trim(new char[] { ' ', '