外掛心得 – 全域鉤子

來源:互聯網
上載者:User
最初,我採用SendMessage WM_SETHOTKEY的方法,來實現在遊戲中呼出外掛並啟用。
這種做法確實簡單(僅僅一個標準控制項加幾行代碼),但存在非常大的弊端:
1 使用Hotkey呼出外掛將導致外掛視窗被強行帶到前端,此時遊戲視窗被最小化,非常麻煩而且遊戲人物很危險。
註:WM_HOTKEY與WM_SETHOTKEY不是同一個事件,對於後者,MSDN說:
An application sends a WM_SETHOTKEY message to a window to associate a hot key with the window. When the user presses the hot key, the system activates the window.
可見這個問題基本上無解。
2 對於一個視窗來說,Hotkey只能有一個,而我們需要 挖礦開關,開啟外掛功能,關閉外掛功能 三個熱鍵。

=====================

怎麼辦?當然我一下就想到了大家耳熟能詳的名詞--鉤子。
雖然鉤子這個名詞我非常熟悉,可是真正自己編寫一個鉤子程式,那還是第一次。沒什麼,承認自己的不足是進步的第一步,下次不就知道了嗎?
OK! 查資料,得到這樣的描述:

Windows系統是建立在事件驅動的機制上的,說穿了就是整個系統都是通過訊息的傳遞來實現的。而鉤子是Windows系統中非常重要的系統介面,用它可以截獲並處理送給其他應用程式的訊息,來完成普通應用程式難以實現的功能。鉤子的種類很多,每種鉤子可以截獲並處理相應的訊息,如鍵盤鉤子可以截獲鍵盤訊息,外殼鉤子可以截取、啟動和關閉應用程式的訊息等。
鉤子實際上是一個處理訊息的程式段,通過系統調用,把它掛入系統。每當特定的訊息發出,在沒有到達目的視窗前,鉤子程式就先捕獲該訊息,亦即鉤子函數先得到控制權。這時鉤子函數即可以加工處理(改變)該訊息,也可以不作處理而繼續傳遞該訊息,還可以強制結束訊息的傳遞。對每種類型的鉤子由系統來維護一個鉤子鏈,最近安裝的鉤子放在鏈的開始,而最先安裝的鉤子放在最後,也就是後加入的先獲得控制權。要實現Win32的系統鉤子,必須調用SDK中的API函數SetWindowsHookEx來安裝這個鉤子函數,這個函數的原型是
HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId);
其中,第一個參數是鉤子的類型;第二個參數是鉤子函數的地址;第三個參數是包含鉤子函數的模組控制代碼;第四個參數指定監視的線程。如果指定確定的線程,即為線程專用鉤子;如果指定為空白,即為全域鉤子。其中,全域鉤子函數必須包含在DLL(動態連結程式庫)中,而線程專用鉤子還可以包含在可執行檔中。得到控制權的鉤子函數在完成對訊息的處理後,如果想要該訊息繼續傳遞,那麼它必須調用另外一個SDK中的API函數CallNextHookEx來傳遞它。鉤子函數也可以通過直接返回TRUE來丟棄該訊息,並阻止該訊息的傳遞。

==========================

看起來線程鉤子比較簡單,於是我選擇實現它。
在程式中添加
m_hHook = SetWindowsHookEx( WH_KEYBOARD, KeyboardProc, NULL, PID );
其中PID是這個網路遊戲的進程號。
看上去很好,可是實際測試無法工作,一檢查,原來這裡m_hHook返回NULL,根本就沒成功。。。
再翻MSDN:
The hMod parameter(就是參數三) must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
原來線程鉤子必須是當前進程(也就是外掛本身)建立的,不能用線程鉤子去鉤其他進程!汗!

========================

沒辦法,必須做一個全域鉤子
建一個DLL工程,匯出DLL和LIB;
然後在外掛中引用它。
核心代碼:
在DLL中:
BOOL CKeyboardHook::StartHook()
{
BOOL bResult=FALSE;
glhHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,glhInstance,0);
if(glhHook!=NULL)
bResult=TRUE;
return bResult;
}
在外掛中:
CKeyboardHook m_hook;
m_hook.StartHook();

================================

搞定了?沒有!
欲知後事如何,請看:
外掛心得 - DLL共用資料

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.