做一个进程HOOK的练习,用MFC扩展DLL来实现。具体操作:在DLL中增加一个对话框资源,根据对话框ID生成一个类,在HOOK的键盘回调函数中显示出来,现在HOOK已经安装成功了,可以在回调函数中用MessageBox,可是显示对话框后引起进程崩溃,高手给指点一下,问题出在哪里?
LRESULT CALLBACK KeyboardProc(int code,WPARAM wParam,LPARAM lParam)
{
//拦截空格,显示对话框
HWND hwnd=GetForegroundWindow();
char buf[100];
::GetWindowText (hwnd,buf,100);
strcat(buf,"测试");
if (!(lParam & 0xA0000000)) //相应一次
if (VK_SPACE==wParam)
{

//if (IDYES==MessageBox(hwnd,"钩子1",buf,MB_YESNO))
// other(hwnd); //AFX_MANAGE_STATE(AfxGetAppModuleState());
HINSTANCE save_hInstance = AfxGetResourceHandle(); //保存资源
HMODULE hDll=GetModuleHandle("dllmenu.dll");  //用Dll资源
if (NULL==hDll)
{
MessageBox(hwnd,"GetModuleHandle失败",buf,MB_YESNO);
return 0;
}
else
MessageBox(hwnd,"GetModuleHandle成功",buf,MB_YESNO); AfxSetResourceHandle(hDll); //用Dll资源


CD1 dlg;
dlg.DoModal();  //这里出问题

AfxSetResourceHandle(save_hInstance);  //恢复资源 }
return 0;
}
程序具体执行过程:按空格后执行“MessageBox(hwnd,"GetModuleHandle成功",buf,MB_YESNO);”然后能弹出CD1类对话框,然后进程崩溃,请指点一下

解决方案 »

  1.   


    AFX_MANAGE_STATE(AfxGetStaticModuleState());CD1 dlg;前面加上这句试试看呢..
      

  2.   

    楼主试试用多线程吧
    把CD1 dlg; 
    dlg.DoModal();  换成CWinThread *pDlgThread = ::AfxBeginThread(RUNTIME_CLASS(CD1));
    ::WaitForSingleObject(pDlgThread->m_hThread, -1);
      

  3.   

    试试下面的::AfxLockTempMaps();
    CD1 dlg; 
    dlg.DoModal(); 
    ::AfxUnlockTempMaps(TRUE);
      

  4.   


    我用C#调用MFC扩展dll,在CD dlg前面加一句AFX_MANAGE_STATE(AfxGetStaticModuleState()); 提示出错。mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in OAClient.obj
    mfcs42d.lib(dllmodul.obj) : error LNK2005: _DllMain@12 already defined in OAClient.obj
    mfcs42d.lib(dllmodul.obj) : error LNK2005: __pRawDllMain already defined in OAClient.obj有没有解决办法呢?
      

  5.   

    To marquess:
    在MFC扩展DLL中需要将AFX_MANAGE_STATE(AfxGetStaticModuleState())换成AFX_MANAGE_STATE(AfxGetAppModuleState())。To 楼主:
    我怀疑是资源句柄的问题。dll中domodal一个窗口,在这个窗口显示的时候,资源句柄就一直是dll的,
    这是如果其他模块(比如主模块)要用到其资源,那就要出错了。一般dll都用非模式窗口,这样就不会有类似问题。
    如果非要用模式窗口,那么domodal之前不要设置资源句柄,
    但这必须保证domodal的这个窗口的资源ID是全局唯一的,也就是说在其他模块里也不会用到。
      

  6.   

    既然是扩展DLL,我觉得你在app中增加dllmenu.lib,然后直接用不就好了么。//AFX_MANAGE_STATE(AfxGetAppModuleState()); 
    HINSTANCE save_hInstance = AfxGetResourceHandle(); //保存资源 
    HMODULE hDll=GetModuleHandle("dllmenu.dll");  //用Dll资源 
    if (NULL==hDll) 

    MessageBox(hwnd,"GetModuleHandle失败",buf,MB_YESNO); 
    return 0; 

    else 
    MessageBox(hwnd,"GetModuleHandle成功",buf,MB_YESNO); AfxSetResourceHandle(hDll); //用Dll资源 

    CD1 dlg; 
    dlg.DoModal();  //这里出问题 
    AfxSetResourceHandle(save_hInstance);  //恢复资源