zoukankan      html  css  js  c++  java
  • 使用WM_COPYDATA跨进程发送数据

    进程之间通讯的几种方法:

    在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有

    使用内存映射文件
    通过共享内存DLL共享内存
    使用SendMessage向另一进程发送WM_COPYDATA消息

    比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一中方法。WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。SDK文档推荐用户使用SendMessage函数,接受方在数据拷贝完成前不返回,这样发送方就不可能删除和修改数据。注意,接受方在DefWndProc事件中,来处理这条消息。由于中文编码是两个字节,所以传递中文时候字节长度要搞清楚。

    用WM_COPYDATA的前提:
    1,知道接收消息进程的句柄。
    2,接收消息进程重载了WM_COPYDATA消息映射,能对其做出反应(否则不是发送端自作多情了?)

    前几天写程序用到WM_COPYDATA进行进程间通信,但是接收方怎么也收不到消息。调试发现找到的窗口句柄是没有问题的,查看MSDN也没有什么提示,百思不得其解。后来看了一些示例代码,发现不同之处是我的SendMessage调用中wParam和lParam参数都是0,因为我只是需要通过WM_COPYDATA消息通知一下接收程序即可,不用传递任何数据。试着将这两个参数改为非空,接收方就可以收到消息了。总结结论为:wParam参数是否为0没有影响,但是lParam参数必须为非空,即必须指向一个有效的COPYDATASTRUCT结构体。原因是什么呢?查了一些资料发现,SendMessage(WM_COPYDATA)底层是通过文件映射(File Mapping)完成的,大概流程是发送方线程根据COPYDATASTRUCT结构体中的传递数据信息,在共享内存中进行数据复制,接收方线程则会到共享内存中读取数据进行处理。因此如果指向COPYDATASTRUCT结构的指针为空的话,流程是无法进行的,所以接收方也理所当然收不到消息。

    procedure TForm1.Button2Click(Sender: TObject);
    var
      Receiver: THandle;
      buffer: array[0..1023] of char;
      Data: TCopyDataStruct;
    begin
      Receiver := FindWindow('TReceiverForm', nil);
      if Receiver > 0 then
      begin
        StrPLCopy(@buffer, Edit1.Text, 1024); // Assumes message in Editbox
        Data.dwData := 0;
        Data.cbData := 1024;
        Data.lpData := @buffer;
        SendMessage(Receiver, WM_COPYDATA, 0, LongInt(@Data));
      end;
    end;
    
    type
      TForm1 = class(TForm)
        { ... }
      private
        { ... }
      protected
        procedure WmCopyData(var Msg: TMessage); message WM_COPYDATA;
      public
        { ... }
      end;
    
    procedure TForm1.WmCopyData(var Msg: TMessage);
    begin
      ShowMessage(
        'This message sent:' + #13 +
        string(PChar(PCopyDataStruct(Msg.LParam)^.lpData))
      );
    end;
    

    参考:http://www.xuebuyuan.com/976757.html

    http://blog.csdn.net/iseekcode/article/details/4821082

  • 相关阅读:
    jieba分词
    hue审计记录-记录用户的查询记录(用户前端删除,后端也不会删除)
    nginx1.16.1平滑升级到1.18
    mysql5.7.24升级到5.7.30 rpm部署模式 redhat7
    ldap无法启动 system library:fopen:Permission denied bss_file.c:402
    hive练习-行列转换 窗口函数
    linkis重编译适配cdh
    redhat7 安装mysql5.15
    hive 自动加载分区 --动态分区
    最近搞了个客户端
  • 原文地址:https://www.cnblogs.com/findumars/p/4176447.html
Copyright © 2011-2022 走看看