钩子,全局钩子

简单说一下钩子的做法,这里用截获拷屏键做例子。

这个是钩子的回调函数声明
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放在这个段里。

不放在这里,当你的程序处于前台时,钩子会起作用,不在前台就不起作用,而放在这里,无论在不在前台都会起作用。

还有一个问题,我运行两遍这个程序,当第二个钩子下了以后,我把第一个运行起来的程序关掉,这个时候无论是不是全局的,钩子都被卸载了,在第二个程序里就可以肆无忌惮了。

要想解决这个问题,我试了半天,只有一个办法,钩子退出的时候不卸载,这样只有当所有进程都退出后钩子才会被自动卸载,不知道这样会不会有内存泄露,谁有更好的方法请告诉我。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章