C#开源: 全局钩子+正则表达式=后台自动获取扫描枪数据

最近在给瑞表做一个global project,主要工作是在Warehouse模块中加入现场的称重以及Barcode Collection和Transmission.

Barcode Scanner用的是摩托罗拉的LS 4278,Ls 2208 标配。

客户希望能够达到现场操作具备手动和后台自动俩种模式,考虑到现场的使用环境和供电情况,我们放弃了串口采用键盘线的连接方式。

作为Soluation的一部分,以下是全局钩子获取条码(通过条码结构定义区别键盘输入和Scanner输入)的源代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Diagnostics;
using Microsoft.Win32;
using System.Text.RegularExpressions;

namespace BarcodeReader
{
    /// <summary>
    /// Barcode Reader Module
    /// </summary>
    public class BarcodeReader
    {
        private List<string> strBarcode;
        private string strTempBarcode;
        private string strMessage;
        private string barcodeformat1;
        private string barcodeformat2;

        /// <summary>
        /// Barcode Value
        /// </summary>
        public virtual List<string> Barcode
        {
            get
            {
                return strBarcode;
            }
            set
            {
                strBarcode = value;
            }
        }

        /// <summary>
        /// Errpr Message
        /// </summary>
        public virtual string Message
        {
            get
            {
                return strMessage;
            }
            set
            {
                strMessage = value;
            }
        }

        /// <summary>
        /// Module Initial
        /// </summary>
        public BarcodeReader(string formatofbarcodeA, string formatofbarcodeB)
        {
            strBarcode = new List<string>();
            strTempBarcode = string.Empty;
            strMessage = string.Empty;
            barcodeformat1 = formatofbarcodeA;
            barcodeformat2 = formatofbarcodeB;
        }

        #region Customize Module
        /// <summary>
        /// Keyboard Start
        /// </summary>
        public virtual void Hook_Start()
        {
            // Install Keyboard
            if (hHook == 0)
            {
                KeyBoardHookProcedure = new HookProc(KeyBoardHookProc);
                hHook = SetWindowsHookEx(WH_KEYBOARD_LL,
                KeyBoardHookProcedure,
                GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);

                #region Thread Hook
                //hHook = SetWindowsHookEx(2,
                //KeyBoardHookProcedure,
                //GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), GetCurrentThreadId());
                #endregion

                // Failure
                if (hHook == 0)
                {
                    Hook_Clear();
                    strMessage  = "Fail to Install KeyBoard!";
                }
            }
        }

        /// <summary>
        /// Mouse Hook Start
        /// </summary>
        public virtual void MouseHook_Start()
        {
            // Install Mouse
            if (mousehook == 0)
            {
                MouseHookProcedure = new HookProc(MouseHookProc);
                mousehook = SetWindowsHookEx(WH_MOUSE_LL,
                MouseHookProcedure,
                GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), 0);

                #region Thread Hook
                //mousehook = SetWindowsHookEx(2,
                // KeyBoardHookProcedure,
                // GetModuleHandle(Process.GetCurrentProcess().MainModule.ModuleName), GetCurrentThreadId());
                #endregion

                // failure.
                if (mousehook == 0)
                {
                    MouseHook_Clear();
                    strMessage = "Fail to Install Mouse!";
                }
            }
        }

        /// <summary>
        /// Hook Clear
        /// </summary>
        public virtual void Hook_Clear()
        {
            bool retKeyboard = true;
            if (hHook != 0)
            {
                retKeyboard = UnhookWindowsHookEx(hHook);
                hHook = 0;
            }
            // failure
            if (!retKeyboard) strMessage = "Fail to Uninstall Keyboard!";
        }

        /// <summary>
        /// Mouse Hook Clear
        /// </summary>
        public virtual void MouseHook_Clear()
        {
            bool retMouseboard = true;
            if (mousehook != 0)
            {
                retMouseboard = UnhookWindowsHookEx(mousehook);
                mousehook = 0;
            }
            // failure
            if (!retMouseboard) strMessage = "Fail to Uninstall Mouse!";
        }

        /// <summary>
        /// KeyBoard Procedure
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        public virtual int KeyBoardHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                if ((int)wParam == 0x100 || (int)wParam == 0x104)
                {
                    KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));

                    //Catch Enter Key
                    if (kbh.vkCode == (int)System.Windows.Forms.Keys.Enter)
                    {
                        if (strTempBarcode != "")
                        {
                            //Transmit Barcode to main thread
                            string strTemp = string.Empty;
                            strTemp = string.Copy(strTempBarcode);
                            strTempBarcode = string.Empty;
                                                   
                            if (Regex.IsMatch(strTemp, barcodeformat1))
                            {
                                if (strBarcode.Count == 0)
                                {
                                    strBarcode.Add(strTemp);
                                    strBarcode.Add("");
                                }
                                else
                                {
                                    strBarcode[0] =  strTemp;
                                }
                            }
                            else if (Regex.IsMatch(strTemp, barcodeformat2))
                            {
                                if (strBarcode.Count != 2)
                                {
                                    if (strBarcode.Count == 0)
                                    {
                                        strBarcode.Add("");
                                        strBarcode.Add(strTemp);
                                    }
                                    else
                                    {
                                        strBarcode.Add(strTemp);
                                    }
                                }
                                else
                                {
                                    strBarcode[1] = strTemp;
                                }
                            }                           
                        }

                        // Scan Result Check
                        if (strBarcode.Count == 2)
                        {
                            if (!string.IsNullOrEmpty(strBarcode[0]) && !string.IsNullOrEmpty(strBarcode[1]))
                            {
                                strMessage = "Barcode has been read";
                            }
                            else if (string.IsNullOrEmpty(strBarcode[0]))
                            {
                                strMessage = "Please read first Barcode";
                            }
                            else if (string.IsNullOrEmpty(strBarcode[1]))
                            {
                                strMessage = "Please read second Barcode";
                            }
                            else
                            {
                                strMessage = "Please read Both of Barcode";
                            }
                        }
                        else
                        {
                            strMessage = "Please read Both of Barcode";
                        }
                    }
                    else
                    {
                        if ((kbh.vkCode >= 8 && kbh.vkCode <= 47) || (kbh.vkCode >= 112 && kbh.vkCode <= 123))
                        {

                        }
                        else
                        {
                            StringBuilder strKeyName = new StringBuilder(225);

                            if (GetKeyNameText(kbh.scanCode * 65536, strKeyName, 255) > 0)
                            {
                                strTempBarcode = strTempBarcode + strKeyName.ToString().Trim(new char[] { ' ', '\0' });
                            }
                        }
                    }
                }
            }
            //if (nCode >= 0)
            //{
            //    KeyBoardHookStruct kbh = (KeyBoardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyBoardHookStruct));
            //    //if (kbh.vkCode == (int)Keys.S && (int)Control.ModifierKeys == (int)Keys.Control) // 截获F8
            //    //{
            //    // MessageBox.Show("快捷键已拦截!不能保存!");
            //    // return 1;

            //    //}
            //    if (kbh.vkCode == (int)Keys.Delete
            //    && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt) //截获Ctrl+Alt+Y
            //    {
            //        MessageBox.Show("!DeleteDeleteDeleteDeleteDelete");
            //        return 1;
            //    }
            //    if (kbh.vkCode == (int)Keys.F10)
            //    {
            //        //SendMessage(btn1Handle, WM_LBUTTONDBLCLK, 0, 0);
            //        //SendMessage(btn1Handle, WM_LBUTTONUP, 0, 0);
            //        SendMessage(this.Handle, 500, 0, 0);
            //        return 1;
            //    }
            //    if (kbh.vkCode == (int)Keys.F11)
            //    {
            //        //SendMessage(btn1Handle, WM_LBUTTONDBLCLK, 0, 0);
            //        //SendMessage(btn1Handle, WM_LBUTTONUP, 0, 0);
            //        SendMessage(this.Handle, 501, 0, 0);
            //        return 1;
            //    }
            //}
            return CallNextHookEx(hHook, nCode, wParam, lParam);
        }

        /// <summary>
        /// Mouse Procedure
        /// </summary>
        /// <param name="nCode"></param>
        /// <param name="wParam"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        public virtual int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
        {
            if (nCode >= 0)
            {
                // MouseHookStruct kbh = (MouseHookStruct)Marshal.PtrToStructure(wParam, typeof(MouseHookStruct));
                //if (kbh.vkCode == (int)Keys.S && (int)Control.ModifierKeys == (int)Keys.Control) // 截获F8
                //{
                // MessageBox.Show("快捷键已拦截!不能保存!");
                // return 1;

                //}
                //if (kbh.vkCode == (int)Keys.Delete
                // && (int)Control.ModifierKeys == (int)Keys.Control + (int)Keys.Alt) //截获Ctrl+Alt+Y
                //{
                // MessageBox.Show("!DeleteDeleteDeleteDeleteDelete");
                // return 1;
                //}
                if ((int)wParam == (int)WM_MOUSE.WM_MOUSEMOVE)
                {
                    //SendMessage(btn1Handle, WM_LBUTTONDBLCLK, 0, 0);
                    //SendMessage(btn1Handle, WM_LBUTTONUP, 0, 0);
                    //if (!this.Bounds.Contains(Form.MousePosition))
                    //{
                    //SendMessage(this.Handle, 500, 0, 0);
                    //return 1;
                    //}
                }
                //if ((int)wParam == (int)WM_MOUSE.WM_RBUTTONDOWN)
                //{
                // //SendMessage(btn1Handle, WM_LBUTTONDBLCLK, 0, 0);
                // //SendMessage(btn1Handle, WM_LBUTTONUP, 0, 0);
                // SendMessage(this.Handle, 501, 0, 0);
                // return 1;
                //}
            }
            return CallNextHookEx(mousehook, nCode, wParam, lParam);
        }

        private const uint WM_LBUTTONUP = 0X202;
        private const uint WM_LBUTTONDBLCLK = 0X201;
        #endregion

        #region Delegate
        //Delegate
        public delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);
        static int hHook = 0;
        static int mousehook = 0;
        public const int WH_KEYBOARD_LL = 13;
        private const int WH_MOUSE_LL = 14;
        HookProc KeyBoardHookProcedure;
        HookProc MouseHookProcedure;

        //键盘Hook结构函数
        [StructLayout(LayoutKind.Sequential)]
        public class KeyBoardHookStruct
        {
            public int vkCode;
            public int scanCode;
            public int flags;
            public int time;
            public int dwExtraInfo;
        }
        ///
        /// 鼠标钩子事件结构定义
        ///
        /// 详细说明请参考MSDN中关于 MSLLHOOKSTRUCT 的说明
        [StructLayout(LayoutKind.Sequential)]
        public struct MouseHookStruct
        {
            ///
            /// Specifies a POINT structure that contains the x- and y-coordinates of the cursor, in screen coordinates.
            ///

            public POINT Point;
            public UInt32 MouseData;
            public UInt32 Flags;
            public UInt32 Time;
            public UInt32 ExtraInfo;
        }

        [StructLayout(LayoutKind.Sequential)]
        public struct POINT
        {
            public int X;
            public int Y;
        }
        #endregion

        #region DllImport
        //Hook Setting
        [DllImport("user32.dll")]
        public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
        [DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
        //Hook Uninstall
        public static extern bool UnhookWindowsHookEx(int idHook);
        [DllImport("user32.dll")]
        //Hook Call
        public static extern int CallNextHookEx(int idHook, int nCode, IntPtr wParam, IntPtr lParam);

        [DllImport("kernel32.dll")]
        public static extern int GetCurrentThreadId();

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetModuleHandle(string name);

        [DllImport("User32.dll")]
        private static extern IntPtr SendMessage(IntPtr hwnd, uint msg, int wParam, int lParam);

        [DllImport("User32.dll")]
        private static extern int GetKeyNameText(int IParam, StringBuilder lpBuffer, int nSize);
        #endregion

        #region MOUSEEVENT
        /// <summary>
        /// Mouse event
        /// </summary>
        public enum WM_MOUSE : int
        {
            ///
            /// 鼠标开始
            ///

            WM_MOUSEFIRST = 0X200,

            ///
            /// 鼠标移动
            ///

            WM_MOUSEMOVE = 0X200,

            ///
            /// 左键按下
            ///

            WM_LBUTTONDOWN = 0X201,

            ///
            /// 左键释放
            ///

            WM_LBUTTONUP = 0X202,

            ///
            /// 左键双击
            ///

            WM_LBUTTONDBLCLK = 0X203,

            ///
            /// 右键按下
            ///

            WM_RBUTTONDOWN = 0X204,

            ///
            /// 右键释放
            ///

            WM_RBUTTONUP = 0X205,

            ///
            /// 右键双击
            ///

            WM_RBUTTONDBLCLK = 0X206,

            ///
            /// 中键按下
            ///

            WM_MBUTTONDOWN = 0X207,

            ///
            /// 中键释放
            ///

            WM_MBUTTONUP = 0X208,

            ///
            /// 中键双击
            ///

            WM_MBUTTONDBLCLK = 0X209,

            ///
            /// 滚轮滚动
            ///

            /// WINNT4.0以上才支持此消息
            WM_MOUSEWHEEL = 0x020A
        }
        #endregion


    }
}

posted @ 2012-10-12 11:04  风飞叶  阅读(1681)  评论(2编辑  收藏  举报