• VC++ 在两个程序中 传送字符串等常量值的方法:使用了 WM_COPYDATA 消息(转载)


    转载:http://www.cnblogs.com/renyuan/p/5037536.html

    VC++ 在两个程序中 传递字符串等常量值的方法:使用了 WM_COPYDATA 消息的

    消息作用:
        在进程间共享数据(内部通过创建内存映射文件)

    消息介绍:
    需要用到的数据结构/类型:
    typedef struct tagCOPYDATASTRUCT {
        ULONG_PTR dwData;
        DWORD cbData;
        PVOID lpData;
    } COPYDATASTRUCT, *PCOPYDATASTRUCT;

    结构体参数说明:
        dwData(ULONG)   保存一个数值, 可以用来作标志等
        lpData(void*)   待发送的数据的起始地址(可以为NULL)
        cbData(DWORD)   待发送的数据的长度
    消息的参数:
        hWnd:   接收数据的窗口的句柄
        wParam: 传送该数据的窗口句柄(NULL也无所谓)
        lParam: COPYDATASTRUCT类型变量的地址
    使用示例:

        COPYDATASTRUCT cds;
        char msg[] = "女孩不哭";
        cds.dwData = 0;
        cds.lpData = msg;
        cds.cbData = strlen(msg)+1; //字符串请记得把''加上, 不然就错了, 这里是ANSI字符串
        SendMessage(FindWindow("nbsg_class", NULL), WM_COPYDATA, 0, (LPARAM)&cds);

    注意:如果要发送的是一个CString类型的字符串,那么可以这么做

    CString str = _T("女孩不哭");
    char* msg = str.GetBuffer(0);

    这样就可以转化为 char*类型了

    --------------------------------------------
    接收端对该消息的一种可能处理:

    BOOL CxuanzeDlg::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
    {
        // TODO:  在此添加消息处理程序代码和/或调用默认值
        COPYDATASTRUCT* pCDS = (COPYDATASTRUCT*)pCopyDataStruct;
        CString str((char*)pCDS->lpData);
        str.Format(_T("%s  标志:%d"), str, pCDS->dwData);
        AfxMessageBox(str);
        return CDialogEx::OnCopyData(pWnd, pCopyDataStruct);
    }


    说明:  
    使用 WM_COPYDATA 消息的传递数据,其实是将要传递的数据复制到共享内存中去后,将地址传递给另一个进程.

    在这个消息中,有一个标志dwData 这个数据是一个ULONG_PTR类型,无符号长整数,可以用作数据的标志.这样不同的标志,可以将传递的数据用作不同的用途!

    其中pCDS为接收到的字符串,pCopyDataStruct为COPYDATASTRUCT结构指针。注意由pCopyDataStruct直接得到的pCDS字符串长度可能不是实际发送的字符串长度,需要用发送字符串时所给定的字符串长度来进一步确定,其长度由pCopyDataStruct ->cbData来得到。

       用到WM_COPYDATA进行进程间通信,但是接收方怎么也收不到消息。调试发现找到的窗口句柄是没有问题的,查看MSDN也没有什么提示,百思不得其解。后来看了一些示例代码,发现不同之处是我的SendMessage调用中wParam和lParam参数都是0,因为我只是需要通过WM_COPYDATA消息通知一下接收程序即可,不用传递任何数据。试着将这两个参数改为非空,接收方就可以收到消息了。总结结论为:wParam参数是否为0没有影响,但是lParam参数必须为非空,即必须指向一个有效的COPYDATASTRUCT结构体。

         原因是什么呢?查了一些资料发现,SendMessage(WM_COPYDATA)底层是通过文件映射(File Mapping)完成的,大概流程是发送方线程根据COPYDATASTRUCT结构体中的传递数据信息,在共享内存中进行数据复制,接收方线程则会到共享内存中读取数据进行处理。因此如果指向COPYDATASTRUCT结构的指针为空的话,流程是无法进行的,所以接收方也理所当然收不到消息。

  • 相关阅读:
    《JavaScript 闯关记》之 BOM
    《JavaScript 闯关记》之单体内置对象
    《JavaScript 闯关记》之基本包装类型
    《JavaScript 闯关记》之正则表达式
    《JavaScript 闯关记》之函数
    《JavaScript 闯关记》之数组
    被「李笑来老师」拉黑之「JavaScript微博自动转发的脚本」
    「前端开发者」如何把握住「微信小程序」这波红利?
    android开发之路13(实际开发常见问题及解决办法ING)
    android开发之路12(android四大组件&Fragment&AsyncTask类)
  • 原文地址:https://www.cnblogs.com/chechen/p/6606570.html
Copyright © 2020-2023  润新知