背景:今天接到客戶一個需求,就是在收銀員在用掃碼槍掃顧客會員碼或者微信付款碼的時候判斷用戶有沒有加企微好友和進企微群,然后根據(jù)這個狀態(tài)進行語音播報,判斷顧客能不能享受優(yōu)惠價。關鍵難點就是用戶用的收銀系統(tǒng)是別家的,線上小程序用的是我們家的,兩家不互通,所以立即決定采用Hook鉤子技術做一工具掛在其他收銀系統(tǒng)上。文章來源:http://www.zghlxwxcb.cn/news/detail-815035.html
Hook鉤子
Windows是一個不斷處理消息的系統(tǒng),每次的鼠標點擊移動鍵盤輸入都是消息。鉤子是系統(tǒng)消息處理的一環(huán),可以使用鉤子處理函數(shù)來監(jiān)聽消息傳送,并處理消息。文章來源地址http://www.zghlxwxcb.cn/news/detail-815035.html
思路
- 用WPF做一個無邊框小小的半透明圓形窗體使用TopMost長駐留在桌面上。
- 增加一個ContextMenu 菜單,安裝鉤子和卸載鉤子
- 接入鉤子API
#region 第一步:聲明API函數(shù)。
// 安裝鉤子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hInstance, int threadId);
// 卸載鉤子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern bool UnhookWindowsHookEx(int idHook);
// 繼續(xù)下一個鉤子
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]
public static extern int CallNextHookEx(int idHook, int nCode, Int32 wParam, IntPtr lParam);
// 取得當前線程編號
[DllImport("kernel32.dll")]
static extern int GetCurrentThreadId();
#endregion
- 聲明鍵盤消息結構和鼠標消息結構
public struct KeyMSG
{
public int vkCode;
public int scanCode;
public int flags;
public int time;
public int dwExtraInfo;
}
public struct MSG
{
public Point p;
public IntPtr HWnd;
public uint wHitTestCode;
public int dwExtraInfo;
}
- 安裝鍵盤鉤子和鼠標鉤子
#region 第二步:聲明,定義委托
public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);
static int hKeyboardHook = 0;//如果hKeyboardHook不為0則說明鉤子安裝成功
HookProc KeyboardHookProcedure;
static int hMouseHook = 0;
HookProc mouseHookProcedure;
#endregion
private void install_Click(object sender, RoutedEventArgs e)
{
HookStart();
}
private void HookStart()
{
if (hKeyboardHook == 0)//如果hKeyboardHook==0,鉤子安裝失敗
{
//創(chuàng)建HookProc實例
KeyboardHookProcedure = new HookProc(KeyboardHookProc);
//設置全局鉤子
hKeyboardHook = SetWindowsHookEx(13, KeyboardHookProcedure,
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
if (hKeyboardHook == 0)
{
//終止鉤子
throw new Exception("安裝鉤子失敗");
}
Trace.WriteLine("鍵盤鉤子安裝成功");
}
if(hMouseHook == 0)
{
mouseHookProcedure = new HookProc(MouseHookProc);
hMouseHook = SetWindowsHookEx(14, mouseHookProcedure,
Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);
if(hMouseHook == 0)
{
throw new Exception("安裝鼠標鉤子失敗");
}
Trace.WriteLine("鼠標鉤子安裝成功");
}
}
- 增加鍵盤鉤子和鼠標鉤子處理函數(shù)
private StringBuilder codes = new StringBuilder(); //接收掃碼槍輸入的數(shù)據(jù)
private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)
{
if (nCode >= 0)
{
if(wParam == 0x100)
{
KeyMSG m = (KeyMSG)Marshal.PtrToStructure(lParam, typeof(KeyMSG));
if (m.vkCode == 0x31)
{
codes.Append(1);
}
else if (m.vkCode == 0x32)
{
codes.Append(2);
}
else if (m.vkCode == 0x33)
{
codes.Append(3);
}
else if (m.vkCode == 0x34)
{
codes.Append(4);
}
else if (m.vkCode == 0x35)
{
codes.Append(5);
}
else if (m.vkCode == 0x36)
{
codes.Append(6);
}
else if (m.vkCode == 0x37)
{
codes.Append(7);
}
else if (m.vkCode == 0x38)
{
codes.Append(8);
}
else if (m.vkCode == 0x39)
{
codes.Append(9);
}
else if (m.vkCode == 0x30)
{
codes.Append(0);
}
else if (m.vkCode == 0x60)
{
codes.Append(0);
}
else if (m.vkCode == 0x61)
{
codes.Append(1);
}
else if (m.vkCode == 0x62)
{
codes.Append(2);
}
else if (m.vkCode == 0x63)
{
codes.Append(3);
}
else if (m.vkCode == 0x64)
{
codes.Append(4);
}
else if (m.vkCode == 0x65)
{
codes.Append(5);
}
else if (m.vkCode == 0x66)
{
codes.Append(6);
}
else if (m.vkCode == 0x67)
{
codes.Append(7);
}
else if (m.vkCode == 0x68)
{
codes.Append(8);
}
else if (m.vkCode == 0x69)
{
codes.Append(9);
}
if (m.vkCode == 0x0D)
{
// 回車鍵
string code = codes.ToString();
Trace.WriteLine(code);
if(code.Length == 18)
{
StatausHandle(code);
codes.Clear();
}
}
}
}
return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);
}
- 卸載鍵盤鉤子和鼠標鉤子
private void unInstall_Click(object sender, RoutedEventArgs e)
{
HookStop();
}
private void HookStop()
{
bool retKeyboard = true;
if (hKeyboardHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hKeyboardHook);
hKeyboardHook = 0;
}
if (!retKeyboard)
throw new Exception("鉤子卸載失敗");
Trace.WriteLine("鍵盤鉤子卸載成功");
if (hMouseHook != 0)
{
retKeyboard = UnhookWindowsHookEx(hMouseHook);
hMouseHook = 0;
}
if (!retKeyboard)
throw new Exception("鼠標鉤子卸載失敗");
Trace.WriteLine("鼠標鉤子卸載成功");
}
- 好了,拿到的code就算掃碼槍輸入的條碼,根據(jù)這個條碼實現(xiàn)自己的判斷邏輯來進行語音播報就行了。
到了這里,關于c#使用Hook鉤子全局監(jiān)聽鍵盤和鼠標的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!