您的位置:首页 > 运维架构

用WM_COPYDATA实现进程通信

2008-12-19 15:24 489 查看
用WM_COPYDATA的前提:
1,知道接收消息进程的句柄。
2,接收消息进程重载了WM_COPYDATA消息映射,能对其做出反应,因为必须使用SendMessage()。
下面CODE几行就说明了一切。
OK,开始写发送端代码:
HWND hWnd = FindWindow(NULL,"MyApp");
if(hWnd!=NULL)
{
COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
cpd.dwData = 0;
cpd.cbData = strlen("字符串");
cpd.lpData = (void*)"字符串";
::SendMessage(hWnd,WM_COPYDATA,NULL,(LPARAM)&cpd);//发送!
}
接收端重载ON_WM_COPYDATA消息映射函数(下面是手工所要加的,你最好还是用ClassWizard)
afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
ON_WM_COPYDATA()/*消息映射*/
BOOL CMainFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
AfxMessageBox((LPCSTR)(pCopyDataStruct->lpData));/*利用对话框表示收到消息*/
return CWnd::OnCopyData(pWnd, pCopyDataStruct);
}

注意:hWnd不能用成员变量保存,需每次Send之前动态生成。
------------------------------------------------------------------------
结构体
  本例子分别用WM_COPYDATA 实现了两种数据类型的发送,一种为Cstring,另外一种为自定义的结构体Student:
  
  //**********************************************************
  
  #pragma pack(1)
  
  struct Student {
  
  char ID[10];
  
  TCHAR  Name[20];
  
  UINT   Age;
  
  UINT   Grade;
  
  char Room[5];
  
  char Tel[12];
  
  };
  
  #pragma pack()
  
  //**********************************************************
  
  因为需要在接收方的OnCopyData()函数中区分发送的两种不同类型数据。所以就定义了以下两个常量:
  
  #define STRING 1
  
  #define STUDENT 2
  
  发送方:
  
  void CSendDataDlg::OnBtSend() //实现CString类型数据的发送
  
  {
  
  UpdateData(TRUE);
  
  if (m_szData.IsEmpty()) {
  
  m_szData = _T("Hello");
  
  UpdateData(FALSE);
  
  }
  
  //   m_szData += '/0';
  
  HWND hWndRcv = ::FindWindow(NULL,"Receiver");
  
  if (hWndRcv == NULL) {
  
  AfxMessageBox(_T("找不到接收窗口,发送不成功"));
  
  return ;
  
  }
  
  COPYDATASTRUCT cpd;
  
  cpd.dwData = STRING; //标志为CString类型
  
  cpd.cbData = m_szData.GetLength() + 1;
  
  //GetLength()只是取得实际字符的长度,没有包括'/0'.
  
  cpd.lpData = (void*)m_szData.GetBuffer(cpd.cbData);
  
  ::SendMessage(hWndRcv,WM_COPYDATA,(WPARAM)this->m_hWnd,(LPARAM)&cpd);
  
  m_szData.ReleaseBuffer();
  
  AfxMessageBox(_T("发送成功"));
  
  }
  
  void CSendDataDlg::OnBtStu() //实现Student类型数据的发送
  
  {
  
  UpdateData();
  
  m_szID += '/0';
  
  m_szName += '/0';
  
  m_szRoom += '/0';
  
  m_szTel += '/0';
  
  m_pStu = new Student();
  
  strcpy(m_pStu->ID,m_szID.GetBuffer(m_szID.GetLength()));
  
  _tcscpy(m_pStu->Name,m_szName.GetBuffer(m_szName.GetLength()));
  
  strcpy(m_pStu->Room,m_szRoom.GetBuffer(m_szRoom.GetLength()));
  
  strcpy(m_pStu->Tel,m_szTel.GetBuffer(m_szTel.GetLength()));
  
  m_szID.ReleaseBuffer();m_szName.ReleaseBuffer();
  
  m_szRoom.ReleaseBuffer();m_szTel.ReleaseBuffer();
  
  m_pStu->Age = m_nAge;
  
  m_pStu->Grade = m_nGrade;
  
  HWND hWndRcv = ::FindWindow(NULL,"Receiver");
  
  if (hWndRcv == NULL) {
  
  AfxMessageBox(_T("找不到接收窗口,发送不成功"));
  
  return ;
  
  }
  
  COPYDATASTRUCT cpd;
  
  cpd.dwData = STUDENT;   // 标志为Student类型
  
  cpd.cbData = sizeof(Student);
  
  cpd.lpData = (PVOID)m_pStu;
  
  ::SendMessage(hWndRcv,WM_COPYDATA,(WPARAM)this->m_hWnd,(LPARAM)&cpd);
  
  delete m_pStu;
  
  AfxMessageBox(_T("发送成功"));
  
  }
  
  接收方:
  
  在OnInitDialog方法中:
  
  //***************************************************************
  
  //初始化ListCtrl控件
  
  LVCOLUMN column;
  
  column.mask = LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH;
  
  column.cx = 80;
  
  column.iSubItem = 0;
  
  column.pszText = _T("ID");
  
  m_ListCtl.InsertColumn(0,&column);
  
  column.cx = 80;
  
  column.pszText = _T("Name");
  
  column.iSubItem = 1;
  
  m_ListCtl.InsertColumn(1,&column);
  
  column.cx = 55;
  
  column.pszText = _T("Age");
  
  column.iSubItem = 2;
  
  m_ListCtl.InsertColumn(2,&column);
  
  column.cx = 55;
  
  column.pszText = _T("Grade");
  
  column.iSubItem = 3;
  
  m_ListCtl.InsertColumn(3,&column);
  
  column.cx = 55;
  
  column.pszText = _T("Room");
  
  column.iSubItem = 4;
  
  m_ListCtl.InsertColumn(4,&column);
  
  column.cx = 80;
  
  column.pszText = _T("Tel");
  
  column.iSubItem = 5;
  
  m_ListCtl.InsertColumn(5,&column);
  
  BOOL CReceiverDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
  
  {
  
  switch (pCopyDataStruct->dwData) { // 接收到的是CString类型
  
  case STRING:
  
  m_szData += (LPCSTR)(pCopyDataStruct->lpData);
  
  UpdateData(FALSE);
  
  break;
  
  case STUDENT: // 接收到的是Student类型
  
  CString id,name,room,tel;
  
  UINT age,grade;
  
  CString str;
  
  Student* pStu = (Student*)(pCopyDataStruct->lpData);
  
  id = pStu->ID;
  
  name = pStu->Name;
  
  room = pStu->Room;
  
  tel = pStu->Tel;
  
  age = pStu->Age;
  
  grade = pStu->Grade;
  
  LVITEM item;
  
  // 把接收到的数据显示到ListCtrl控件上
  
  item.mask = LVIF_TEXT;
  
  int n = m_ListCtl.GetItemCount();
  
  item.iItem = n;
  
  item.iSubItem = 0;
  
  item.pszText = id.GetBuffer(id.GetLength());
  
  id.ReleaseBuffer();
  
  m_ListCtl.InsertItem(&item);
  
  m_ListCtl.SetItemText(n,1,name);
  
  str.Format("%d",age);
  
  m_ListCtl.SetItemText(n,2,str);
  
  str.Format("%d",grade);
  
  m_ListCtl.SetItemText(n,3,str);
  
  m_ListCtl.SetItemText(n,4,room);
  
  m_ListCtl.SetItemText(n,5,tel);
  
  UpdateData(FALSE);
  
  //delete pStu;
  
  break;
  
  }
  
  //   return CDialog::OnCopyData(pWnd, pCopyDataStruct);
  
  return TRUE;
  
  }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: