首页 > 代码库 > 利用WM_COPYDATA消息实现进程间通信

利用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 = http://www.mamicode.com/(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 = http://www.mamicode.com/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消息实现进程间通信