天天看點

使用鈎子函數[1]

使用鈎子函數[1]

目前對鈎子的了解:

譬如我們用滑鼠在某個視窗上輕按兩下了一次, 或者給某個視窗輸入了一個字母 a;

首先發現這些事件的不是視窗, 而是系統!

然後系統告訴視窗: 喂! 你讓人點了, 并且是連續點了兩滑鼠, 你準備怎麼辦?

或者是系統告訴視窗: 喂! 有人向你家裡扔磚頭了, 不信你看看, 那塊磚頭是 a.

這時視窗的對有些事件會忽略、對有些事件會做出反應:

譬如, 可能對滑鼠單擊事件忽略, 視窗想: 你單擊我不要緊, 累死你我不負責;

但一旦誰要輕按兩下我, 我會馬上行動, 給你點顔色瞧瞧!

這裡視窗準備要采取的行動, 就是我們提前寫好的事件.

用 windows 的話說, 視窗的事件就是系統發送給視窗的消息; 視窗要采取的行動(事件代碼)就是視窗的回調函數.

但是! 往往隔牆有耳. 系統要通知給視窗的"話"(消息), 可能會被另一個家夥(譬如是一個賊)提前聽到!

有可能這個賊就是專門在這等情報的, 賊知道後, 往往在視窗知道以前就采取了行動!

并且這個賊對不同的消息會采取不同的行動方案, 它的行動方案一般也是早就準備好的;

當然這個賊也不是對什麼消息都感興趣, 對不感興趣的消息也就無須制定相應的行動方案.

總結: 這個"賊"就是我們要設定的鈎子; "賊"的"行動方案"就是鈎子函數, 或者叫鈎子的回調函數.

鈎子分兩種, 一種是系統級的全局鈎子; 一種是線程級的鈎子.

全局鈎子函數需要定義在 dll 中, 從線程級的鈎子開始比較簡單.

其實鈎子函數就三個:

設定鈎子: setwindowshookex

釋放鈎子: unhookwindowshookex

繼續鈎子: callnexthookex

線上程級的鈎子中經常用到 getcurrentthreadid 函數來擷取目前線程的 id.

下面例子中設定了一個線程級的鍵盤鈎子, 專門攔截字母 a.

盡管這個例子已經很簡單了, 但還不足以讓人明白徹底; 下面還得從更簡單的開始.

繼續閱讀