利用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