日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

C#全局监听Windows键盘事件

發布時間:2023/12/29 C# 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#全局监听Windows键盘事件 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本方法只涉及到如何應用現有工具類實現監聽,其具體的原理主要涉及到調用Windows底層API:定義一個鉤子鉤住鍵盤事件,在這里不講具體原理。

1.工具類代碼

引用

using System; using System.Collections.Generic; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Reflection;

具體代碼

class KeyboardHook{public event KeyEventHandler KeyDownEvent;public event KeyPressEventHandler KeyPressEvent;public event KeyEventHandler KeyUpEvent;public delegate int HookProc(int nCode, Int32 wParam, IntPtr lParam);static int hKeyboardHook = 0; //聲明鍵盤鉤子處理的初始值//值在Microsoft SDK的Winuser.h里查詢public const int WH_KEYBOARD_LL = 13; //線程鍵盤鉤子監聽鼠標消息設為2,全局鍵盤監聽鼠標消息設為13HookProc KeyboardHookProcedure; //聲明KeyboardHookProcedure作為HookProc類型//鍵盤結構[StructLayout(LayoutKind.Sequential)]public class KeyboardHookStruct{public int vkCode; //定一個虛擬鍵碼。該代碼必須有一個價值的范圍1至254public int scanCode; // 指定的硬件掃描碼的關鍵public int flags; // 鍵標志public int time; // 指定的時間戳記的這個訊息public int dwExtraInfo; // 指定額外信息相關的信息}//使用此功能,安裝了一個鉤子[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);//使用此功能,通過信息鉤子繼續下一個鉤子[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();//使用WINDOWS API函數代替獲取當前實例的函數,防止鉤子失效[DllImport("kernel32.dll")]public static extern IntPtr GetModuleHandle(string name);public void Start(){// 安裝鍵盤鉤子if (hKeyboardHook == 0){KeyboardHookProcedure = new HookProc(KeyboardHookProc);hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, GetModuleHandle(System.Diagnostics.Process.GetCurrentProcess().MainModule.ModuleName), 0);//hKeyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardHookProcedure, Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]), 0);//************************************//鍵盤線程鉤子SetWindowsHookEx(13, KeyboardHookProcedure, IntPtr.Zero, GetCurrentThreadId());//指定要監聽的線程idGetCurrentThreadId(),//鍵盤全局鉤子,需要引用空間(using System.Reflection;)//SetWindowsHookEx( 13,MouseHookProcedure,Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),0);////關于SetWindowsHookEx (int idHook, HookProc lpfn, IntPtr hInstance, int threadId)函數將鉤子加入到鉤子鏈表中,說明一下四個參數://idHook 鉤子類型,即確定鉤子監聽何種消息,上面的代碼中設為2,即監聽鍵盤消息并且是線程鉤子,如果是全局鉤子監聽鍵盤消息應設為13,//線程鉤子監聽鼠標消息設為7,全局鉤子監聽鼠標消息設為14。lpfn 鉤子子程的地址指針。如果dwThreadId參數為0 或是一個由別的進程創建的//線程的標識,lpfn必須指向DLL中的鉤子子程。 除此以外,lpfn可以指向當前進程的一段鉤子子程代碼。鉤子函數的入口地址,當鉤子鉤到任何//消息后便調用這個函數。hInstance應用程序實例的句柄。標識包含lpfn所指的子程的DLL。如果threadId 標識當前進程創建的一個線程,而且子//程代碼位于當前進程,hInstance必須為NULL。可以很簡單的設定其為本應用程序的實例句柄。threaded 與安裝的鉤子子程相關聯的線程的標識符//如果為0,鉤子子程與所有的線程關聯,即為全局鉤子//************************************//如果SetWindowsHookEx失敗if (hKeyboardHook == 0){Stop();throw new Exception("安裝鍵盤鉤子失敗");}}}public void Stop(){bool retKeyboard = true;if (hKeyboardHook != 0){retKeyboard = UnhookWindowsHookEx(hKeyboardHook);hKeyboardHook = 0;}if (!(retKeyboard)) throw new Exception("卸載鉤子失敗!");}//ToAscii職能的轉換指定的虛擬鍵碼和鍵盤狀態的相應字符或字符[DllImport("user32")]public static extern int ToAscii(int uVirtKey, //[in] 指定虛擬關鍵代碼進行翻譯。int uScanCode, // [in] 指定的硬件掃描碼的關鍵須翻譯成英文。高階位的這個值設定的關鍵,如果是(不壓)byte[] lpbKeyState, // [in] 指針,以256字節數組,包含當前鍵盤的狀態。每個元素(字節)的數組包含狀態的一個關鍵。如果高階位的字節是一套,關鍵是下跌(按下)。在低比特,如果設置表明,關鍵是對切換。在此功能,只有肘位的CAPS LOCK鍵是相關的。在切換狀態的NUM個鎖和滾動鎖定鍵被忽略。byte[] lpwTransKey, // [out] 指針的緩沖區收到翻譯字符或字符。int fuState); // [in] Specifies whether a menu is active. This parameter must be 1 if a menu is active, or 0 otherwise.//獲取按鍵的狀態[DllImport("user32")]public static extern int GetKeyboardState(byte[] pbKeyState);[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]private static extern short GetKeyState(int vKey);private const int WM_KEYDOWN = 0x100;//KEYDOWNprivate const int WM_KEYUP = 0x101;//KEYUPprivate const int WM_SYSKEYDOWN = 0x104;//SYSKEYDOWNprivate const int WM_SYSKEYUP = 0x105;//SYSKEYUPprivate int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam){// 偵聽鍵盤事件if ((nCode >= 0) && (KeyDownEvent != null || KeyUpEvent != null || KeyPressEvent != null)){KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));// raise KeyDownif (KeyDownEvent != null && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)){Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;KeyEventArgs e = new KeyEventArgs(keyData);KeyDownEvent(this, e);}//鍵盤按下if (KeyPressEvent != null && wParam == WM_KEYDOWN){byte[] keyState = new byte[256];GetKeyboardState(keyState);byte[] inBuffer = new byte[2];if (ToAscii(MyKeyboardHookStruct.vkCode, MyKeyboardHookStruct.scanCode, keyState, inBuffer, MyKeyboardHookStruct.flags) == 1){KeyPressEventArgs e = new KeyPressEventArgs((char)inBuffer[0]);KeyPressEvent(this, e);}}// 鍵盤抬起if (KeyUpEvent != null && (wParam == WM_KEYUP || wParam == WM_SYSKEYUP)){Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;KeyEventArgs e = new KeyEventArgs(keyData);KeyUpEvent(this, e);}}//如果返回1,則結束消息,這個消息到此為止,不再傳遞。//如果返回0或調用CallNextHookEx函數則消息出了這個鉤子繼續往下傳遞,也就是傳給消息真正的接受者return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);}~KeyboardHook(){Stop();}}

2.調用方法

2.1啟動監聽

首先定義按鍵鉤子及工具類

private KeyEventHandler myKeyEventHandeler = null;//按鍵鉤子private KeyboardHook k_hook = new KeyboardHook();

其次,定義監聽后需要實現的方法

private void hook_KeyDown(object sender, KeyEventArgs e){// 這里寫具體實現writeLog("按下按鍵" + e.KeyValue);}

最后開啟監聽

public void startListen(){myKeyEventHandeler= new KeyEventHandler(hook_KeyDown);k_hook.KeyDownEvent += myKeyEventHandeler;//鉤住鍵按下k_hook.Start();//安裝鍵盤鉤子}

2.2關閉監聽

public void stopListen(){if (myKeyEventHandeler != null){k_hook.KeyDownEvent -= myKeyEventHandeler;//取消按鍵事件myKeyEventHandeler = null;k_hook.Stop();//關閉鍵盤鉤子}}

點擊下載例程

總結

以上是生活随笔為你收集整理的C#全局监听Windows键盘事件的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。