3年前写了一篇《USB口的红外条形码扫描器的另类使用》,不过相关代码是VB编写,在这几年之间,有许多网友提出需要C#版的,起初还以为由VB修改C#应该很容易,最近研究了一下,发现C#和VB调用API的机制还是有所不同的,在迁移的过程中还是会遇到不少问题,所以我专门抽时间做了一个基于C#的程序。

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

VB相关的代码请见:http://yfsoft.blog.51cto.com/1635641/323475

--------------------------------------------------------------------------------

窗体相关代码:

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150
 using System;  
using System.Collections.Generic;  
using System.ComponentModel;  
using System.Data;  
using System.Drawing;  
using System.Text;  
using System.Windows.Forms;  
 
namespace ReadBadCode  
{  
    public partial class frmTest : Form  
    {  
        BarCodeHook BarCode = new BarCodeHook();  
        public frmTest()  
        {  
            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();  
                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, FormClosedEventArgs e)  
        {  
            BarCode.Stop();  
        }  
 
        private void textBox6_TextChanged(object sender, EventArgs e)  
        {  
            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
{
    public partial class frmTest : Form
    {
        BarCodeHook BarCode = new BarCodeHook();
        public frmTest()
        {
            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();
                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, FormClosedEventArgs e)
        {
            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;  
using System.Collections.Generic;  
using System.Text;  
using System.Runtime.InteropServices;  
using System.Reflection;  
 
namespace ReadBadCode  
{  
    public 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);  
 
        [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;  
        }  
    }  

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

namespace ReadBadCode
{
    public 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);

[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;
        }
    }
}

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

转载于:https://blog.51cto.com/yfsoft/323420

红外条码扫描器的另类使用C#版相关推荐

  1. 【红外学习 4】【最终版】STC15f104W 红外led发射,导线交互 2种方式 测试成功

    1,红外LED发射NEC编码.C 2,导线直连,发送NEC编码,与机顶盒交互.C 3,[最终版]用导线的方式实现红外控制功能.C /* 1,红外LED发射NEC编码.C 单片机:STC15f104W ...

  2. Arduino红外控制LED灯开关

    Arduino红外光电反射传感器模块 本章主要实现:通过红外模块控制LED的亮和灭.当遮挡住红外时,LED点亮:不遮挡住红外时,LED熄灭. 1.需要设备: 1.LED灯一个: 2.一个欧姆电阻: 3 ...

  3. STM32红外寻迹小车

    STM32红外寻迹小车(寄存器版) 最近学习了STM32,想通过制作一辆小车来加深对STM32的理解,在平时学习时经常用正点原子提供的源代码稍加该装就行,但是正点原子没有提供关于红外寻迹模板的相关程序 ...

  4. 小爱智能音箱红外控制继电器

    小爱智能音箱红外控制继电器 一.实物图 二.物料准备 1.小爱智能音箱万能遥控版(活动价¥99) 2.红外遥控继电器. 关于红外遥控继电器以下提供二种解决方案: 2.1简单省事版 买现成的红外遥控插排 ...

  5. CSCD(2015-2016年)来源期刊目录中国科学引文数据库

    经过中国科学引文数据库(Chinese Science Citation Database,简称CSCD)定量遴选.专家定性评估, 2015-2016年度中国科学引文数据库收录来源期刊1200种,其中 ...

  6. 江苏魔百盒M301H_Hi3798MV300-300H-310芯片通刷-免费卡刷固件包

    江苏魔百-盒M301H_Hi3798MV300-300H-310芯片通-刷-免费卡刷固件包 本固件针对江苏版魔百盒M301H-Hi3798MV300和Hi3798MV300H芯片-华为万物互联世界lo ...

  7. 基于STM32F407ZGT6芯片,实现小车功能

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 基于STM32F407ZGT6芯片,实现小车前进后退,左转右转,ADC调速,红外以及蓝牙,寻迹,避障,屏幕显示功能 开源代码,共同提高 ...

  8. 树莓派云音乐c语言,基于树莓派的红外遥控版网易云音乐播放器

    基于树莓派的红外遥控版网易云音乐播放器.下面是遥控键盘示意图: CH- CH CH+ << >> || - + EQ 0 100+ 200+ 1 2 3 4 5 6 7 8 9 ...

  9. linux树莓派网易云音乐,基于树莓派的红外遥控版网易云音乐播放器

    基于树莓派的红外遥控版网易云音乐播放器.下面是遥控键盘示意图: CH- CH CH+ << >> || - + EQ 0 100+ 200+ 1 2 3 4 5 6 7 8 9 ...

  10. USB口的红外条形码扫描器的另类使用

    目前的条形码扫描器有点类似外接键盘(其实从消息传送上它就相当于一个键盘),把输入焦点定位到可输入的控件上,一扫描相应的条形码信息就输入到文本框中去了,但是如果没有输入焦点,或另一个不相干的程序获得输入 ...

最新文章

  1. 腾讯AI Lab两大算法刷新人脸识别与检测纪录,秉承「基础研究+落地应用」之路
  2. 2015 Multi-University Training Contest 1 - 1002 Assignment
  3. SharePoint 2013 图文开发系列之WebPart
  4. 详解Java反射机制
  5. 【测试点2超时问题】1046 Shortest Distance (20 分)_21行代码AC
  6. 使用Ext.grid.Panel显示远程数据
  7. JAVA分代收集机制详解
  8. 【转】Wireshark网络抓包(三)——网络协议
  9. IntelliJ IDEA 2020 快捷键私人订制
  10. 【OJ】洛谷分支结构题单题解锦集
  11. Windbg分析dump及调试程序
  12. [R语言统计]频数表
  13. Linux epoll模型详解及源码分析
  14. 如何用Python给图片添加文字/图片水印的方法,特别简单好用,filestools和Pil模块
  15. js 去掉字符串的空格回车换行
  16. 如何解决不能绘制网络模型,报错protobuf
  17. ABAP SY-系统值
  18. 折线图 和如何在图上写字
  19. Android gif 录屏
  20. 简单到令人发指的插画制作方法

热门文章

  1. 安装ps2021后,解决adobe一直发送消息的办法
  2. blob类型对象转为file类型对象
  3. 如何在Mac禁用NTFS for Mac 15
  4. [Swift][leetcode] 433. 最小基因变化
  5. PHP 抽象工厂模式(Kit模式)
  6. python 守护进程(daemon)on : 会打扮的装饰器
  7. 在域控制器上安装Exchange 2003的注意事项
  8. 常去的国外网站一览表
  9. jquery04-animate
  10. 单/多文档的窗体类属性修改(VC_MFC)