今天尝试使用senndmessage实现进程间通讯,百度一下后得到的方法是这样的:
SDK文档推荐用户使用SendMessage函数,接受方在数据拷贝完成前不返回,这样发送方就不可能删除和修改数据: 这个函数的原型及其要用到的结构如下: SendMessage(hwnd,WM_COPYDATA,wParam,lParam);
其中,WM_COPYDATA对应的十六进制数为0x004A wParam设置为包含数据的窗口的句柄。lParam指向一个COPYDATASTRUCT的结构:
typedef struct tagCOPYDATASTRUCT{
DWORD dwData;//用户定义数据
DWORD cbData;//数据大小
PVOID lpData;//指向数据的指针
}COPYDATASTRUCT;
该结构用来定义用户数据。 具体过程如下:
首先,在发送方,用FindWindow找到接受方的句柄,然后向接受方发送WM_COPYDATA消息. 接受方在DefWndProc事件中,来处理这条消息.由于中文编码是两个字节,所以传递中文时候字节长度要搞清楚.
于是按照上述方法进行尝试。但不成功。sendmessage返回总是0。断点进去发现findwindow执行正常,不解。
运行被通讯程序断点查看句柄地址后,再运行通讯程序,发现findwindow返回的值与被通讯程序的句柄地址不同。
仔细查看后发现findwindow反馈的是一个CWnd实例,通过CWnd->m_HWnd获得目标窗口句柄。
在查找过程中用到了spy++,很实用的工具。同时感谢平乐兄,不吝赐教!
其实总结来看只是个很小的问题,但发现自己的WINAPI32知识还是很匮乏,需要继续努力!
附实现代码:
- //Test1
- void CTest1Dlg::OnOK()
- {
- // TODO: Add extra validation here
- CString message;
- GetDlgItemText(IDC_EDIT1,message);
- CWnd * t_hwnd;
- t_hwnd = FindWindow(NULL,"Test2");
- if(!t_hwnd)
- return;
- COPYDATASTRUCT cds;
- cds.dwData = 0;
- cds.cbData = message.GetLength();
- cds.lpData = malloc(message.GetLength());
- memcpy((char*)cds.lpData,message,message.GetLength());
- ::SendMessage(t_hwnd->m_hWnd,WM_COPYDATA,(WPARAM)m_hWnd,(LPARAM)(LPVOID)&cds);
- free(cds.lpData);
- }
- //Test2
- BOOL CTest2Dlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
- {
- // TODO: Add your message handler code here and/or call default
- char * message = (char *)malloc(pCopyDataStruct->cbData+1);
- memcpy(message,(char*)pCopyDataStruct->lpData,pCopyDataStruct->cbData);
- message[pCopyDataStruct->cbData] = '/0';
- SetDlgItemText(IDC_EDIT1,message);
- free(message);
- return CDialog::OnCopyData(pWnd, pCopyDataStruct);
- }