zoukankan      html  css  js  c++  java
  • C# 区分键盘和红外线扫描枪输入 模拟扫描枪

    2010年的时候做一个POS的项目用了红外线条码扫描枪,也有键盘输入条码。为了区分出来,查找了很多资料,学习了API,还有键盘钩子,模拟键盘输入。很让我崩溃的调试了两三天,不是钩子加载失败就是内存错误,还有莫名其妙的退出,最后总算可以了。最近看到这个功能,在网上查了查,又看到了叶帆的《红外条码扫描器的另类使用C#版》,他直接写了一个类,我的就是写在了窗体里。最后代码中,我把他的程序也加进来了,功能上还是有些不同,大家可以试一下。

    主要API如下:

    #region 声明钩子API
            //安装钩子原型  
            [DllImport("user32.dll", CharSet = CharSet.Auto)]
            public static extern IntPtr SetWindowsHookEx
                (
                    int hookid,
                    HookPro pfnhook,
                    IntPtr hinst,
                    int threadid
                );
    
            //卸载钩子原型  
            [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
            public static extern bool UnhookWindowsHookEx
                (
                   IntPtr hhook
                );
    
            //回调钩子原型  
            [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
            public static extern bool CallNextHookEx
                (
                    IntPtr hhook,
                    int code,
                    IntPtr wparam,
                    IntPtr lparam
                );
    
            //  
            [DllImport("Kernel32.dll", EntryPoint = "RtlMoveMemory")]
            public static extern void CopyMemory
                (
                    ref KBDLLHOOKSTRUCT Source,
                    IntPtr Destination, int Length
                );
    
    
            #endregion

    监控按键,ACSII码48到105,大小字母和数字就都包含了,主要方法如下:

    ArrayList alNum = new ArrayList();
    
            /// <summary>  
            /// 钩子回调  
            /// </summary>  
            /// <param name="nCode"></param>  
            /// <param name="wParam"></param>  
            /// <param name="lParam"></param>  
            /// <returns></returns>  
            public bool KEYBOARD_HOOKPRO(int nCode, IntPtr wParam, IntPtr lParam)
            {
                KBDLLHOOKSTRUCT kb = new KBDLLHOOKSTRUCT();
                CopyMemory(ref kb, lParam, 20);      //结果就在这里了             
                if ((int)wParam == 256)
                {
    
                    if (kb.vkCode >= 48 && kb.vkCode <= 105)
                    {
                        alNum.Add(Convert.ToChar(kb.vkCode));
                    }
    
                    if (kb.vkCode == 13 && alNum.Count > 6)
                    {
                        txtBarcode.Text = "";
    
                        string str = null;
                        foreach (char a in alNum)
                        {
                            str = str + a.ToString();
                        }
                        alNum = new ArrayList();
    
                        txtBarcode.Text = str;
                        listBox1.Items.Add(str);
                       
                        this.Show();
                        this.WindowState = FormWindowState.Normal;
                        this.Activate();
                    }
                    //else
                    //{
                    //    alNum.Clear();
                    //}
                }
                //UNLOAD_WINDOWS_KETBOARD_HOOK();
                //SET_WINDOWS_KEYBOARD_HOOK();
    
                // if(curkeypresscode!=null)curkeypresscode(kb.vkCode, (int)Control.ModifierKeys);//这个是我用来外置操作的,此处不用  
    
    
                return CallNextHookEx(hHook, nCode, wParam, lParam);
            }

    另外考虑到大家手中可能没有红外线条码扫描枪,我写了一个模拟程序,主要就是模拟按键:

    [DllImport("user32.dll")]
    public static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);

    发送的数字或字母要转换成ACSII码。

    public int Asc(string character)
            {
                if (character.Length == 1)
                {
                    System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
                    int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
                    return (intAsciiCode);
                }
                else
                {
                    throw new Exception("Character is not valid.");
                }
            }

    为了让大家看到效果使用了延时发送,打开记事本,然后启动“SendKeyDemo ” 项目, 点击发送,会延时2秒钟发送,如果你感觉2秒钟太长或太短,你自己看着改数字吧!然后再点击一下记事本程序,让它获得焦点,就可以看到记事本输入一串数字了。

    Send1_thumb6

    现在在“SendKeyDemo”启动的情况下,再到“PFJXC ”的Debug目录下启动接收程序,不在多项目启动,否则会提示 “加载钩子失败 ”,你就看不到效果了。

    Send2_thumb5

    你可以把PFJXC的程序最少化,然后发送条码或是用红外线条码枪扫描条码,窗体就会自动跳出来了。

    代码下载

  • 相关阅读:
    Dockerfile常用指令
    Maven相关命令
    CI-CD平台搭建过程整理
    边工作边刷题:70天一遍leetcode: day 28-1
    边工作边刷题:70天一遍leetcode: day 28
    边工作边刷题:70天一遍leetcode: day 29-1
    边工作边刷题:70天一遍leetcode: day 29
    边工作边刷题:70天一遍leetcode: day 30-1
    边工作边刷题:70天一遍leetcode: day 30
    边工作边刷题:70天一遍leetcode: day 31-4
  • 原文地址:https://www.cnblogs.com/wk986/p/2972296.html
Copyright © 2011-2022 走看看