zoukankan      html  css  js  c++  java
  • 进程间通信交换数据——初级篇

    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);

  • 相关阅读:
    55、分页查询employees表,每5行一页,返回第2页的数据
    54、查找排除当前最大、最小salary之后的员工的平均工资avg_salary
    53、按照分组拼接字段
    52、获取Employees中的first_name
    51、查找字符串'10,A,B' 中逗号','出现的次数cnt
    图片素材
    软件下载
    一款高效卸载软件
    《单独.17 人的困境》(摘抄)
    Markdown的简单使用
  • 原文地址:https://www.cnblogs.com/lzjsky/p/1774496.html
Copyright © 2011-2022 走看看