【windows】 进程间通信 WM_COPYDATA消息
WM_COPYDATA消息可以实现window应用程序之间的数据传输,是同步传输方式。
需要用到结构体 COPYDATASTRUCT
typedef struct tagCOPYDATASTRUCT { DWORD dwData; //32位自定义的数据 DWORD cbData; // lpData指针指向的数据的大小,单位字节 PVOID lpData; //指向数据的指针,要传输的数据 } COPYDATASTRUCT;
一般使用 SendMessage()函数发送消息,不使用PostMessage(),可以确保在接收方复制数据前比秒发送方修改或删除数据。
LRESULT SendMessage( HWND hWND, //接收进程的窗体句柄 UINT Msg, //发送的消息 WM_COPYDATA WPARAM wParam, //发送进程的窗体句柄 LPARAM lParam, //指向COPYDATASTRUCT数据结构的指针 };
要注意的是 1、 lParam不能为空;2、lParam不包含接收进程无法访问的对象的指针或引用,比如发送进程自身的HDC、HBITMAP之类的东西。
如果知道接收进程的名字,可以使用FindWindow()函数获取接收进程窗体句柄。
示例:创建两个MFC对话框程序,sendAPP发送时间,receiveAPP接收时间,主要代码如下:
//sendAPP添加一个按钮,添加按钮click处理事件:
//sendAPPDlg.cpp void CsendAPPDlg::OnBnClickedButtonsendmessage() { // TODO: 在此添加控件通知处理程序代码 LPCWSTR szReceiveDlgTitle = L"receiveAPP"; HWND hSendWindow = this->GetSafeHwnd(); HWND hReceiveWindow = ::FindWindow(NULL, szReceiveDlgTitle); COPYDATASTRUCT copyData; char szSendBuf[MAX_PATH]; time_t timeNow; time(&timeNow); sprintf_s(szSendBuf, "%s", ctime(&timeNow)); copyData.dwData = 0;//32位自定义数据 copyData.cbData = strlen(szSendBuf);//lpData指针指向数据的大小,单位字节 szSendBuf[copyData.cbData ] = '\0'; copyData.lpData = szSendBuf;//指向数据的指针,就是你要传输的数据 //第一个参数 hWnd:接收进程的窗体句柄 //第二个参数 Msg:消息类型 //第三个参数 wParam:发送进程的窗体句柄 //第四个参数 lParam:指向COPYDATASTRUCT数据结构体的指针 ::SendMessage(hReceiveWindow, WM_COPYDATA, (WPARAM)hSendWindow, (LPARAM)©Data); printf("%s\n", szSendBuf); }
//receiveAPP添加 WM_COPYDATA消息处理函数
//receiveAPPDlg.cpp BOOL CreceiveAPPDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { // TODO: 在此添加消息处理程序代码和/或调用默认值 char szBuffer[300]; memset(szBuffer, 0, sizeof(szBuffer)); sprintf(szBuffer, "dwData:%d\ncbData:%d\nlpDdata:0x%08x = %s\n", pCopyDataStruct->dwData, pCopyDataStruct->cbData, (PVOID)pCopyDataStruct->lpData, (char*)pCopyDataStruct->lpData); SetDlgItemText(IDC_STATIC_Show, szBuffer); return CDialogEx::OnCopyData(pWnd, pCopyDataStruct); }
运行两个exe,点击发送数据,receiveAPP会显示当前时间
总结:
实现两个进程间同步通信,传输较少数据量
1.sendMessage()发送消息; 发送方
2.onCopyData()消息处理函数处理消息。 接收方
发送方和接收方可以是同一个,可以使用FindWindow()函数获取已知窗口名字的窗体句柄。
参考:https://www.cnblogs.com/xiekeli/p/3994380.html