进程间通信
1 自定义消息和WM_COPYDATA
1) 自定义消息缺点 --参数不够用
2) WM_COPYDATA
通过WM_COPYDATA传递消息,操作系统会首先将发送的数据拷贝到高2GB共享区,然后再拷贝到接收方的用户空间中,所以会有两次拷贝,因此在数据量不大的时候,可以使用此方法,缺点就是拷贝两次效率低
// 发送方发送消息
HWND hWnd = ::FindWindow(NULL, _T("目标窗口的标题"));//获取接收方的窗口句柄
::SendMessage(hWnd, WM_MYMSG, (WPARAM)GetSafeHwnd(), (LPARAM)fProgress);//发送消息
//接受消息的程序内需添加自定义消息处理的步骤
//第一步:定义自定义消息宏,自定义的消息系统提供了一个宏WM_USER来指定自定义消息的范围
#define WM_MYMSG WM_USER + 2
//第二步:类中添加消息处理函数
afx_msg LRESULT OnMyMsg(WPARAM wParam, LPARAM lParam);
//第三步:将消息与处理函数进行消息映射
BEGIN_MESSAGE_MAP(CRateToolDlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_MESSAGE(WM_MYMSG, &CRateToolDlg::OnMyMsg)//自定义消息
END_MESSAGE_MAP()
WM_COPYDATA
注意COPYDATASTRUCT 参数写全,不然会出现接收方接收不到消息
//发送方
COPYDATASTRUCT ca;
ca.dwData = 0x12345678; //所要发送的数据
TCHAR szBuff[] = { _T("hello world") };//必须带上这个参数,不带上的话会出现接收方接收不到消息
ca.cbData = sizeof(szBuff);
ca.lpData = szBuff; //所要发送的数据
::SendMessage(
hWnd,
WM_COPYDATA,
(WPARAM)GetSafeHwnd(), //发送消息的窗口句柄
(LPARAM)&ca);//消息携带的数据
//接收方:响应WM_COPYDATA消息,通过类向导添加消息响应处理代码
BOOL CADlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CString csFmt;
csFmt.Format(_T("%08x %s"),
pCopyDataStruct->dwData,
pCopyDataStruct->lpData);
AfxMessageBox(csFmt);
pCopyDataStruct->dwData = 9;
return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
}
2 共享段,(dll中的全局变量属性是写时拷贝,读时共享,因为写时拷贝所以用默认的属性多个进程进行不了通信,所以可以用共享段来进行多个进程使用dll通信)
1) 在dll中创建一个共享段,并在共享段中定义数据,定义例子如下,.h已经写好了声明,下列只是实现的例子
2) 将共享段的属性设置为可读,可写,可共享(重点)
3) 导出共享段中定义的数据
#pragma data_seg( "TEST_DATA" ) //起始位置
int g_nVal = 9;
char szBuff[MAXBYTE] = { "hell world" };
#pragma data_seg() //结束位置
#pragma comment(linker, "/SECTION:TEST_DATA,RWS") //设置共享属性
/*
参数字符串不能有空格如这样的写法RWS前面加了一个空格#pragma comment(linker, "/SECTION:CR33_DATA, RWS")
*/