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

MFC用WM_COPYDATA在进程间发送数据

2013-12-12 14:27 477 查看
在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动态数据交换。     
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息