解决方案 »

  1.   

    1.SetWindowsHookEx的最后一个参数要求是线程ID,即目标窗口所在的UI线程的ID,不是进程ID,也不是窗口句柄,一般是目标进程的主线程ID才行。
    2.SetWindowsHookEx的返回值如何,有没有调用成功。
    3.你的操作系统是多少位的?如果是64位的,默认记事本、计算器等都是64位的,你编写的32位DLL无法注入到64位进程,所以挂钩失败。
    4.你是如何判断记事本没有调用CallWndProc的?是直接打断点调试,还是在CallWndProc里写了一句MessageBox,运行后没有发现弹出MessageBox?
    5.你的CallWndProc是怎么写的,有没有调用CallNextHookEx?
      

  2.   


    1. 不好意思,我上面写错了,我是传的线程id,不是句柄。线程ID是通过GetWindowThreadProcessId这个函数获取的。
    2.SetWindowsHookEx可以返回的句柄,用getlasterror函数查看也没有错误。
    3.我操作系统是32为的
    4.我是勾计算器,不是记事本,判断是否调用CallWndProc是打断点的。MessageBox也试过,也是一样的效果。
    5.CallWndProc里面有调用CallNextHookEx。下面是我的CallWndProc函数。
    LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)   
    {
       if(0 <= nCode)
    {
    CWPSTRUCT* sMesg = (CWPSTRUCT*)lParam;
    //MessageBox(g_hWnd_this,_T("nCode"), _T("CallWndProc"), MB_OK); //hwnd表示消息所属的窗口
    if(g_hWnd_window == sMesg->hwnd)
    {
    //MessageBox(g_hWnd_this,_T("hwnd"), _T("CallWndProc"), MB_OK); switch(sMesg->message)
                        。 
                 } 
              }
    return CallNextHookEx(g_hHook, nCode, wParam, lParam);
    }
      

  3.   

    你把整个工程文件夹传上来看看吧,(工程文件夹内的.sdf文件和两个Debug文件夹以及两个Release文件夹可以删掉以减小体积),
    可以打包成rar传到网盘(如百度云盘)上,然后在这里贴链接。
      

  4.   


    传到百度云盘了,以下是链接。
    http://pan.baidu.com/s/1pJ9L8vT
      

  5.   

    我这里WIN7 32位上测试你的代码是可以对计算器成功挂钩的,并且CallWndProc里写MessageBox,也能在计算器上弹出MessageBox,
    你在其它电脑上试试,也许是你电脑上有360之类的安全软件给阻止了。另外调用挂钩函数挂钩成功以后,可以用VisualStudio的“调试”-“附加到进程”,选择计算器的进程,附加到计算器进程上进行调试,这样就可以在“模块”窗口查看计算器进程有没有把你的dll加载进来。
      

  6.   


    不好意思,可能是我加载的测试方法不对。
    按照你说的,我先把dll attach到计算器,但是在运行加载时,会提示计算器的进程没有debug情报,是否继续。我选择继续,这时候可以打开计算器。
    然后我再用我的调式程序去LoadLibrary我的这个dll,并且调用StartCallWndProc函数,去进行挂载,并且把计算器的句柄传进去。
    但是这样之后,操作计算器,计算器还是反应,也没有messagebox显示。我的加载方法估计是有问题,能帮忙告诉下你具体是怎么加载的吗。
      

  7.   


    void CTestCallDlg::SetHookForCalculator()
    {
    HWND hCalcWnd = ::FindWindow(L"CalcFrame", L"计算器");
    if (!hCalcWnd)
    return;
    BOOL (__stdcall *StartCallWndProc)(HWND, HWND);
    HMODULE hModule = ::LoadLibrary(L"MessageDll.dll");
    StartCallWndProc = (BOOL (__stdcall*)(HWND,HWND))::GetProcAddress(hModule, "StartCallWndProc");
    if (!StartCallWndProc)
    return;
    StartCallWndProc(GetSafeHwnd(), hCalcWnd);
    }我只是用MFC程序简单的调用了一下你DLL导出的StartCallWndProc函数,并传入计算器的窗口句柄
      

  8.   


    我的跟你的一样,但是我在收到CallWndProc消息之后,去判断消息是不是传给计算器的时候,也就是这样的判断if(hCalcWnd == sMesg->hwnd)始终是false。
    我在想,是不是hCalcWnd这个主窗口不接收消息。只有子窗口接受消息。但是我之前也试过,把message的句柄根计算器的子窗口句柄比较,也是false。不知道为什么。
      

  9.   


    原因找到了,原来这种方法调式的话,我用我的MFC调用DLL传进去的串口句柄会被无效。
    所以句柄判断一直是失败的。
    谢谢了,一直帮忙在看。