您的当前位置:首页正文

条码扫描器接口编程

2024-11-08 来源:个人技术集锦

目前的条形码扫描器有点类似外接键盘(其实从消息传送上它就相当于一个键盘),把输入焦点定位到可输入的控件上,一扫描相应的条形码信息就输入到文本框中去了,但是如果没有输入焦点,或另一个不相干的程序获得输入焦点,那就有点乱套了。我想实现的是,不管什么情况,只要扫描器一工作,我的程序就能自动激活,并能获得当前输入的条形码信息。实现思路:我用的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;
       }
    }
}

【注意】要想测试实际的效果,必须执行编译后的Exe文件,在开发环境直接运行会没有效果的。

推荐适合二次开发的仓库仓库扫描枪:

Top