有一个工程,是静态链接到MFC的DLL  ,它有3个全局变量,我是准备把他注入到别的进程中的
我想让这个DLL有界面,于是在这个DLL种插入了一个对话框资源,并创建了一个类。这个对话框类和DLL的文件处在同一个工程中。
结果一编译就说3个全局变量重定义,,,这是怎么回事啊请问,我注入一个进程,然后热键在进程中弹出DLL的界面,,应该怎么设计啊

解决方案 »

  1.   

    全局变量,在cpp文件中定义,然后在h文件中extern。
      

  2.   


    编译通过了但是在被注入的进程中呼出对话框窗口的时候,被注入的进程直接崩了。。dll全局变量声明代码 cpp中
    HINSTANCE   hHookDllXueL            = NULL ;      //dll实例  
    HHOOK         hhookXueL               = NULL ;      //钩子句柄
    CXLDLLDlg     g_xldlldlg ;                          //控制对话框cxldlldlg即是上文中的DLL中插入的对话框类...相关测试代码LRESULT  WINAPI HookFun(  int nCode, WPARAM wParam,LPARAM lParam )
    {
        if ((DWORD)wParam == VK_HOME)
        {
            g_xldlldlg.ShowWindow(SW_SHOW);
        }
        return CallNextHookEx(hhookXueL,nCode,wParam,lParam);
    }
    可以问下咋子回事么分马上送上帮帮忙撒 老大
      

  3.   

    恩,跟资源有关系。别的模块如果要使用dll中的资源,需要先调用AfxSetResourceHandle(hDll);譬如,你在别的程序中CreateDialog
    你需要hRes = AfxGetResourceHandle();
    AfxSetResourceHandle(hDll);
    ...这儿创建你的对话框
    AfxSetResourceHandle(hRes);//
      

  4.   

    have a try,,,wait for a moment..
      

  5.   

    晕,你的dlg没有Create,不能使用。LRESULT  WINAPI HookFun(  int nCode, WPARAM wParam,LPARAM lParam )
    {
        if ((DWORD)wParam == VK_HOME)
        {
            hRes = AfxGetResourceHandle();
            AfxSetRessourceHandler(hDll);
            if (g_xldlldlg.GetSafeHwnd() == NULL)
                g_xldlldlg.Create(你的对话框id);
            g_xldlldlg.ShowWindow(SW_SHOW);
            AfxSetResourceHandle(hRes);
        }
        return CallNextHookEx(hhookXueL,nCode,wParam,lParam);
    }
      

  6.   

    牛哥,你的意思是,我每次按下home键都要重新创建么?
      

  7.   

    这不有判断吗,如果句柄为空,说明窗口没创建,这个时候才创建。
    if (g_xldlldlg.GetSafeHwnd()== NULL)
      

  8.   

    改后的代码如下,不过对话框不是居中显示的,有点奇怪。。我弄了个public变量来监视一下
    LRESULT  WINAPI HookFun(  int nCode, WPARAM wParam,LPARAM lParam )
    {
        if ((DWORD)wParam == VK_HOME)
        {        HINSTANCE   hOldResHandle=AfxGetResourceHandle();   
            HINSTANCE   hInst   =   ::GetModuleHandle(_T("XueLD.dll"));   
       
            AfxSetResourceHandle(hInst);         if (g_xldlldlg.GetSafeHwnd()== NULL) 
            {
              
                g_xldlldlg.Create(IDD_DLG_XUELD_DLG); 
                g_xldlldlg.hello ++;
            }
            CString cstr = _T("");
            cstr.Format(_T("%d"),g_xldlldlg.hello);
            g_xldlldlg.ShowWindow(SW_SHOW);        AfxSetResourceHandle(hOldResHandle); 
        }
        return CallNextHookEx(hhookXueL,nCode,wParam,lParam);
    }
      

  9.   


    目标进程退出时报错是不是要释放资源??
    错误提示:应用程序发生异常 unknown software exception (0x80000003)位置为0x7c921208要终止程序,请单击确定
      

  10.   

    恩,关闭的时候DestoryWindow一下。
      

  11.   


    无论是先关闭发起钩子的进程还是先关闭被注入的进程,都会报错根据牛哥你的意思的话,应该是这个对话框资源没有释放但是怎么释放这个对话框资源才是合理的呢发起挂钩的进程还是被注入的进程?对话框不好接收这个通知啊。。或者这样,在DLL的对话框中添加响应函数?比如。。
      

  12.   

    是全局钩子吧,你是如何关闭钩子进程的?在卸载钩子的地方调用对话框的DestoryWindow就可以。
      

  13.   

    顺便贴一下我的卸载钩子的过程不过可能不够专业。。一起贴了。。    HINSTANCE  m_hookDll = ::LoadLibrary(_T("XueLD.dll"));
        HOOKSET    m_pSet;
        HOOKUNSET  m_pUnSet;
        if (NULL != m_hookDll)
        {
            m_pSet   = (HOOKSET)GetProcAddress(m_hookDll,"SetHook");
            m_pUnSet = (HOOKUNSET)GetProcAddress(m_hookDll,"UnSetHook"); 
            if (!m_pSet || !m_pUnSet)
            {
                AfxMessageBox(_T("look for function error!"));
                return ;
            }
        }
        else
        {
            AfxMessageBox(_T("Load DLL failed"));
            return ;
        }
         for (DWORD i = 0 ;  i < m_vecHHookInfo.size() ;i++)
        {
            //卸载钩子
            SuspendThread(m_vecProcessInfo[i].hThread);
            (*m_pUnSet)(m_vecHHookInfo[i]);
            ResumeThread(m_vecProcessInfo[i].hThread);
        }
        FreeLibrary(m_hookDll);
      

  14.   

    你这里不是有卸载钩子的程序吗?在UnSetHook中进行处理就可以。
      

  15.   


    直接调用g_xldlldlg.DestroyWindow()还是崩有点头晕了看来这个资源不太好释放 HOOK_API BOOL UnSetHook(HHOOK hHook)
    {
        AFX_MANAGE_STATE(AfxGetStaticModuleState());    if (!hHook)
        {
            return false;
        }    HINSTANCE   hOldResHandle=AfxGetResourceHandle();   
        HINSTANCE   hInst   =   ::GetModuleHandle(_T("XueLD.dll"));   
        g_xldlldlg.DestroyWindow();
        AfxSetResourceHandle(hInst); 
        AfxSetResourceHandle(hOldResHandle);     return UnhookWindowsHookEx(hHook);
    }
    头晕了
      

  16.   

    钩子类型为:键盘钩子&线程钩子
    HOOK_API BOOL UnSetHook(HHOOK hHook)
    {
        AFX_MANAGE_STATE(AfxGetStaticModuleState());    if (!hHook)
        {
            return false;
        }    HINSTANCE   hOldResHandle=AfxGetResourceHandle();   
        HINSTANCE   hInst   =   ::GetModuleHandle(_T("XueLD.dll"));   
        g_xldlldlg.DestroyWindow();
        AfxSetResourceHandle(hInst); 
        AfxSetResourceHandle(hOldResHandle);     return UnhookWindowsHookEx(hHook);
    }崩在最后一句  return UnhookWindowsHookEx(hHook);而且非常奇怪的事我调用这一句g_xldlldlg.DestroyWindow();目标进程里的窗口还在。。
      

  17.   

    HOOK_API BOOL UnSetHook(HHOOK hHook);这个是一个导出函数,实现在DLL中调用由发起钩子的进程调用的。调最后一句功能API 卸载钩子时目标进程崩掉
      

  18.   

    正常情况下,不释放资源也不会有什么问题。这个应该是别的错误,DEBUG一下吧,查看一下调用堆栈什么的。
      

  19.   

    发起进程的代码如下:void CXueLDlg::OnCancel()
    {
        // TODO: 在此添加专用代码和/或调用基类
        HINSTANCE  m_hookDll = ::LoadLibrary(_T("XueLD.dll"));
        HOOKSET    m_pSet;
        HOOKUNSET  m_pUnSet;
        if (NULL != m_hookDll)
        {
            m_pSet   = (HOOKSET)GetProcAddress(m_hookDll,"SetHook");
            m_pUnSet = (HOOKUNSET)GetProcAddress(m_hookDll,"UnSetHook"); 
            if (!m_pSet || !m_pUnSet)
            {
                AfxMessageBox(_T("look for function error!"));
                return ;
            }
        }
        else
        {
            AfxMessageBox(_T("Load DLL failed"));
            return ;
        }
         for (DWORD i = 0 ;  i < m_vecHHookInfo.size() ;i++)
        {
            //卸载钩子
            SuspendThread(m_vecProcessInfo[i].hThread);
            (*m_pUnSet)(m_vecHHookInfo[i]);
            ResumeThread(m_vecProcessInfo[i].hThread);
        }
        FreeLibrary(m_hookDll);    CDialog::OnCancel();
     }