首 页 | 新 闻 | 技术中心 | 第二书店 | 《程序员》 | 《开发高手》 | 社 区 | 黄 页 | 人 才
移 动专 题SUNIBM微 软微 创精 华Donews人 邮
我的技术中心 
我的分类 我的文档
全部文章 发表文章
专栏管理 使用说明



 RSS 订阅 
最新文档列表
Windows/.NET
.NET  (rss)    
Visual C++  (rss)    
Delphi  (rss)    
Visual Basic  (rss)    
ASP  (rss)    
JavaScript  (rss)    
Java/Linux
Java  (rss)    
Perl  (rss)    
综合
其他开发语言  (rss)    
文件格式  (rss)    
企业开发
游戏开发  (rss)    
网站制作技术  (rss)    
数据库
数据库开发  (rss)    
软件工程
其他  (rss)    

积极原创作者 
wangchinaking (57)
yjz0065 (113)
coofucoo (105)
Drate (69)
lphpc (30)
smallnest (61)
iiprogram (64)
downmoon (32)
danny_xcz (49)
btbtd (81)
CSDN - 文档中心 - .NET 阅读:7157   评论: 12    参与评论
标题   如果在C#用WM_COPYDATA消息来实现两个进程之间传递数据     选择自 TheAres 的 Blog
关键字   C# WM_COPYDATA sendmessage
出处  

简介:

本文着重讲述了如果用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;
 }
}


相关文章
对该文的评论
walkline ( 2006-01-27)
请问,用这个方法,两个进程必须都是自己写的程序才能接收消息,如果是从任意指定的一个程序中获得比如图片之类的信息,用这个方法可以吗?
望回复:walkline@gmail.com
CSDN 网友 ( 2005-01-09)
能否把"发送方"再贴一遍,上面的都是乱码
CSDN 网友 ( 2005-01-09)
接收不到,我在发送方发送了字符串,在接收方没有任何反应
CSDN 网友 ( 2004-08-17)
如果只知道进程名字,而不知道lpWindowName呢?
hxhbluestar ( 2004-02-25)
至少我觉得有用