已经有一个DLL和它的接口,这个DLL会自动对指定的一个窗体发送信息,想新建一个DLL将这个DLL封装起来,当已有的DLL向指定的窗体发送消息时,新建的DLL先获取这个消息,由新的DLL做一些处理后,再由新的DLL发送到指定的窗体。
    已有的DLL中的指定接收消息的窗体接口是SetAppHWnd(HWND hAppWnd)
    定义一个自定义消息名称:#define  WM_RECEIVEDATA WM_USER + 942
    当调用SetAppHWnd函数指定了接收消息的窗体后,已有的DLL会自动将自定义消息WM_RECEIVEDATA发送给接收消息的窗体。现在想做的就是,新建一个DLL用来封装已有的DLL,所有的接口与已有的DLL一样,就是想在已有的DLL发WM_RECEIVEDATA消息时,新建的DLL先获取这个消息并将对应这个消息的数据做一些处理后再将处理后的消息发送至指定的窗体。
    目前的想法有两种:
    1 在新建的DLL中使用钩子函数拦截WM_RECEIVEDATA消息,将数据进行处理后,通过新建的DLL的接口SetAppHWndEx(HWND hAppWnd)将WM_RECEIVEDATA消息发送至指定的窗体。
    2 由于可以指定接收消息的窗体,可以在新建的DLL中创建一个新的空窗体,使用已有的DLL中的SetAppHWnd(HWND hAppWnd)函数先将WM_RECEIVEDATA消息发送这个新的空窗体,经过处理后再将WM_RECEIVEDATA消息通过新建的DLL的SetAppHWndEx(HWND hAppWnd)函数发送至指定的窗体。
    两种方式哪一种好,由于可以指定接收消息的窗体,是不是还有其他的方法可以实现这样的功能。
    因为对DLL的消息处理不了解,希望在解答上面能详细一些。谢谢。

解决方案 »

  1.   

    就是拦截指定窗口的消息啊,貌似用SetWindowLongPtr就可以了。或者SetWindowsHookEx也可以。
      

  2.   

    已经基本上搞定了,做法是在DLL中创建一个对话框,通过自定义的SetAppHWndEx将消息发送至DLL中新建的对话框,然后在该对话框内的消息循环DefWindowProc中对接收的消息进行处理,处理完成通过SendMessage将消息发送至以前接收消息的窗体。具体做法如下:
    1 先在资源文件中新建一个对话框,ID随便取名,我取名为IDD_DLGTEMP。
    2 通过该资源生成一个对话框类。选择菜单中的插入->类,将对话框ID与类绑定。
    class DlgTemp : public CDialog
    {
       .......
    }
    3 在DlgTemp中声明一个变量以用来保存以前接收消息的窗体名柄
    HWND m_hAppWnd;
    4 在XXX.h(XXX即为你创建的DLL名称)中声明一个该对话框的指针
    DlgTemp         *m_pTempDlg;
    5 在XXX.cpp中的InitInstance()函数添加以下代码:
    m_pTempDlg = new DlgTemp();
    if(m_pTempDlg != NULL)
    {
        BOOL ret = m_pTempDlg->Create(IDD_DLGTEMP, NULL);    if(!ret)   //Create failed.
           AfxMessageBox(_T("Error creating Dialog"));    m_pTempDlg->ShowWindow(SW_HIDE);//隐藏该对话框
    }
    else
    {
        AfxMessageBox(_T("Error Creating Dialog Object"));
    }
    6 自定义的SetAppHWndEx中添加以下代码:
    theApp.m_pTempDlg->m_hAppWnd = hAppWnd;
    SetAppHWnd(theApp.m_pTempDlg->GetSafeHwnd());
    其中hAppWnd即为以前接受消息的窗体的句柄。
    theApp.m_pTempDlg->GetSafeHwnd()即为DLL中新建的对话框的句柄
    由于以前的DLL中SetAppHWnd可以设定接受消息窗体的句柄,所以在新的DLL中将此句柄设为新建对话框的句柄。
    7 添加新建对话框的消息循环
    LRESULT DlgTemp::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
    {
    ......
    }
    在此消息循环中添加以下代码:
    switch(message)
    {
       case WM_RECEIVEDATA:
       {
            if(......)//满足可以发送到以前窗体的条件
                 ::SendMessage(m_hAppWnd, WM_RECEIVEDATA, wParam, lParam);
                 //hAppWnd即为保存的以前接受消息的窗体句柄
            else
                 return CDialog::DefWindowProc(message, wParam, lParam);
            break;
       }
       .....
       default:
    return CDialog::DefWindowProc(message, wParam, lParam);}功能基本已经实现,不过细节部份还是调试