zoukankan      html  css  js  c++  java
  • 利用WM_COPYDATA消息实现进程间通信

      进程间通信最简单的方式就是发送WM_COPYDATA消息,下面通过例子来实现。

          发送WM_COPYDATA消息

          SendMessage(hRecvWnd,

                              WM_COPYDATA,

                              (WPARAM)hSendWnd,

                              (LPARAM)&CopyData);

           其中的CopyData为COPYDATASTRUCT结构类型,该结构定义如下:

           typedef struct tagCOPYDATASTRUCT {

                 DWORD dwData;

                 DWORD cbData;

                 PVOID lpData;

           } COPYDATASTRUCT;

      参数:

          dwData;   // Specifies data to be passed to the receiving application.

          cbData;    //Specifies the size, in bytes, of the data pointed to by the lpData member.

          lpData;    // Pointer to data to be passed to the receiving application. can be NULL.

           注意:该消息只能由SendMessage()来发送,而不能使用PostMessage()。因为系统必须管理用以传递数据的缓冲区的生命期,如果使用了PostMessage(),数据缓冲区会在接收方(线程)有机会处理该数据之前,就被系统清除和回收。此外如果lpData指向一个带有指针或某一拥有虚函数的对象时,也要小心处理。

           如果传入的句柄不是一个有效的窗口或当接收方进程意外终止时,SendMessage()会立即返回,因此发送方在这种情况下不会陷入一个无穷的等待状态中。

     

           接收WM_COPYDATA消息

           只要用COPYDATASTRUCT *pCopyData = (COPYDATASTRUCT*)lParam; 就可以了,接收方应认为这些数据是只读的。

           由于发送方在接收方处理WM_COPYDATA消息完毕前都是处于等待中,所以接收方应当尽快处理WM_COPYDATA消息。

       代码实现  

    //发送端:
    void CSendCopyDataDlg::OnBnClickedBtnSend()
    {
        CString strSendText;
        m_EditSend.GetWindowText(strSendText);
        if (strSendText.IsEmpty())
        {
            AfxMessageBox(_T("发送内容不能为空!"));
            return;
        }
    
        // 获取接收端窗口句柄
        HWND hWnd = ::FindWindow(NULL,_T("RecvCopyData"));
        if (hWnd == NULL)
        {
            AfxMessageBox(_T("数据接收端未启动!"));
            return;
        }
    
        // 发送数据
        COPYDATASTRUCT CopyData; 
        CopyData.dwData = 1;                          
        CopyData.cbData = strSendText.GetLength() * 2;   //分配足够缓冲区长度,防止接收乱码 
        CopyData.lpData = (void*)strSendText.GetBuffer();
        ::SendMessage(hWnd, WM_COPYDATA, NULL, (LPARAM)&CopyData);
        strSendText.ReleaseBuffer();
    }
    
    //接收端:
    afx_msg BOOL OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct);
    
    ON_WM_COPYDATA()
    BOOL CRecvCopyDataDlg::OnCopyData(CWnd* pWnd, 
                                      COPYDATASTRUCT* pCopyDataStruct)
    {
        //在编辑框中追加数据 
        SYSTEMTIME st;
        CString strDateTime;
        GetSystemTime(&st);
        strDateTime.Format(_T("%04d-%02d-%02d %02d:%02d:%02d.%04d   "), 
            st.wYear,
            st.wMonth,
            st.wDay,
            st.wHour,
            st.wMinute,
            st.wSecond,
            st.wMilliseconds);
        CString strRecvText = strDateTime + (LPWSTR)(pCopyDataStruct->lpData);
        m_RichEditRecv.SetSel(-1, -1);  
        m_RichEditRecv.ReplaceSel(strRecvText + _T("
    ")); 
    
        return CDialog::OnCopyData(pWnd, pCopyDataStruct);
    }

       编译运行

      例子下载:http://pan.baidu.com/s/1i5n6Kex

       

  • 相关阅读:
    精简shell基础
    Centos7.4下安装Jumpserver 1.0.0(支持windows组件)
    二.Flask 学习模板
    一、Flask路由介绍
    web爬虫,BeautifulSoup
    web爬虫,requests请求
    django之Form组件补充
    中间件和Django缓存
    django之Form组件
    django from表单验证
  • 原文地址:https://www.cnblogs.com/MakeView660/p/6912530.html
Copyright © 2011-2022 走看看