回調函數和鈎子函數的說明


回調函數:

回調函數是應用程序提供給Windows系統DLL或其它DLL調用的函數,一般用於截獲消息、獲取系統信息或處理異步事件。應用程序把回調函數的地址指針告訴DLL,而DLL在適當的時候會調用該函數。回調函數必須遵守事先規定好的參數格式和傳遞方式,否則DLL一調用它就會引起程序或系統的崩潰。通常情況下,回調函數采用標准WindowsAPI的調用方式,即__stdcall,當然,DLL編制者可以自己定義調用方式,但客戶程序也必須遵守相同的規定。在__stdcall方式下,函數的參數按從右到左的順序壓入堆棧,除了明確指明是指針或引用外,參數都按值傳遞,函數返回之前自己負責把參數從堆棧中彈出。

    簡單的說就是回調函數函數不是系統定義的,而是應用程序自己定義的一個由系統來調用的函數,所以顯然,它的參數必須按照約定來,即,參數是預先定義好的。

鈎子函數:

WINDOWS的鈎子函數可以認為是WINDOWS的主要特性之一。利用它們,您可以捕捉您自己進程或其它進程發生的事件。通過“鈎掛”,您可以給WINDOWS一個處理或過濾事件的回調函數,該函數也叫做“鈎子函數”,當每次發生您感興趣的事件時,WINDOWS都將調用該函數。一共有兩種類型的鈎子:局部的和遠程的。 

 

  局部鈎子僅鈎掛您自己進程的事件。 

  遠程的鈎子還可以將鈎掛其它進程發生的事件。遠程的鈎子又有兩種: 

  基於線程的 它將捕獲其它進程中某一特定線程的事件。簡言之,就是可以用來觀察其它進程中的某一特定線程將發生的事件。 

  系統范圍的 將捕捉系統中所有進程將發生的事件消息。 當您創建一個鈎子時,WINDOWS會先在內存中創建一個數據結構,該數據結構包含了鈎子的相關信息,然后把該結構體加到已經存在的鈎子鏈表中去。新的鈎子將加到老的前面。當一個事件發生時,如果您安裝的是一個局部鈎子,您進程中的鈎子函數將被調用。如果是一個遠程鈎子,系統就必須把鈎子函數插入到其它進程的地址空間,要做到這一點要求鈎子函數必須在一個動態鏈接庫中,所以如果您想要使用遠程鈎子,就必須把該鈎子函數放到動態鏈接庫中去。當然有兩個例外:工作日志鈎子和工作日志回放鈎子。這兩個鈎子的鈎子函數必須在安裝鈎子的線程中。原因是:這兩個鈎子是用來監控比較底層的硬件事件的,既然是記錄和回放,所有的事件就當然都是有先后次序的。所以如果把回調函數放在DLL中,輸入的事件被放在幾個線程中記錄,所以我們無法保證得到正確的次序。故解決的辦法是:把鈎子函數放到單個的線程中,譬如安裝鈎子的線程。 

 

  鈎子一共有14種,以下是它們被調用的時機: 

 

  WH_CALLWNDPROC 當調用SendMessage時 

 

  WH_CALLWNDPROCRET 當SendMessage的調用返回時 

 

  WH_GETMESSAGE 當調用GetMessage 或 PeekMessage時 

 

  WH_KEYBOARD 當調用GetMessage 或 PeekMessage 來從消息隊列中查詢WM_KEYUP 或 WM_KEYDOWN 消息時 

 

  WH_MOUSE 當調用GetMessage 或 PeekMessage 來從消息隊列中查詢鼠標事件消息時 

 

  WH_HARDWARE 當調用GetMessage 或 PeekMessage 來從消息隊列種查詢非鼠標、鍵盤消息時 

 

  WH_MSGFILTER 當對話框、菜單或滾動條要處理一個消息時。該鈎子是局部的。它時為那些有自己的消息處理過程的控件對象設計的。 

 

  WH_SYSMSGFILTER 和WH_MSGFILTER一樣,只不過是系統范圍的 

 

  WH_JOURNALRECORD 當WINDOWS從硬件隊列中獲得消息時 

 

  WH_JOURNALPLAYBACK 當一個事件從系統的硬件輸入隊列中被請求時 

 

  WH_SHELL 當關於WINDOWS外殼事件發生時,譬如任務條需要重畫它的按鈕. 

 

  WH_CBT 當基於計算機的訓練(CBT)事件發生時 

 

  WH_FOREGROUNDIDLE 由WINDOWS自己使用,一般的應用程序很少使用 

 

  WH_DEBUG 用來給鈎子函數除錯 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM