USB扫码枪二维码读取(一)——U3D篇

USB扫码枪为即插即用,通过类似键盘的方式和系统进行交互,扫描出来的数据获取方式有两种实现方式。

(1)文本框输入获取焦点,扫描后自动显示在文本框内。

(2)使用键盘钩子,勾取扫描枪虚拟按键,进行键盘虚拟码和ASCII码的转换后获取数据。

在程序进行开发时,一般使用第二种方式,下面在U3D开发环境下,接收USB扫码枪扫描数据方面的问题进行探讨分享。

在程序开发中要实现系统钩子其实很简单,调用Win32的API即可。

(1)SetWindowsHookEx 用于设置钩子。(设立一道卡子,盘查需要的信息)

  

private static IntPtr SetHook(LowLevelKeyboardProc proc)
    {
        using (Process curProcess = Process.GetCurrentProcess())
        using (ProcessModule curModule = curProcess.MainModule)
        {
            return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
        }
    }

(2)CallNextHookEx 用于传递钩子(消息是重要的,所以从哪里来,就应该回到哪里去,除非你决定要封锁消息)

 private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

(3)UnhookWindowsHookEx 卸载钩子(卸载很重要,卡子设多了会造成拥堵)

void OnApplicationQuit()
    {
        UnhookWindowsHookEx(_hookID);
    }

最重要的环节有两个:

一是对接收到的一个个键盘数值的处理。

我的扫码枪设置后扫码的情况举例如下:

(1)在大写字母前发送shift的虚拟码160

(2)第二功能键发送shift加对应的虚拟码

(3)结束发送键盘码为13 40

如:160 187 对应的为键盘的+,ASCII码为43

160 65 对应的为键盘的A ,ASCII码为65

需要处理shift对应的大小写问题,以及第二功能键的特殊处理;

private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
    {
        bool isShift = false;

        if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
        {
            
            int vkCode = Marshal.ReadInt32(lParam);
         //   UnityEngine.Debug.Log("ASCII:" + vkCode);

            if (vkCode >= 65 && vkCode <= 90)
                vkCode = vkCode + 32;//处理为小写字母

            if (myHook.m_hInstance.vkCodeLast == 160)
            {
                if (vkCode >= 48 && vkCode <= 57 )
                {
                    if(vkCode==48)
                        vkCode= 41;//)
                    else if (vkCode == 49)
                        vkCode = 33; //!
                    else if (vkCode == 50)
                        vkCode = 64;// @
                    else if (vkCode == 51)
                        vkCode = 35;//#
                    else if (vkCode == 52)
                        vkCode = 36;//$
                    else if (vkCode == 53)
                        vkCode = 37;//%
                    else if (vkCode == 54)
                        vkCode = 94;//^
                    else if (vkCode == 55)
                        vkCode = 38;//&
                    else if (vkCode == 56)
                        vkCode = 42;//*
                    else if (vkCode == 57)
                        vkCode = 40;//)
                    else if (vkCode == 189)
                        vkCode = 95;//_
                    else if (vkCode == 187)
                        vkCode = 43;//+
                }
                else if (vkCode >= 97 && vkCode <= 122)
                    vkCode = vkCode - 32;//为大写字母

                if (vkCode == 186)//:
                {
                    vkCode = 58;
                }else if (vkCode == 187)
                    vkCode = 43;//+
                else if (vkCode == 189)
                    vkCode = 95;//-
                else if (vkCode == 190)
                    vkCode = 62;//>
                else if (vkCode == 191)
                    vkCode = 63;//?
                else if (vkCode == 219)
                    vkCode = 123;//{
                else if (vkCode == 220)
                    vkCode = 124;//|
                else if (vkCode == 221)
                    vkCode = 125;//}
            }

            if (vkCode == 186)// ;
            {
                vkCode = 59;
            }
            if (vkCode == 187)// =
            {
                vkCode = 61;
            }
            if (vkCode == 189)// -
            {
                vkCode = 45;
            }
            if (vkCode == 190)//.
            {
                vkCode = 46;
            }
            if (vkCode == 191)// /
            {
                vkCode = 47;
            }
            if (vkCode == 219)
                vkCode = 91;//[
            if (vkCode == 220)
                vkCode = 92;//\
            if (vkCode == 220)
                vkCode = 93;//]

            if (vkCode == 109)// 数字键-
            {
                vkCode = 45;
            }

            if (vkCode == 13)
            {
                myHook.m_hInstance._result.Add("\r\n");
            }


            if (vkCode != 160 && vkCode!=13&&vkCode != 40)
            {
                myHook.m_hInstance.lenNow++;

                string alpha = Convert.ToChar(vkCode).ToString();
                myHook.m_hInstance._result.Add(alpha);
            }

            myHook.m_hInstance.vkCodeLast = vkCode;
        }
        return CallNextHookEx(_hookID, nCode, wParam, lParam);
    }

二是扫码结束的判断。

程序中对接收到13回车的键盘码为结束的判断标志,收到后添加"\r\n"作为判断标志。

public static string getRet()
    {
        string s = string.Join("", myHook.m_hInstance._result.ToArray());  
        if (s.EndsWith("\r\n"))
        {
            myHook.m_hInstance._result.Clear();
            return s.Trim();
        }
        else
        {
            return "";
        }  
    }

我的处理测试代码U3D中使用(C#)在这里

使用时

string str = myHook.getRet();即可

你可能感兴趣的:(C#)