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