一.為什麼需要全域性鍵盤監聽?
在某些情況下應用程式需要實現快捷鍵執行特定功能,例如大家熟知的qq截圖功能ctrl+alt+a快捷鍵,只要qq程式在執行(無論是擁有焦點還是處於後台執行狀態),都可以按下快捷鍵使用此功能…
二.怎樣才能實現全域性鍵盤監聽?
這裡需要用到windows api,原始碼如下:(可以作為乙個工具類[keyboardhook.cs]收藏起來)
using system;
using system.collections.generic;
using system.text;
using system.runtime.interopservices;
using system.windows.forms;
using system.reflection;
namespace 桌布管家
//使用此功能,安裝了乙個鉤子
[dllimport("user32.dll", charset = charset.auto, callingconvention = callingconvention.stdcall)]
public
static
extern
intsetwindowshookex(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
intcallnexthookex(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()}}
public
void
stop()
if (!(retkeyboard)) throw
new exception("解除安裝鉤子失敗!");
}//toascii職能的轉換指定的虛擬鍵碼和鍵盤狀態的相應字元或字元
[dllimport("user32")]
public
static
extern
inttoascii(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
intgetkeyboardstate(byte pbkeystate);
[dllimport("user32.dll", charset = charset.auto, callingconvention = callingconvention.stdcall)]
private
static
extern
short
getkeystate(int vkey);
private
const
int wm_keydown = 0x100;//keydown
private
const
int wm_keyup = 0x101;//keyup
private
const
int wm_syskeydown = 0x104;//syskeydown
private
const
int wm_syskeyup = 0x105;//syskeyup
private
intkeyboardhookproc(int ncode, int32 wparam, intptr lparam)
//鍵盤按下
if (keypressevent != null && wparam == wm_keydown)
}// 鍵盤抬起
if (keyupevent != null && (wparam == wm_keyup || wparam == wm_syskeyup))
}//如果返回1,則結束訊息,這個訊息到此為止,不再傳遞。
//如果返回0或呼叫callnexthookex函式則訊息出了這個鉤子繼續往下傳遞,也就是傳給訊息真正的接受者
return callnexthookex(hkeyboardhook, ncode, wparam, lparam);
}~keyboardhook()
}}
三.如何使用上面的工具類?
//0.準備工作
//把上面的工具類新增到專案中
//1.首先匯入需要的命名空間
using system.runtime.interopservices; //呼叫windows api函式時要用到
using microsoft.win32; //寫入登錄檔時要用到
//2.安裝hook,在程式入口中寫上下面的**(本例中用了winform,在form的構造方法中安裝hook即可)
//安裝鍵盤鉤子
k_hook = new keyboardhook();
k_hook.keydownevent += new keyeventhandler(hook_keydown);//鉤住鍵按下
k_hook.start();//安裝鍵盤鉤子
//3.判斷輸入鍵值(實現keydown事件)
private void hook_keydown(object sender, keyeventargs e) }
//注意幾種不同的鍵值判斷:
//1>.單普通鍵(例如a)
//2>.單控制鍵+單普通鍵(例如ctrl+a)
//3>.多控制鍵+單普通鍵(例如ctrl+alt+a)
//上面的**中演示了2,其它情況以此類推,無非就是添幾個條件再&&起來就好
四.使用全域性鍵盤監聽需要注意的問題(請讀者朋友務必看看)
1.在應用程式中使用全域性鍵盤監聽,會被360發現,彈窗提示使用者「有程式正在監聽鍵盤輸入,是否阻止?」
所以如果程式中必須要用hook應該告訴使用者不會洩露其資訊等等
否則殺軟的提示會對使用者體驗造成極大的影響
HOOK使用 全域性鍵盤鉤子
define win32 winnt 0x0500 設定系統版本,可以使用底層鍵盤鉤子 define wm my shorts wm user 105 include windows.h 全域性變數 lpword g lpdwvirtualkey null keycode 陣列的指標 int g n...
C 全域性鍵盤監聽
using system using system.collections.generic using system.text using system.runtime.interopservices using system.windows.forms using system.reflectio...
C 全域性滑鼠鍵盤Hook
原文出自 using system using system.collections.generic using system.reflection using system.runtime.interopservices using system.text using system.windows...