C 全域性鍵盤監聽(Hook)的使用

2021-07-12 02:59:34 字數 4075 閱讀 5681

一.為什麼需要全域性鍵盤監聽?

在某些情況下應用程式需要實現快捷鍵執行特定功能,例如大家熟知的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...