首页 > 代码库 > 使用WM_COPYDATA跨进程发送数据
使用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
使用WM_COPYDATA跨进程发送数据