本帖最后由 kongling12 于 2010-09-10 23:47:47 编辑

解决方案 »

  1.   

    hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc, NULL, GetCurrentThreadId());
      

  2.   

    您好,仍然没有用....贴上测试代码LRESULT CALLBACK KeyProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
    MessageBoxA(NULL, "1","1", MB_OK);
    return ::CallNextHookEx(hOk, nCode, wParam, lParam);
    }
    void CAsaApp::InstallHook()
    {

    hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc, NULL, GetCurrentThreadId());
    if (hOk == NULL)   //因为没有传进参数 这能这样得到进程的线程,但是失败,如果吧最后的参数改成0,则hook失败
    {
    MessageBoxA(NULL, "hook is false", "!!", MB_OK);
    return;
    }
    else
    {
    MessageBoxA(NULL, "hook is success", "!!", MB_OK);
    return;
    }
    }
      

  3.   

    hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc, NULL, GetCurrentThreadId());
    这样安装的话,钩子究竟是安装不成功还是没有效果?如果是没有效果的话,那说明那个软件的界面部分与加载你的DLL的那段代码不在同一个线程,因此GetCurrentThreadId没有获得界面线程的ID。
    如果你能获得那个软件的窗口句柄(你打算在哪个窗口里响应Ctrl+F5,你就用哪个窗口的句柄),那么你可以通过GetWindowThreadProcessId来获取它的线程ID。
      

  4.   

    GetCurrentThreadId()得到的是当前的线程ID,这个和你要钩的线程是不是一个线程啊?
      

  5.   


    void CAsaApp::InstallHook()
    {
    HWND hnotpd = FindWindow("Notepad","qw.txt - 记事本");
    if (hnotpd == NULL)
    {
    MessageBoxA(NULL, "hnotpd is null", "!!", MB_OK);
    return;
    }
    DWORD dwId;
    GetWindowThreadProcessId(hnotpd, &dwId);
    if (dwId == NULL)
    {
    MessageBoxA(NULL, "dwId is null", "!!", MB_OK);
    return;
    }
    hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc,theApp.m_hInstance, dwId);
    if (hOk == NULL)  //这里总是提示hOk=NULL
    {
    MessageBoxA(NULL, "hook is false", "!!", MB_OK);
    return;
    }
    else
    {
    MessageBoxA(NULL, "hook is success", "!!", MB_OK);
    return;
    }
    }
      

  6.   


    现在改成这样可以hook成功但是 没有效果void CAsaApp::InstallHook()
    {
    HWND hnotpd = FindWindow("Notepad","qw.txt - 记事本");
    if (hnotpd == NULL)
    {
    MessageBoxA(NULL, "hnotpd is null", "!!", MB_OK);
    return;
    }
    DWORD dwId,dwThreadId;
    dwThreadId = GetWindowThreadProcessId(hnotpd, &dwId);
    if (dwId == NULL)
    {
    MessageBoxA(NULL, "dwId is null", "!!", MB_OK);
    return;
    }
    hOk = ::SetWindowsHookEx(WH_KEYBOARD, KeyProc,theApp.m_hInstance, dwThreadId);
    if (hOk == NULL)
    {
    MessageBoxA(NULL, "hook is false", "!!", MB_OK);
    return;
    }
    else
    {
    MessageBoxA(NULL, "hook is success", "!!", MB_OK);
    return;
    }
    }
      

  7.   

    把钩子写在当前模块中的方法仅适合于在本进程内部安装钩子。此时SetWindowsHookEx的第三个参数必须是NULL,而第四个参数则是想要安装钩子的线程(必须是本进程内的线程)。
    如果要钩其它进程(比如记事本)中的消息,你的钩子必须写在一个独立的DLL文件中,并且安装钩子的时候,必须用LoadLibrary所返回的hModule作为SetWindowsHookEx的第三个参数,GetProcAddress所返回的值作为第二个参数,然后第四个参数设为0。例如:
    HOOKPROC hkprcSysMsg; 
    static HINSTANCE hinstDLL; 
    static HHOOK hhookSysMsg; 
     
    hinstDLL = LoadLibrary((LPCTSTR) "c:\\windows\\sysmsg.dll"); 
    hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "SysMessageProc"); 
    hhookSysMsg = SetWindowsHookEx(WH_SYSMSGFILTER,hkprcSysMsg,hinstDLL,0); 
      

  8.   


    theApp.m_hInstance传的不对吧,这时你应该传的是DLL模块句柄的,可以用GetModuleHandle获取还有,你是跨进程操作吗,如果跨进程,最好用:
    hOk = SetWindowsHookEx(WH_KEYBOARD_LL,KeyProc,GetModuleHandle(TEXT("kbFilter")),0);另外,在KeyProc中别忘了用CallNextHookEx回调hOK。
    一般都是可以的
      

  9.   

    如果是本进程的话。没有必要使用hook,PreTranslateMsg就可以