MFC用WM_COPYDATA在进程间发送数据

在VC中用WM_COPYDATA在进程间发送数据

用WM_COPYDATA的前提:
1,知道接收消息进程的句柄。
2,接收消息进程重载了WM_COPYDATA消息映射,能对其做出反应(否则不是发送端自作多情了?)
看过前提,的出结论:在自己写的两个进程间用WM_COPYDATA再好不过。

下面CODE几行就说明了一切。
获得句柄的方法,最简单的方法就是使用FindWindow,找窗口类,或者名,如果你觉得这样不把握,那就利用SetProp个窗口做个记号....(不说这些,跑踢儿了都)

 ******************************************************************************************************
发送端代码:

1.字符串的发送
 CString m_szdata;
 m_szdata = _T("hello");

ShellExecute(NULL,NULL,"EditDlg.exe",NULL,NULL,SW_SHOW);
 Sleep(100);
 HWND hWnd = ::FindWindow(NULL,"EditDlg");
 if(hWnd != NULL)
 {
  COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/

  //cpd.dwData = 1;                                                                                                         //标志发送字符串
  //cpd.cbData = strlen("字符串")+1;
  //cpd.lpData = "字符串";
  //::SendMessage(hWnd,WM_COPYDATA,NULL,(LPARAM)&cpd);//发送!

  cpd.dwData = 1;                                                                                                        //标志发送CString类型
  cpd.cbData = m_szdata.GetLength()+ 1;  
  cpd.lpData = (void*)m_szdata.GetBuffer(cpd.cbData);
  ::SendMessage(hWnd,WM_COPYDATA,NULL,(LPARAM)&cpd);//发送!
 }

//还需要解决的是发送数组问题
CString strWindowTitle = _T("testcomm");
    CString strDataToSend  = _T("This is a message to send");
    
LRESULT copyDataResult;
CWnd *pOtherWnd = CWnd::FindWindow(NULL, strWindowTitle);


if (pOtherWnd)
{
COPYDATASTRUCT cpd;
cpd.dwData = 0;
cpd.cbData = strDataToSend.GetLength();
cpd.lpData = (void*)strDataToSend.GetBuffer(cpd.cbData);
copyDataResult = pOtherWnd->SendMessage(WM_COPYDATA,
                                                (WPARAM)AfxGetApp()->m_pMainWnd->GetSafeHwnd(),
                                                (LPARAM)&cpd);
strDataToSend.ReleaseBuffer();
// copyDataResult has value returned by other app


else 
{
AfxMessageBox("Unable to find other app.");
}
OnOK();

2.数组的发送

void CMainFrame::OnMenuitem32773() 
{
 // TODO: Add your command handler code here
 int BIT16Size = 64;
 BIT16 int3array[64+1] ;
 int3array[0] = BIT16Size;
 for(int i=0; i<BIT16Size; i++)
 {
  int3array[i+1] = 0x14;
 }

 this->SendDataToBIT16EditDlg(int3array,BIT16Size+1);
}

SendDataToBIT16EditDlg为发送一个数组,数组中有1+N个数,第一个为数据大小N,其它为实际数据N个,它的定义如下:
void CMainFrame::SendDataToBIT16EditDlg(BIT16 BIT16DataArray[], int WholeSize)
{  
 HWND hWnd = ::FindWindow(NULL,"EditDlg");          //找到窗口
 if(hWnd != NULL)
 {
  COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
  cpd.dwData = 2;                                              // 标志为数组类型
  cpd.cbData = sizeof(BIT16)*WholeSize;
  cpd.lpData = (void *)BIT16DataArray;
  
  ::SendMessage(hWnd,WM_COPYDATA,NULL,(LPARAM)&cpd);//发送!
 }
}

3.结构体的发送

//发送3,结构体,此处仅定义了2个整型变量
void CMainFrame::OnMenuitem32774() 
{
 typedef struct{
  int temp_SizeofDataArray;                    
  int  temp_DataArray;                          
 }DynamicArray;

 DynamicArray StuArray;
 StuArray.temp_SizeofDataArray = 3;
 StuArray.temp_DataArray = 4;

 HWND hWnd = ::FindWindow(NULL,"EditDlg");
 if(hWnd != NULL)
 {
  COPYDATASTRUCT cpd; /*给COPYDATASTRUCT结构赋值*/
  cpd.dwData = 3;               // 标志为DynamicArray类型
  cpd.cbData = sizeof(StuArray);
  cpd.lpData = &StuArray;
  
  ::SendMessage(hWnd,WM_COPYDATA,NULL,(LPARAM)&cpd);//发送!
 } 
}

接收端代码:
接收端重载ON_WM_COPYDATA消息映射函数,可用ClassWizard来添加.

//程序间传送数据,其它进程可以给本进程发送数据
BOOL CEditDlgDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) 
{
 // TODO: Add your message handler code here and/or call default
 using namespace std;
 CString str;
 typedef struct{
  int temp_SizeofDataArray;                    //数组大小
  int  temp_DataArray;                         //十六进制数组
 }DynamicArray;

 int size,i;
 
 switch (pCopyDataStruct->dwData) 
 {
 case 1:                                               // 接收到的是字符串或CString类型
        AfxMessageBox((LPCSTR)(pCopyDataStruct->lpData));
        break;


 case 2:                                              // 接收到的是数组类型
  BIT16 *int3array;
        int3array = (BIT16 *)(pCopyDataStruct->lpData);   //放入数组

  size = int3array[0].to_ulong();                            //第一行为数组大小
  m_edit16Binary.DataArray.clear();
  for(i=1; i < size+1; i++)
  { 
   m_edit16Binary.DataArray.push_back(int3array[i]); 
  }

  m_edit16Binary.SizeofDataArray = size;
  m_edit16Binary.Efficacy = m_edit16Binary.MakeEfficacy();

  //更新编辑框,显示正确的效验和
  m_edit16Binary.Init();
  OnButtonEfficacy();
  break;


 case 3:                                               //接收到的是结构体
  DynamicArray *pstuArray;
  pstuArray = (DynamicArray *)(pCopyDataStruct->lpData);


  str.Format("%d",pstuArray->temp_SizeofDataArray);
  AfxMessageBox(str);

  str.Format("%d",pstuArray->temp_DataArray);
  AfxMessageBox(str);
  break;
 default:
  break;
 }
 
 return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

头文件说明:

#include <bitset>
#include <vector>

using namespace std;
typedef  bitset< 16 >  BIT16;

 ******************************************************************************************************

进程通信还有其他一些手段,相对来说比较麻烦,但局限性要比WM_COPYDATA小。当然你也可以两端都注册一个消息来通信.

程序之间传递参数有多种实现方法:   
  1。发消息传递传递一个数值,使用wm_copydata结构可传递一组各种不同类型的参数。   
  2。如果是一对多个程序发消息(共享),须使用RegisterWindowMessage()注册消息标识符   
  3。使用共享文件传递大批量数据,用发消息的方法通知。   
  4。使用剪贴板,静态交换。   
  5。使用原子   
  6。DDE动态数据交换。     

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值