1.需要用到的函數
學過Windows編程的應該都知道,Windows的核心機制是消息機制,消息是操作系統告訴應用程序發生了什么事情,比如當用戶移動了鼠標或者按鍵后,操作系統會通知應用程序
實際上在Windows下,我們可以監控操作系統發送給另外一個進程的消息,然后決定對這個消息怎么處理,比如繼續發送,或者改變消息,或者不讓這個消息發給應用程序,也可以讓應用程序處理完消息后通知監控的進程 這些都依賴一個API,SetWindowsHookEx
HHOOK WINAPI SetWindowsHookEx( _In_ int idHook, _In_ HOOKPROC lpfn, _In_ HINSTANCE hMod, _In_ DWORD dwThreadId );
idHook就是我們要監控的消息類型
lpfn是當我們收到這個消息后,要交給哪個函數去處理,函數的類型是HOOKPROC,這個函數定義在winuser.h里面,原型是
typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
hMod是我們函數所在模塊,如果我們的函數是在DLL里面,那么我們需要兩個API,一個是Loadlibrary,一個是GetProcAddress,前者映射一個DLL到我們的進程里面,后者則是從一個DLL
返回我們所需要的函數
dwThreadID是我們要監視的線程ID,如果是0的話就是系統鈎子,也就是我們監視的進程所有消息都會獲取
詳細的解釋請參考MSDN:
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
在我們截取到監視的進程的消息后,我們可以調用CallNextHookEx來將消息繼續傳遞,當然也可以選擇不讓消息繼續傳遞,如果我們不喜歡將該消息傳遞給監視的進程,就在函數里面return 1
,如果要把他發送給監視的進程,就return 0
2.截取本進程的消息
1.創建項目
我們用VS創建一個WIN32項目,這樣就默認給我們創建了一個接收消息的窗口,具體過程如下 (VS2008環境下):
文件->新建項目->選擇WIN32項目,並且輸入名稱->點擊確定
進入向導后,直接點擊完成,這樣就創建了一個WIN32的默認項目,當然為了調試方便,我們需要對一些設置進行更改
選中項目的屬性,選擇配置屬性->鏈接器->系統->子系統,選擇控制台
這樣做的目的是為了方便我們可以直接利用cout輸出調試信息
2.進行設置,方便調試
設置完成后編譯會無法通過,因為WIN32項目默認main函數跟C++的main函數不一樣,所以我們需要對main函數進行改造,將函數原型改成C++的默認形式后,通過GetModuleHandle獲得本進程的hInstance,就可以了
接下來我們在Windows的消息處理函數里面增加處理KEYBOARD的代碼:
case WM_KEYDOWN: printf("按下按鍵\n"); break;
接下來只要在程序開頭調用我們的函數:
LRESULT CALLBACK KeyboardProc(int nCodec,WPARAM wParam,LPARAM lParam) { cout<<"截取到鍵盤消息"<<endl; return 1; //return CallNextHookEx(hkb,nCodec,wParam,lParam); } void SetHook(HINSTANCE hMoudle) { hkb = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)KeyboardProc, hMoudle, 0); }
在程序調用SetHook后,就能攔截到我們進程的鍵盤消息
對於截取本進程的消息,代碼並不復雜,10+行的代碼就能攔截本進程的鍵盤消息,消息類型很多種,還有DEBUG消息,MOUSE消息等,都可以進行攔截