代码如下:
#pragma data_seg("Shared")
HHOOK g_lhHook=NULL;
HINSTANCE          g_lhInstance=NULL;
#pragma data_seg()
#pragma comment(linker,"/SECTION:Shared,RWS")extern "C" __declspec (dllexport) BOOL HookStart();
extern "C" __declspec (dllexport) BOOL HookStop();BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
//如果使用lpReserved参数则删除下面这行
UNREFERENCED_PARAMETER(lpReserved);  switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH://在DLL加载时对全局变量赋值
g_lhInstance = (HINSTANCE)hModule;
break;
case DLL_PROCESS_DETACH:
g_lhInstance = NULL;
break;
default:
break;
}    return TRUE;
}//钩子的过滤函数
LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
{
LPMOUSEHOOKSTRUCT pMouseHook=NULL; pMouseHook=(MOUSEHOOKSTRUCT FAR *)lParam; return::CallNextHookEx(g_lhHook,nCode,wParam,lParam);
}//安装钩子
BOOL HookStart()

HWND hWnd = NULL;
DWORD dwThreadId = 0; hWnd = FindWindow(NULL,"Test");
dwThreadId = GetWindowThreadProcessId(hWnd,NULL); g_lhHook = SetWindowsHookEx(WH_MOUSE,
MouseProc,
g_lhInstance,
dwThreadId
);

return (g_lhHook!=NULL);
}//卸载钩子
BOOL HookStop()
{
BOOL ret; if(g_lhHook!=NULL)
{
ret=::UnhookWindowsHookEx(g_lhHook);
g_lhHook=NULL;
} return ret;
}
安装钩子的函数HookStart()已经被EXE文件成功调用?可回调函数里没任何消息可以捕捉到,哪儿错了呢?谢谢高手指点.

解决方案 »

  1.   

    呵呵 老大,<<钩子函数的反拦截>>帖子看了吗?俺是按照他说的做的啊!给个建议好吗?
      

  2.   

    SetWindowsHookEx(WH_MOUSE, MouseProc,g_lhInstance,dwThreadId);dwThreadId 要设置成 0 ,才能实现全局钩子。
      

  3.   

    听说钩子有本地和远程之分,我是想定义个一个远程的.用来钩其他进程的鼠标或键盘消息啊.dwThreadId 应该为所钩的那个线程的ID,这样对嘛?
      

  4.   

    要么像busade1() 说的那样使用全局钩子,要么把DLL注入目标进程中,使用线程钩子。
    注入的方法搜索一下,很多人问过的。
      

  5.   

    把dwThreadId设置成0是全局钩子,系统会把它注入到所有进程中。如果要使用线程钩子只对某个线程有效,回调函数应该与目标线程处在同一个进程内。
      

  6.   

    的确 把 dwThreadId 设成 所要插入的线程的id,但是如果哪个线程没有WH_MOUSE 当然就不会有效果阿。
      

  7.   

    大家可能没搞清楚吧,还是我不懂,现在详细如下:
    1 首先定义一个DLL,就是上面贴的代码;
    2 创建一个进程,在该进程内调用DLL的导出函数HookStart(),安装钩子;
    3 被钩的另一个进程为C,其主线程的ID已经在DLL中获得:
             hWnd = FindWindow(NULL,"Test");
    dwThreadId = GetWindowThreadProcessId(hWnd,NULL);
      并传给了SetWindowsHookEx()这个函数,这样的方法正确嘛?看了一下WINDOWS核心编程,好像就是这样说的,还有http://community.csdn.net/Expert/topic/3507/3507600.xml?temp=.7010157这个帖子也是这样说的,可以说就是它的翻版.老大,是我理解错了,还是你们????
      

  8.   

    以下是我的测试代码,没问题,能收到消息
    LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)
    {
    LPMOUSEHOOKSTRUCT pMouseHook=NULL; if (nCode == HC_ACTION && wParam == WM_LBUTTONDOWN)
    {
    AfxMessageBox("aaa");
    }
    pMouseHook=(MOUSEHOOKSTRUCT FAR *)lParam; return::CallNextHookEx(g_hMouseHook,nCode,wParam,lParam);
    }BOOL _declspec(dllexport) InstallMouseHook()
    {
        if(g_fIsInstalled) return FALSE;
        HWND hWnd = ::FindWindowEx(NULL, NULL,"Notepad", NULL);
        DWORD id = GetWindowThreadProcessId(hWnd, NULL);
        g_hMouseHook = ::SetWindowsHookEx(WH_MOUSE,(HOOKPROC)MouseProc, g_hInstances, id);
        if(g_hMouseHook==NULL)
            AfxMessageBox("安装钩子错误!",MB_OK,0);
        g_fIsInstalled = TRUE;
        return TRUE;
    }
      

  9.   

    搂上的,不要意思,问一下你的Notepad是怎样创建的呢?我用MFC创建一个基于对话框的应用程序,其标题为TEST,然后
             HWND hWnd = NULL;
    DWORD dwThreadId = 0; hWnd = FindWindow(NULL,"TEST");
    dwThreadId = GetWindowThreadProcessId(hWnd,NULL); g_lhHook = SetWindowsHookEx(WH_MOUSE,
    MouseProc,
    g_lhInstance,
    dwThreadId
    );

    return (g_lhHook!=NULL);
    也成功了,我想钩着TEST的鼠标消息,请问还要做其他工作嘛?非常谢谢你,分不够可以再加啊.:):)
      

  10.   

    代码发给我:[email protected]
    我帮你看看Notepad是系统的记事本程序的类名
      

  11.   

    我看了你的程序,其实你的钩子已经起到作用了,只是在IDE调试环境下,没能到达断点罢了。你可以在LRESULT CALLBACK MouseProc(int nCode,WPARAM wParam,LPARAM lParam)函数中添加输入信息到日志文件或者用MessageBox()提示信息等方式来测试一下。
    拦截别的程序消息的钩子,除了是全局的可以直接调试以外,其他的好象不能直接调试。被调试的程序应该是由IDE环境加载的才能完全由IDE来控制,Test程序是你单独开启的进程,IDE无法得到这个进程里的信息或消息,所以无法调试(这只是个人认为,如果哪位高手能直接调试,告诉一下方法)
      

  12.   

    大家可以调试 调用dll的主程序啊,  就是那个 test.exe啊, 这样就能知道 hook的情况了
      

  13.   

    test.exe并没有调用dll,只是用来被hook的
      

  14.   

    我没有源程序,不过哪个exe文件调用dll,就可以调试哪个exe文件阿,因为它也会被hook的
      

  15.   

    楼主做的是A程序调用DLL,设置钩子,对B程序进行消息拦截。用的不是全局钩子。所以在A程序里面是拦截不到消息的。而B程序又是单独开启的一个进程,跟IDE没有任何关系。
      

  16.   

    是的 :) 调试时,如果截获了B程序的消息,如何能让DLL中的断点断住呢?
      

  17.   

    推荐 一个程序 PrcView,可以看见进程的模块,这样可以知道b有没有被hook阿