當前位置:編程學習大全網 - 源碼下載 - ucos裏的hook函數是什麽?為什麽要有這些函數?幹什麽用的?

ucos裏的hook函數是什麽?為什麽要有這些函數?幹什麽用的?

鉤子HOOK函數是Windows消息處理機制的壹部分,通過設置“鉤子”,應用程序可以在系統級對所有消息、事件進行過濾,訪問在正常情況下無法訪問的消息。當然,這麽做也是需要付出壹定的代價的。由於多了這麽壹道處理過程,系統性能會受到壹定的影響,所以大家在必要的時候才使用“鉤子”,並在使用完畢及時將其刪除。

首先讓我們看看HOOK函數是怎麽安裝、調用和刪除的。應用程序通常是調用SetWindowsHookEx()函數來進行安裝的,其函數的原型如下:

SetWindowsHookEx(

Int idHook;

HOOKPROC lpfn;

HINSTANCE hMod;

DWORD dwThreadId;

);

參數說明:

idHook 是”鉤子”的類型,”鉤子”的類型壹***有13種,具體如下表:

“鉤子”類型

解釋

WH_CALLWNDPROC

系統將消息發送到指定窗口之前的“鉤子”

WH_CALLWNDPROCRET

消息已經在窗口中處理的“鉤子”

WH_CBT

基於計算機培訓的“鉤子”

WH_DEBUG

差錯“鉤子”

WH_FOREGROUNDIDLE

前臺空閑窗口“鉤子”

WH_GETMESSAGE

接收消息投遞的“鉤子”

WH_JOURNALPLAYBACK

回放以前通過WH_JOURNALRECORD“鉤子”記錄的輸入消息

WH_JOURNALRECORD

輸入消息記錄“鉤子”

WH_KEYBOARD

鍵盤消息“鉤子”

WH_MOUSE

鼠標消息“鉤子”

WH_MSGFILTER

對話框、消息框、菜單或滾動條輸入消息“鉤子”

WH_SHELL

外殼“鉤子”

WH_SYSMSGFILTER

系統消息“鉤子”

lpfn 指向“鉤子”過程的指針。

hMod “鉤子”過程所在模塊的句柄。

dwThreadId “鉤子”相關線程的標識。

通常我們都是把”鉤子”做成動態鏈接庫,這樣的好處是可以是系統內的每個進程訪問。但是也可以在系統中直接調用,我的建議還是用動態庫。如果用動態庫的話,那麽SetWindowsHookEx()中的第三個參數就是該動態鏈接庫模塊的句柄;對於壹個只供單個進程訪問的”鉤子”,可以將其”鉤子”過程放在安裝”鉤子”的同壹個線程內,此時SetWindowsHookEx()中的第三個參數為該線程的hInstance。安裝”鉤子”有兩種方法:1.妳可以把他做成動態連接庫文件,和程序壹起編譯。2.妳可以在程序的任何地方直接調用。第2種的方法太麻煩,我不建議用,在這裏我就不詳細介紹啦。相比之下第1種比較簡單。其”鉤子”的過程都在動態鏈接庫內完成。SetWindowsHookEx()函數是壹個安裝函數,如故壹個由某種類型的”鉤子”監視的事件發生,系統就會調用相應類型的”鉤子”鏈開始處的”鉤子”過程,”鉤子”鏈的每個”鉤子”過程都要考慮是否把事件傳遞給下壹個”鉤子”過程。如果要傳遞的話,就要調用CallNestHookEx()函數。這個函數成功時返回”鉤子”鏈中下壹個”鉤子”過程的返回值,返回值的類型依賴於”鉤子”的類型。這個函數的原型如下:

LRESULT CallNextHookEx(

HHOOK hhk;

int nCode;

WPARAM wParam;

LPARAM lParam;

);

其中hhk為當前”鉤子”的句柄,由SetWindowsHookEx()函數返回。NCode為傳給”鉤子”過程的事件代碼。wParam和lParam 分別是傳給”鉤子”過程的wParam值,其具體含義與”鉤子”類型有關。

釋放”鉤子”

釋放”鉤子”比較簡單,他只有壹個參數。當不在需要”鉤子”時,應及時將其釋放。他是調用UnhookWindowsHookEx()函數來實現的,函數原型如下:

UnhookWindowsHookEx(

HHOOK hhk;

);

函數成功返回TRUE,否則返回FALSE。

如果我這樣講您還是不明白的話,請看下面給出的壹些典型“鉤子”代碼和說明。

LRESULT WINAPI CallWndProc(int nCode,WPARAM wParam,LPARAM lParam)

{

if(nCode<0)

return CallNextHookEx(NULL,nCode,wParam,lParam);

switch(nCode)

{

case HC_ACTION:

//”鉤子”程序要處理什麽的代碼

break;

default:

break;

}

return CallNextHookEx(NULL,nCode,wParam,lParam);

}

這是WH_CALLWNDPROC”鉤子”的代碼,此”鉤子”允許程序監視由函數SendMessage發送給窗口過程的消息。系統將消息發送到目的窗口之前調用WH_CALLWNDPROC “鉤子”過程。

LRESULT WINAPI CallwndProc(int nCode,WPARAM,wParam,LPARAM lParam)

{

if(nCode<0) return callNextHookEx(NULL,nCode,wParam,lParam);

switch(nCode)

{

case HC_ACTION:

switch(wParam)

{

Case PM_REMOVE:

//某個應用程序調用了GetMessage函數或者是帶PM_REMOVE參數的//PeekMessage函數,從消息隊列中移去壹個消息。

Break;

Case PM_NOREMOVE:

//某個應用程序以PM_NOREMOVE為參數調用PeekMessage函數

break;

default:

break;

}

break;

default:

break;

}

return CallNextHookEx(NULL,nCode,wParam,lParam);

}

這是調用WH_GETMESSAGE的函數,此函數允許應用程序監視函數GetMessage和 PeekMessage返回的消息。應用程序可以用鉤子WH_GETMESSAGE來監視鼠標和鍵盤的輸入以及其他系統發送到消息隊列中的消息。

LRESULT CALLBACK CBTProc(int nCode,WPARAM wParam,LPARAM lParam)

{

If(nCode<0) Return callNextHookEx(NULL,nCode,wParam,lParam);

Switch(nCode)

{

case HCBT_ACTIVATE:

//系統將激活壹個窗口

break;

case HCBT_CLICKSKIPPED:

//系統從系統消息隊列中移去壹個鼠標消息

break;

case HCBT_CREATEWND:

//系統將創建壹個窗口

break;

case HCBT_DESTROYWND:

//系統將關閉壹個窗口

break;

case HCBT_KEYSKIPPED:

//系統從系統消息隊列中移去壹個鍵盤消息

break;

case HCBT_MINMAX:

//系統將最大化或最小化壹個窗口

break;

case HCBT_MOVESIZE:

//系統將移動壹個窗口或改變壹個窗口的大小

break;

case HCBT_QS:

//系統在系統消息隊列中檢索到WM_QUEUESYNC消息

break;

case HCBT_SETFOCUS:

//系統設置鍵盤輸入窗口

break;

case HCBT_SYSCOMMAND:

//將要執行壹個系統命令

break;

default:

//可以添加其他代碼

break;

}

return CallNextHookEx(NULL,nCode,wParam,lParam);

}

每種”鉤子”類型都有其對應的函數,這些函數的參數都是壹樣的,有興趣的朋友可以在MSDN中找的他們的詳細說明。

下面我給出壹個完整的”鉤子”安裝和刪除的過程的代碼。

#include "stdafx.h"

#include "hook.h"

HINSTANCE hInstance;

HHOOK hhkKeyboard;

BOOL APIENTRY DllMain( HANDLE hModule,DWORD ul_reason_for_call, LPVOID lpReserved)

{

switch (ul_reason_for_call)

{

case DLL_PROCESS_ATTACH:

case DLL_THREAD_ATTACH:

case DLL_THREAD_DETACH:

case DLL_PROCESS_DETACH:

break;

}

hInstance=(HINSTANCE)hModule;

return TRUE;

}

LRESULT KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

{

MessageBeep(-1);

return CallNextHookEx(hhkKeyboard,nCode,wParam,lParam);

}

HOOK_API BOOL EnableKeyboardCapture()

{

if(!(hhkKeyboard=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hInstance,0)))

return FALSE;

return TRUE;

}

HOOK_API BOOL DisableKeyboardCapture()

{

return UnhookWindowsHookEx(hhkKeyboard);

}

註意:這是壹個動態鏈接庫文件。

在程序中要想調用“鉤子”的時候,有EnableKeyboardCapture()函數就可以啦,但妳按鍵的時候就回發出聲音。

  • 上一篇:春節發紅包的來歷及傳說
  • 下一篇:SpringBoot中使用@RequestBody時如何自定義需要轉換的日期格式
  • copyright 2024編程學習大全網