进程之间通讯(1)-WM_COPYDATA

进程之间通讯方法有很多种,我所知道的方法有1、剪贴板2、匿名,命名管道3、邮槽4、窗口消息WM_COPYDATA 5、硬盘文件操作模式。这里介绍的是第四种WM_COPYDATA消息通讯模式。用WM_COPYDATA的前提:
1,知道接收消息进程的句柄。
2,接收消息进程重载了WM_COPYDATA消息映射 。
基于对话框的发送端代码:

void CSendDlg::OnBnClickedSend()  
{
    CWnd *pWnd = CWnd::FindWindow(NULL,"接收窗口的标题");
    CString sCopyData = "传递的字符串";
    COPYDATASTRUCT cpd;
    cpd.dwData = 0;
    cpd.cbData = sCopyData.GetLength() + 1;//多加一个长度,防止乱码
    cpd.lpData = (void*)sCopyData.GetBuffer(cpd.cbData);
    if(pWnd==NULL)
	 return;  //如果对一个不存在的窗口发送消息会导致程序奔溃
    pWnd->SendMessage(WM_COPYDATA,NULL,(LPARAM)&cpd);
}

基于对话框的接收端:
1、首先要添加WM_COPYDATA消息声明
2、添加消息映射,重载消息函数

// 声明
afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
//消息映射,在消息循环中添加BEGIN_MESSAGE_MAP.....END_MESSAGE_MAP
ON_WM_COPYDATA()
// 实现
BOOL CReceiveDlg::OnCopyData( CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct )
{
    AfxMessageBox((LPCSTR)(pCopyDataStruct->lpData));
    return CWnd::OnCopyData(pWnd, pCopyDataStruct);
}

这里需要介绍的是结构体COPYDATASTRUCT:

typedef struct tagCOPYDATASTRUCT {
  DWORD dwData;  //一个32位的数据,可以作参数传递
  DWORD cbData;  //指定发送lpData的大小,以字节为单位
  PVOID lpData;  //要发送的数据
} COPYDATASTRUCT;

注意:用SendMessage进程之间通讯发送完消息后要等到消息处理完才会返回,会影响进程的运行效率,若A进程发送消息给B进程,B进程在处理消息时间内A进程处于卡死(等待)状态,若B在处理数据时奔溃,结果不可预料,推荐采用SendMessageTimeout来发送消息,来处理超时的情况。另外用WM_COPYDATA 消息进行通信,通信数据不宜太多。

参考文献:1、http://greatverve.cnblogs.com/archive/2012/12/17/WM_COPYDATA.html