Windows 程序可以使用 WM_COPYDATA
函数来实现一些进程间的简单通信 , 使用 SendMessage
来发送消息 :
SendMessage(接收窗口句柄, WM_COPYDATA, (WPARAM)发送窗口句柄, (LPARAM)©Data);
其中的 copyData
是要发送的数据 , 类型为 COPYDATASTRUCT
结构体 :
typedef struct tagCOPYDATASTRUCT {
ULONG_PTR dwData;
DWORD cbData;
_Field_size_bytes_(cbData) PVOID lpData;
} COPYDATASTRUCT, *PCOPYDATASTRUCT;
字段解释如下 :
dwData : Specifies up to 32 bits of data to be passed to the receiving application.
cbData : Specifies the size, in bytes, of the data pointed to by the lpData member.
lpData : Long pointer to data to be passed to the receiving application. This member can be NULL.
该消息只能由 SendMessage()
发送 , 而不能使用 PostMessage()
, 因为系统必须管理用以传递数据的缓冲区的生命期 , 如果使用了 PostMessage()
, 数据缓冲区会在接收方有机会处理该数据之前 , 就被系统清除和回收 , 如果传入的接收窗口句柄无效或者当接收方进程意外终止时 , SendMessage() 会立即返回 , 发送方不会陷入一个无穷等待的状态中 ; 示例代码如下(MFC程序) :
发送进程 A 送代码 :
void CMFCApplicationSendDlg::OnBnClickedButtonSendmsg()
{
// 接收消息进程名
CString strOtherWndTitle = _T("RecvClient");
// 发送数据
CString strSendData = _T("Hello World");
// 获取接收消息进程句柄
HWND hOtherWnd = ::FindWindow(NULL, strOtherWndTitle.GetBuffer(0));
if (hOtherWnd != NULL && ::IsWindow(hOtherWnd))
{
COPYDATASTRUCT cdsSend;
cdsSend.dwData = 0;
cdsSend.cbData = strSendData.GetLength() * sizeof(TCHAR);
cdsSend.lpData = (void*)strSendData.GetBuffer(0);
HRESULT hResult = ::SendMessage(hOtherWnd, WM_COPYDATA, (WPARAM)(AfxGetApp()->m_pMainWnd), (LPARAM)&cdsSend);
}
strSendData.ReleaseBuffer();
}
接收方先添加 WM_COPYDATA
函数 , 然后将窗口名字 Caption
修改成发送方需要捕获的指定名字 , 然后完善 WM_COPYDATA 函数代码如下 :
BOOL CMFCApplicationRecvDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
if (pCopyDataStruct != NULL)
{
LPCTSTR pszText = (LPCTSTR)(pCopyDataStruct->lpData);
DWORD dwLength = (DWORD)(pCopyDataStruct->cbData);
TCHAR szRecvData[1024] = {0};
memcpy(szRecvData, pszText, dwLength);
MessageBox(szRecvData, _T("Recieve Msg"), MB_OK);
}
return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
}
个人网站: Github , 欢迎点击给星