<iframe marginwidth="0" marginheight="0" src="http://218.16.120.35:65001/PC/Global/images/b.html" frameborder="0" width="728" scrolling="no" height="90"></iframe>
简介: 本文着重讲述了如果用
WM_COPYDATA消息来实现两个
进程之间传递数据.
进程之间通讯的几种方法: 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯。常用的方法有
- 使用内存映射文件
- 通过共享内存DLL共享内存
- 使用SendMessage向另一进程发送WM_COPYDATA消息
比起前两种的复杂实现来,WM_COPYDATA消息无疑是一种经济实惠的一中方法.
WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。SDK文档推荐用户使用SendMessage函数,接受方在数据拷贝完成前不返回,这样发送方就不可能删除和修改数据:
这个函数的原型及其要用到的结构如下:
SendMessage(hwnd,WM_COPYDATA,wParam,lParam);
其中,WM_COPYDATA对应的十六进制数为0x004A
wParam设置为包含数据的窗口的句柄。lParam指向一个COPYDATASTRUCT的结构:
typedef struct tagCOPYDATASTRUCT{
DWORD dwData;//用户定义数据
DWORD cbData;//数据大小
PVOID lpData;//指向数据的指针
}COPYDATASTRUCT;
该结构用来定义用户数据。
具体过程如下:
首先,在发送方,用FindWindow找到接受方的句柄,然后向接受方发送WM_COPYDATA消息.
接受方在DefWndProc事件中,来处理这条消息.由于中文编码是两个字节,所以传递中文时候字节长度要搞清楚.
代码中有适量的解释,大家请自己看吧.
具体代码如下:
//---------------------------------------------------
//发送方:
//---------------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace WindowsFormGetMsg
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.ComponentModel.Container components = null;
const int WM_COPYDATA = 0x004A;
public Form1()
{
InitializeComponent();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(176, 32);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(160, 21);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(432, 266);
this.Controls.AddRange(new System.Windows.Forms.Control[] { this.textBox1 });
this.Name = "Form1";
this.Text = "接收方";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
//接收自定义消息 USER,并显示其参数
case WM_COPYDATA:
COPYDATASTRUCT mystr = new COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr = (COPYDATASTRUCT) m.GetLParam(mytype);
this.textBox1.Text = mystr.lpData;
break;
default:
base.DefWndProc(ref m);
break;
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
}
//---------------------------------------------------
//接受方
//---------------------------------------------------
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Runtime.InteropServices;
namespace WindowsFormGetMsg
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.ComponentModel.Container components = null;
const int WM_COPYDATA = 0x004A;
public Form1()
{
InitializeComponent();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(176, 32);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(160, 21);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "textBox1";
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
this.ClientSize = new System.Drawing.Size(432, 266);
this.Controls.AddRange(new
System.Windows.Forms.Control[] { this.textBox1 });
this.Name = "Form1";
this.Text = "接收方";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
protected override void DefWndProc(ref System.Windows.Forms.Message m)
{
switch (m.Msg)
{
//接收自定义消息 USER,并显示其参数
case WM_COPYDATA:
COPYDATASTRUCT mystr = new
COPYDATASTRUCT();
Type mytype = mystr.GetType();
mystr = (COPYDATASTRUCT) m.GetLParam(mytype);
this.textBox1.Text = mystr.lpData;
break;
default:
base.DefWndProc(ref m);
break;
}
}
}
[StructLayout(LayoutKind.Sequential)]
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
}
分享到:
相关推荐
c# wm_copydata 实现进程间通信的例子 开发环境vs2005 简单明了
不同C#之间通讯。
C# WM_消息实现进程间通信实例 运行环境 VS2008
本文实例讲述了C#使用委托(delegate)实现在两个form之间传递数据的方法。分享给大家供大家参考。具体分析如下: 关于Delegate【代理、委托】是C#中一个非常重要的概念,向前可以推演到C++的指针,向后可以延续到匿名...
C# 两个窗体之间实时传递数据的实例。利用委托和事件的方法,从子窗体传送数据到主窗体。比较安全。
使用copydata实现两个进程之间进行数据的接收以及传递功能,该实例为C#实现的进程间数据接收、发送windows消息,通用适用于C#和delphi等其他变成语言之间的进程交互......
C#写的使用WM_COPYDATE消息传送字符串的演示程序。
[C#] 进程与进程之间传递消息 窗口与窗口之间传递消息
C#winform多个窗体之间相互传递数据操作。弹出一个新窗体,选中一个数据并传递到父窗体的某个控件上,可以是TextBox也可以是DataGrideView之间相互传递数据,处理并刷新等。
包含整个SLN解决方案,绝对调试通过,详见http://blog.csdn.net/yl2isoft/article/details/20222679
C#_SendMessage_WPARAM大全.txt
.net4.0新增内存共享功能,从而很方便的实现了多进程间通信。
利用C#语言以及内存映射技术,编写了一个程序,可以实现进程间数据共享。
两个DataGridView通过委托实时传值,安全高效 C# 两个窗体之间实时传递数据的实例。利用委托和事件的方法,从子窗体传送数据到主窗体。比较安全。
还在四处寻找进程间的通信方法吗?或者想了解一下COPYDATA这个消息的使用方法? 这个Demo包含了COPYDATA的收发,非常简单易懂,一看即会:)
其中proA,proB是用wpf写的两个模拟进程程序 ShareMemLib将共享内存代码封装成lib,定义了发送者和监听者 两个进程在实例化ShareMemory时指定相同的map,并指定当前为发送者或监听者 发送者负责发送消息,监听者负责...
c# 两个进程操作一个txt,互发信息均可实现
C#多个类之间进行值传递的方法实现,有多种不同的方法可以实现
两种不同的方法实现在两个窗体之间传递参数,适用于C#普通窗体之间传递参数,