进程间通信交换数据——初级篇

1:采用自定义信息

发端:

(1)UpdateData();

(2)查找对象句柄 CWnd *pWnd = CWnd::FindWindow(NULL,_T("DataRecv1"));

(3)自定义消息WM_Comm1:#define WM_COMM1      WM_USER+101,

  (4) 发送
 UINT uMsg;
  uMsg = atoi(m_StrMes);
  pWnd->SendMessage(WM_COMM1,NULL,(LPARAM)uMsg);

收端:

(1)定义相同的消息#define WM_COMM1      WM_USER+101

(2)ON_MESSAGE(WM_COMM1,OnUserReceiveMsg)

(3)afx_msg void OnUserReceiveMsg(WPARAM wParam,LPARAM lParam);

(4)void CDataRecv1Dlg::OnUserReceiveMsg(WPARAM wParam,LPARAM lParam)
       {
               m_StrGetMes.Format("%d\n",int(lParam));
               UpdateData(FALSE);
        }

2:用注册消息进行通信

和自定义消息很类似

发端:

(1):注册消息const UINT wm_nRegMsg=RegisterWindowMessage("reg_data");

(2)同自定义消息

收端

(1):注册消息const UINT wm_nRegMsg=RegisterWindowMessage("reg_data");

(2):ON_REGISTERED_MESSAGE(wm_nRegMsg,OnRegReceiveMsg)//(注意采用的宏不一样)

(3),(4)同:

3:  用wm_copydata消息实现通信

发端:

(1):查找对象窗口的句柄

(2):发送copydatastruct结构体

  COPYDATASTRUCT cpd;
  cpd.dwData =0;
  cpd.cbData = m_CopyData.GetLength();
  cpd.lpData = (void*)m_CopyData.GetBuffer(cpd.cbData);
  pWnd->SendMessage(WM_COPYDATA,NULL,(LPARAM)&cpd);

收端:

(1)在message_map中添加ON_WM_COPYDATA()

(2)afx_msg中添加afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);

(3)消息映射

BOOL CDataRecv1Dlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
   m_StrGetCopyData= (LPCTSTR)pCopyDataStruct->lpData;
   m_StrGetCopyData=m_StrGetCopyData.Left(pCopyDataStruct->cbData);
   UpdateData(FALSE);
   return CDialog::OnCopyData(pWnd, pCopyDataStruct);
}

4:使用内存地址通信

发端:

(1)查找对象句柄

(2):获得当前句柄的进程ID:

DWORD PID;
 GetWindowThreadProcessId(pWnd->m_hWnd,(DWORD*)&PID);

(3):根据进程ID打开进程获得进程句柄

HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,PID);

(4):分配虚拟内存

LPVOID lpBaseAddress;
 lpBaseAddress = VirtualAllocEx(hProcess,0,BUFFER_SIZE,MEM_COMMIT,PAGE_READWRITE);
 char data[BUFFER_SIZE];
 strcpy(data,m_strSendAddress);

(5):将数据写入对象进程地址空间中

WriteProcessMemory(hProcess,lpBaseAddress,data,BUFFER_SIZE,NULL);

(6):注册消息

const UINT wm_nMemMsg=RegisterWindowMessage("mem_data");

(7):发送注册消息

 pWnd->SendMessage(wm_nMemMsg,NULL,(LPARAM)lpBaseAddress);
 Sleep(100);

(8)释放申请的虚拟内存

VirtualFreeEx(hProcess,lpBaseAddress,0,MEM_RELEASE);

收端:

(1):const UINT wm_nMemMsg=RegisterWindowMessage("mem_data");

(2):ON_REGISTERED_MESSAGE(wm_nMemMsg,OnRegMemMsg)

(3):afx_msg void OnRegMemMsg(WPARAM wParam,LPARAM lParam);

(4):

void CDataRecv1Dlg::OnRegMemMsg(WPARAM wParam,LPARAM lParam)
{
 LPVOID lpBaseAddress=(LPVOID)lParam;

//打开进程
 HANDLE hProcess = GetCurrentProcess();

 char data[BUFFER_SIZE];

//通过当前进程读内存中的数据
 ReadProcessMemory(hProcess,lpBaseAddress,data,BUFFER_SIZE,NULL);
 m_GetMemData = data;
 UpdateData(FALSE);

}

5:利用内存映射通信

发端:

(1):// 创建内存映像对象.

HANDLE hMapping;  
 LPSTR lpData;  
 hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,NULL,
                    PAGE_READWRITE,0,BUFFER_SIZE,"MYSHARE");  

(2):将文件的视图映射到一个进程的地址空间上,返回LPVOID类型的内存指针.

 lpData=(LPSTR)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);  

(3:给这段映像内存写数据

 sprintf(lpData,m_strFileMap);  

(4)// 释放映像内存.
 UnmapViewOfFile(lpData);  

收端:

和发端比较类似

hMapping=CreateFileMapping((HANDLE)0xFFFFFFFF,
  NULL,PAGE_READWRITE,0,0x100,"MYSHARE");
 if(hMapping==NULL)
 {
  AfxMessageBox("CreateFileMapping() failed.");
  return;
 }
  lpData=(LPSTR)MapViewOfFile(hMapping,FILE_MAP_ALL_ACCESS,0,0,0);
 if(lpData==NULL)
 {
  AfxMessageBox("MapViewOfFile() failed.");
  return;
 }

//给这段映像内存的数据赋给本地变量
 m_strFileMap.Format("%s",lpData);
 UnmapViewOfFile(lpData);

6:使用剪贴板数据通信

发端:

UpdateData();                    // 更新数据.
 CString strData=m_strClipBoard;  // 获得数据.

 // 打开系统剪贴板.
 if (!OpenClipboard()) return;

 // 使用之前,清空系统剪贴板.
 EmptyClipboard();

 // 分配一内存,大小等于要拷贝的字符串的大小,返回的内存控制句柄.
 HGLOBAL hClipboardData;
 hClipboardData = GlobalAlloc(GMEM_DDESHARE, strData.GetLength()+1);
 
 // 内存控制句柄加锁,返回值为指向那内存控制句柄所在的特定数据格式的指针.
 char * pchData;
 pchData = (char*)GlobalLock(hClipboardData);
 // 将本地变量的值赋给全局内存.
 strcpy(pchData, LPCSTR(strData));
 // 给加锁的全局内存控制句柄解锁.
 GlobalUnlock(hClipboardData);
 // 通过全局内存句柄将要拷贝的数据放到剪贴板上.
 SetClipboardData(CF_TEXT,hClipboardData);
 // 使用完后关闭剪贴板.
 CloseClipboard();

收端:

// 打开系统剪贴板.
 if (!OpenClipboard()) return;

 // 判断剪贴板上的数据是否是指定的数据格式.
 if (IsClipboardFormatAvailable(CF_TEXT)|| IsClipboardFormatAvailable(CF_OEMTEXT))
 {// 从剪贴板上获得数据.
  HANDLE hClipboardData = GetClipboardData(CF_TEXT);
  // 通过给内存句柄加锁,获得指向指定格式数据的指针.
  char *pchData = (char*)GlobalLock(hClipboardData);
  // 本地变量获得数据.
  m_strClipBoard = pchData;
  // 给内存句柄解锁.
  GlobalUnlock(hClipboardData);
 }
 else
 { AfxMessageBox("There is no text (ANSI) data on the Clipboard.");
 }
 // 使用完后关闭剪贴板.
 CloseClipboard();

 // 更新数据.
 UpdateData(FALSE);

原文地址:https://www.cnblogs.com/lzjsky/p/1774496.html