条码扫描器接口编程 – wanglang3081的专栏 – CSDN博客

电子专业 徐 自远 468℃

条码扫描器接口编程

目前的条形码扫描器有点类似外接键盘(其实从消息传送上它就相当于一个键盘),把输入焦点定位到可输入的控件上,一扫描相应的条形码信息就输入到文本框中去了,但是如果没有输入焦点,或另一个不相干的程序获得输入焦点,那就有点乱套了。我想实现的是,不管什么情况,只要扫描器一工作,我的程序就能自动激活,并能获得当前输入的条形码信息。实现思路:我用的USB口的条形码扫描器,仔细分析了一下,扫描成功后,以键盘按键消息的形式把条形码输入信息通知给系统。这样通过键盘钩子就可以方便的获得该信息了。但是,怎样区分信息是键盘还是条形码输入的哪?很简单,条形码扫描器在很短的时间内输入了至少3个字符以上信息,并且以“回车”作为结束字符,在这种思想指引下,很完美的实现了预定功能。 

窗体相关代码:

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
using System;  
usingSystem.Collections.Generic;  
usingSystem.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
usingSystem.Windows.Forms;  

namespace ReadBadCode  
 
   publicpartial class frmTest :Form  
   
      BarCodeHook BarCode = newBarCodeHook();  
      public frmTest()  
       
          InitializeComponent();  
          BarCode.BarCodeEvent += newBarCodeHook.BarCodeDelegate(BarCode_BarCodeEvent);  
       

      private delegate void ShowInfoDelegate(BarCodeHook.BarCodesbarCode);  
      private void ShowInfo(BarCodeHook.BarCodesbarCode)  
       
          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();  
              textBox5.Text =barCode.Chr.ToString();  
              textBox6.Text = barCode.IsValid ? barCode.BarCode :””;  
           
       

      void BarCode_BarCodeEvent(BarCodeHook.BarCodesbarCode)  
       
          ShowInfo(barCode);  
       

      private void frmTest_Load(object sender, EventArgse)  
       
          BarCode.Start();  
       

      private void frmTest_FormClosed(object sender, FormClosedEventArgse)  
       
          BarCode.Stop();  
       

      private void textBox6_TextChanged(object sender, EventArgse)  
       
          if (textBox6.Text.Length >0)  
           
              MessageBox.Show(textBox6.Text);  
           
       
   
 

 
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace ReadBadCode
{
   publicpartial class frmTest : Form
   {
      BarCodeHook BarCode = new BarCodeHook();
      public frmTest()
      {
          InitializeComponent();
          BarCode.BarCodeEvent += newBarCodeHook.BarCodeDelegate(BarCode_BarCodeEvent);
      }

      private delegate void ShowInfoDelegate(BarCodeHook.BarCodesbarCode);
      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();
              textBox5.Text = barCode.Chr.ToString();
              textBox6.Text = barCode.IsValid ? barCode.BarCode : “”;
          }
      }

      void BarCode_BarCodeEvent(BarCodeHook.BarCodes barCode)
      {
          ShowInfo(barCode);
      }

      private void frmTest_Load(object sender, EventArgs e)
      {
          BarCode.Start();
      }

      private void frmTest_FormClosed(object sender, FormClosedEventArgse)
      {
          BarCode.Stop();
      }

      private void textBox6_TextChanged(object sender, EventArgs e)
      {
          if (textBox6.Text.Length > 0)
          {
              MessageBox.Show(textBox6.Text);
          }
      }
   }
}

BarCodeHook 类:

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
using System;  
usingSystem.Collections.Generic;  
using System.Text;  
usingSystem.Runtime.InteropServices;  
using System.Reflection;  

namespace ReadBadCode  
 
   public classBarCodeHook  
   
      public delegate void BarCodeDelegate(BarCodesbarCode);  
      public event BarCodeDelegateBarCodeEvent;  

      public struct BarCodes  
       
          public intVirtKey;     //虚拟码  
          public intScanCode;    //扫描码  
          public string KeyName;  //键名  
          public uintAscII;      //AscII  
          public charChr;        //字符  

          public string BarCode;  //条码信息  
          public boolIsValid;    //条码是否有效  
          public DateTimeTime;   //扫描时间  
       

      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, HookProclpfn, IntPtr hInstance, intthreadId);  

      [DllImport(“user32.dll”, CharSet = CharSet.Auto, CallingConvention=CallingConvention.StdCall)]  
      private static extern bool UnhookWindowsHookEx(intidHook);  

      [DllImport(“user32.dll”, CharSet = CharSet.Auto, CallingConvention=CallingConvention.StdCall)]  
      private static extern int CallNextHookEx(int idHook, int nCode,Int32 wParam, IntPtrlParam);  

      [DllImport(“user32″, EntryPoint =”GetKeyNameText”)]  
      private static extern int GetKeyNameText(int lParam, StringBuilderlpBuffer, int nSize);  

      [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, intuFlags);  

      delegate int HookProc(int nCode, Int32 wParam, IntPtrlParam);  
      BarCodes barCode = newBarCodes();  
      int hKeyboardHook = 0;  
      string strBarCode = “”;  

      private int KeyboardHookProc(int nCode, Int32 wParam, IntPtrlParam)  
       
          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 = newStringBuilder(255);  
                  if (GetKeyNameText(barCode.ScanCode * 65536, strKeyName, 255)> 0)  
                   
                      barCode.KeyName = strKeyName.ToString().Trim(new char[] { ‘ ‘, ‘\0’});  
                   
                  else 
                   
                      barCode.KeyName = “”;  
                   

                  byte[] kbArray = newbyte[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, newHookProc(KeyboardHookProc),Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);  
           
          return (hKeyboardHook !=0);  
       

      // 卸载钩子   
      public bool Stop()  
       
          if (hKeyboardHook != 0)  
           
              returnUnhookWindowsHookEx(hKeyboardHook);  
           
          return true;  
       
   

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;

namespace ReadBadCode
{
   public classBarCodeHook
   {
      public delegate void BarCodeDelegate(BarCodes barCode);
      public event BarCodeDelegate BarCodeEvent;

      public struct BarCodes
      {
          public intVirtKey;     //虚拟码
          public intScanCode;    //扫描码
          public string KeyName;  //键名
          public uintAscII;      //AscII
          public charChr;        //字符

          public string BarCode;  //条码信息
          public boolIsValid;    //条码是否有效
          public DateTimeTime;   //扫描时间
      }

      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, HookProclpfn, 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, StringBuilderlpBuffer, int nSize);

      [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, IntPtrlParam);
      BarCodes barCode = new BarCodes();
      int hKeyboardHook = 0;
      string strBarCode = “”;

      private int KeyboardHookProc(int nCode, Int32 wParam, IntPtrlParam)
      {
          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, newHookProc(KeyboardHookProc),Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);
          }
          return (hKeyboardHook != 0);
      }

      // 卸载钩子
      public bool Stop()
      {
          if (hKeyboardHook != 0)
          {
              return UnhookWindowsHookEx(hKeyboardHook);
          }
          return true;
      }
   }
}

转载请注明:徐自远的乱七八糟小站 » 条码扫描器接口编程 – wanglang3081的专栏 – CSDN博客

喜欢 (0)

苏ICP备18041234号-1 bei_an 苏公网安备 32021402001397号