鉤子,全局鉤子

簡單說一下鉤子的做法,這裏用截獲拷屏鍵做例子。

這個是鉤子的回調函數聲明
LRESULT CALLBACK HookProcKeyboard(int nCode, WPARAM wParam, LPARAM lParam);

在初始化的時候下鉤子
g_hHookKB = ::SetWindowsHookEx(WH_KEYBOARD, HookProcKeyboard, theDll.m_hInstance, 0);

退出的時候卸載鉤子
::UnhookWindowsHookEx(g_hHookKB);

鉤子回調函數
LRESULT CALLBACK HookProcKeyboard(int nCode, WPARAM wParam, LPARAM lParam)
{
    CString s;
    s.Format("%d-%d-%d", nCode, (DWORD)wParam, (DWORD)lParam);
    AfxMessageBox(s);

    if (nCode == HC_ACTION && wParam == VK_SNAPSHOT)
    {

        if (g_hHookKB != NULL && g_nNumOfNeedClear > 0)
        {
            ::OpenClipboard(NULL);
            ::EmptyClipboard();
            ::CloseClipboard();
        }
   
        return 0;
    }
    return ::CallNextHookEx(g_hHookKB, nCode, wParam, lParam);
}

Ok了,這就是個最簡單的鉤子。

那什麼是鉤子什麼是全局鉤子?普通鉤子又叫線程鉤子,只針對某一線程,而全局鉤子針對整個系統,這個例子就是個全局鉤子,不過還要加下面幾句:
#pragma data_seg(".PrtSc")

HHOOK g_hHookKB = NULL;

#pragma data_seg()
#pragma comment(linker, "/SECTION:.PrtSc,RWS")

設置一個數據段PrtSc,把這個段設爲共享的,g_hHookKB放在這個段裏。

不放在這裏,當你的程序處於前臺時,鉤子會起作用,不在前臺就不起作用,而放在這裏,無論在不在前臺都會起作用。

還有一個問題,我運行兩遍這個程序,當第二個鉤子下了以後,我把第一個運行起來的程序關掉,這個時候無論是不是全局的,鉤子都被卸載了,在第二個程序裏就可以肆無忌憚了。

要想解決這個問題,我試了半天,只有一個辦法,鉤子退出的時候不卸載,這樣只有當所有進程都退出後鉤子纔會被自動卸載,不知道這樣會不會有內存泄露,誰有更好的方法請告訴我。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章