如何在C#用WM

进程|数据

简介:

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

时间: 2016-05-07

如何在C#用WM的相关文章

如何在ubuntu14.04上安装轻量级的Budgie桌面(v8)

如何在ubuntu14.04上安装轻量级的Budgie桌面(v8) Budgie是为Linux发行版定制的旗舰桌面,也是一个定制工程.为思想前卫的用户设计,致力于简单和简洁.它的一个巨大优势是它不是别的项目的fork版本,是从都到尾都独立的. Budgie 桌面环境 Budgie桌面与GNOME栈紧密结合,使用先进的技术从而提供一个可选择的桌面体验.出于开源理念,这个桌面之后也能在别的Linux发行版中看到. 现在Budgie能够通过面板的设置达到和GNOME2桌面相似的使用体验. 0.8版的特

SAP WM Production Schedule Profile设置问题导致生产补货的TO单自动创建问题

SAP WM Production Schedule Profile设置问题导致生产补货的TO单自动创建问题   笔者所在的D项目上,业务人员希望工单一旦release,自动触发为生产补货的TR单.然后业务人员手工将TR 转成TO单把物料从仓库到产线边上(storage type 100).   按照客户的需求,我做好了配置,准备好了相关主数据.在我测试的时候,发现了一个问题,困扰了我半天.   我CO01创建了工单并下达之后,却发现TR产生了,同时自动创建了TO单!     保存,   看这个

SAP WM LP10 创建TO单据的时候,系统根据目的地100下的库存自动扣减TO里的数量?

SAP WM LP10 创建TO单据的时候,系统根据目的地Storage Type 100下的库存自动扣减TO里的数量   LP10将TR转成TO单据的时候,我们常常发现,生成的TO单据里的数量并不是等于TR里的数量,而是系统自动根据目的地storage type 100下的库存数量自动扣减之后的数量作为生成的TO的数量.原因何在?     下一步,   下一步,     勾选100 Storage Type 下的Deactivate qty reduction 选项即可避免此种情况的出现.  

word文档-如何在360浏览器中直接 打开word文件 ?

问题描述 如何在360浏览器中直接 打开word文件 ? 在IE浏览器中可以.碰到WORD文档,自动就下载了!为什么? 解决方案 需要有浏览器插件,IE一般有OFFICE插件,所以可以直接打开 解决方案二: 因为360是非法流氓软件,它根本就是粗陋地用IE的内核拼凑了一个山寨的浏览器,做一个稍微有点用的软件功能只是它实施违法犯罪侵害用户计算机和数据的幌子而已. 解决方案三: 这个好像需要转换吧.吧word转成pdf格式的然后在线显示!

servlet-如何在sevlet中弹出提示框?

问题描述 如何在sevlet中弹出提示框? 我想在我的servlet:Login.java中弹出提示框?该怎么写? 解决方案 在servlet方法中写入out.print("alert(0);"); 解决方案二: ajax中弹出提示框 解决方案三: http://xiehx163.blog.163.com/blog/static/6146679620096105212377/ 参考.

格式 webp-谷歌的webp图片格式如何在windows下使用java转换成其他格式

问题描述 谷歌的webp图片格式如何在windows下使用java转换成其他格式 参考了http://blog.csdn.net/geeklei/article/details/41147479,可以在linux下成功执行,但是在windows下编译出dll和jar始终无法正确运行java.lang.IllegalArgumentException: image == null!无法识别这样的图片格式 解决方案 Java webp转jpg webp是最近google推出的新的图片格式 googl

openni opencv linux-如何在linux下建立一个着openni和opencv的工程?

问题描述 如何在linux下建立一个着openni和opencv的工程? 如何在linux下建立一个着openni和opencv的工程?麻烦大神们详细解说下,不胜感激!!!!

qt-如何在QSqlQueryModel中实现增删查改,然后如何与mysql数据库同步更新

问题描述 如何在QSqlQueryModel中实现增删查改,然后如何与mysql数据库同步更新 本人是个菜鸟在做一个简单的同学录系统,这是进入之后的界面 我想实现鼠标选取一个表格点击"修改同学信息"之后能对它在修改并且修改确定后能同步刷新MySQL数据库而且表格中的数据也更新. 下面是我的代码:#include ""record.h""#include ""ui_record.h""#include &qu

如何在Word背景图片上打字

  如何在Word背景图片上打字          方法/步骤 首先建立一个Word文档并打开. 添加一个背景图片,粘贴复制就行. 接着选择插入文本框.插入后在文本框中输入你要输入的内容. 将文本框拖到你需要的地方,接着选中文本档-右单击选择-设置文本框格式,将填充选项中颜色设置为白色.