利用WM_COPYDATA消息实现进程间通信

Posted 我来乔23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用WM_COPYDATA消息实现进程间通信相关的知识,希望对你有一定的参考价值。

  进程间通信最简单的方式就是发送WM_COPYDATA消息,下面通过例子来实现。

      发送WM_COPYDATA消息

      SendMessage(hRecvWnd,

                          WM_COPYDATA,

                          (WPARAM)hSendWnd,

                          (LPARAM)&CopyData);

       其中的CopyData为COPYDATASTRUCT结构类型,该结构定义如下:

       typedef struct tagCOPYDATASTRUCT {

             DWORD dwData;

             DWORD cbData;

             PVOID lpData;

       } COPYDATASTRUCT;

  参数:

      dwData;   // Specifies data to be passed to the receiving application.

      cbData;    //Specifies the size, in bytes, of the data pointed to by the lpData member.

      lpData;    // Pointer to data to be passed to the receiving application. can be NULL.

 

       注意:该消息只能由SendMessage()来发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。此外如果lpData指向一个带有指针或某一拥有虚函数的对象时,也要小心处理。

       如果传入的句柄不是一个有效的窗口或当接收方进程意外终止时,SendMessage()会立即返回,因此发送方在这种情况下不会陷入一个无穷的等待状态中。

 

       接收WM_COPYDATA消息

       只要用COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam; 就可以了,接收方应认为这些数据是只读的。

       由于发送方在接收方处理WM_COPYDATA消息完毕前都是处于等待中,所以接收方应当尽快处理WM_COPYDATA消息。

 

   代码实现  

//发送端:
void CSendCopyDataDlg::OnBnClickedBtnSend()
{
    CString strSendText;
    m_EditSend.GetWindowText(strSendText);
    if (strSendText.IsEmpty())
    {
        AfxMessageBox(_T("发送内容不能为空!"));
        return;
    }

    // 获取接收端窗口句柄
    HWND hWnd = ::FindWindow(NULL,_T("RecvCopyData"));
    if (hWnd == NULL)
    {
        AfxMessageBox(_T("数据接收端未启动!"));
        return;
    }

    // 发送数据
    COPYDATASTRUCT CopyData; 
    CopyData.dwData = 1;                          
    CopyData.cbData = strSendText.GetLength() * 2;   //分配足够缓冲区长度,防止接收乱码 
    CopyData.lpData = (void*)strSendText.GetBuffer();
    ::SendMessage(hWnd, WM_COPYDATA, NULL, (LPARAM)&CopyData);
    strSendText.ReleaseBuffer();
}

//接收端:
afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);

ON_WM_COPYDATA()
BOOL CRecvCopyDataDlg::OnCopyData(CWnd* pWnd, 
                                  COPYDATASTRUCT* pCopyDataStruct)
{
    //在编辑框中追加数据 
    SYSTEMTIME st;
    CString strDateTime;
    GetSystemTime(&st);
    strDateTime.Format(_T("%04d-%02d-%02d %02d:%02d:%02d.%04d   "), 
        st.wYear,
        st.wMonth,
        st.wDay,
        st.wHour,
        st.wMinute,
        st.wSecond,
        st.wMilliseconds);
    CString strRecvText = strDateTime + (LPWSTR)(pCopyDataStruct->lpData);
    m_RichEditRecv.SetSel(-1, -1);  
    m_RichEditRecv.ReplaceSel(strRecvText + _T("\\n")); 

    return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

   编译运行

 

  例子下载:http://pan.baidu.com/s/1i5n6Kex

 

 

   

以上是关于利用WM_COPYDATA消息实现进程间通信的主要内容,如果未能解决你的问题,请参考以下文章

IPC进程间通信之四数据复制消息WM_COPYDATA

转 unity进程间通信 unity hook WM_COPYDATA

MFC sendmessage实现进程间通信

MFC中WM_COPYDATA消息

WM_COPYDATA 与数组与向量

C# 进程间通信之二传递复杂数据类型(转)