原文:C#中使用SendMessage在进程间传递数据的实例

1 新建解决方案SendMessageExample

在解决方案下面新建三个项目:CopyDataStruct,Receiver和Sender。

其中,CopyDataStruct项目的输出类型为“类库”,Receiver和Sender项目的输出类型为“Windows 应用程序”。

整个实例程序的结构如下图所示。

2 CopyDataStruct项目实现

定义结构体COPYDATASTRUCT,代码如下所示。

using System;
using System.Runtime.InteropServices; namespace CopyDataStruct
{
public struct COPYDATASTRUCT
{
public IntPtr dwData;
public int cbData;
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
}

编译CopyDataStruct项目生成dll,再在Receiver和Sender项目中添加对此dll的引用。

3 Sender项目实现

Sender项目仅包含一个名称为“消息发送者”的窗体,如下图所示。

编写窗体后端代码,如下所示。

using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using CopyDataStruct; namespace Sender
{
public partial class frmSender : Form
{
//Win32 API函数
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam); [DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern int FindWindow(string lpClassName, string lpWindowName); const int WM_COPYDATA = 0x004A; public frmSender()
{
InitializeComponent();
} private void btnSend_Click(object sender, EventArgs e)
{
int hWnd = FindWindow(null, @"消息接受者");
if (hWnd == 0)
{
MessageBox.Show("555,未找到消息接受者!");
}
else
{
byte[] sarr = System.Text.Encoding.Default.GetBytes(txtString.Text);
int len = sarr.Length;
COPYDATASTRUCT cds;
cds.dwData = (IntPtr)Convert.ToInt16(txtInt.Text);//可以是任意值
cds.cbData = len + 1;//指定lpData内存区域的字节数
cds.lpData = txtString.Text;//发送给目标窗口所在进程的数据
SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
}
}
}
}

4  Receiver项目实现

Receiver项目仅包含一个名称为“消息接受者”的窗体,如下图所示。

编写窗体的后端代码,如下所示。

using System;
using System.Windows.Forms;
using CopyDataStruct; namespace Receiver
{
public partial class frmReceiver : Form
{
const int WM_COPYDATA = 0x004A;
public frmReceiver()
{
InitializeComponent();
} protected override void DefWndProc(ref Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT cds = new COPYDATASTRUCT();
Type t = cds.GetType();
cds = (COPYDATASTRUCT)m.GetLParam(t);
string strResult = cds.dwData.ToString() + ":" +cds.lpData;
lsvMsgList.Items.Add(strResult);
break;
default:
base.DefWndProc(ref m);
break;
}
}
}
}

5 运行结果

运行消息发送和消息接收程序(Sender.exe和Receiver.exe),效果如下图所示。

6 实例说明

6.1 SendMessage方法参数说明

  • hWnd:接收消息的窗口的句柄
  • Msg:消息标识符
  • wParam:32位的特定附加信息,具体取决于消息
  • lParam:32位特定附加信息,具体取决于消息

6.2 WM_COPYDATA消息说明

使用WM_COPYDATA消息,lParam参数可以指向一个 COPYDATASTRUCT结构体类型的变量。

typedef struct COPYDATASTRUCT{
  ULONG_PTR dwData; //可以是任意值
  DWORD cb_data; //指定lpData内存区域的字节数
  PVOID lpData; //发送给目录窗口所在进程的数据
}COPYDATASTRUCT;

若定义的结构体不满足上面的定义,在接收端无法正确获取lParam参数指向的数据。

另外,WM_COPYDATA消息的标识符为0x004A。

C#中使用SendMessage在进程间传递数据的实例的更多相关文章

  1. Linux 利用管道父子进程间传递数据

    [原文] fork()函数:用于创建子进程,子进程完全复制父进程的资源,相当于父进程的拷贝.具体理解,运用父进程的同一套代码,通过判断进程ID来执行不同进程的不同任务. 返回值正常为子进程ID,出错返 ...

  2. 使用 WM_COPYDATA 在进程间共享数据

    开发中有时需要进程间传递数据,比如对于只允许单实例运行的程序,当已有实例运行时,再次打开程序,可能需要向当前运行的实例传递信息进行特殊处理.对于传递少量数据的情况,最简单的就是用SendMessage ...

  3. 用WM_COPYDATA消息来实现两个进程之间传递数据

    文着重讲述了如果用WM_COPYDATA消息来实现两个进程之间传递数据. 进程之间通讯的几种方法:在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.常用的方法有   1.使用内存映射 ...

  4. IBinder对象在进程间传递的形式(一)

    命题 当service经常被远程调用时,我们经常常使用到aidl来定一个接口供service和client来使用,这个事实上就是使用Binder机制的IPC通信.当client bind servic ...

  5. C#中使用SendMessage进行进程通信的实例

    原文:C#中使用SendMessage进行进程通信的实例 1 新建解决方案SendMessageSecondExample 在解决方案下面新建两个项目:Sender和Receiver,两者的输出类型均 ...

  6. 进程间传递文件描述符——sendmsg和recvmsg函数

    先引入一个例子,该程序的目的是子进程向父进程传递文件描述符,并通过该文件描述符读取buf. #include <func.h> int main(){ int fds[2]; pipe(f ...

  7. WPF 进程间传递参数

    WPF 进程间传递参数          在软件开发中有时需要在一个软件中启动另一个软件,这时用Process.Start(“软件路径”)可以启动另一个软件.如果在这个过程中还需要传递一些参数给新启动 ...

  8. 进程间传递文件描述符fd

    众所周知,子进程会继承父进程已经打开的文件描述符fd,但是fork之后的是不会被继承的,这个时候是否无能无力了?答应是NO.Linux提供了一个系统调用sendmsg,借助它,可以实现进程间传递文件描 ...

  9. Android学习笔记_23_服务Service之AIDL和远程服务实现进程通信以及进程间传递自定义类型参数

    一.了解AIDL语言: 在Android中, 每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢? 显然, Java中是不支持跨进程内存共享的.因此要传递对象, 需要把对象解析 ...

随机推荐

  1. 2015第25周三iframe小结

    一个 HTML页面可以有一个或多个子框架,这些子框架以<iframe>来标记,用来显示一个独立的HTML页面.这里所讲的框架编程包括框架的自我控制以及框架之间的互相访问,例如从一个框架中引 ...

  2. 上海游侠电动汽车团队招募。iOS,Android,产品经理以及 SEVER 端工程师 - V2EX

    上海游侠电动汽车团队招募.iOS,Android,产品经理以及 SEVER 端工程师 - V2EX 上海游侠电动汽车团队招募.iOS,Android,产品经理以及 SEVER 端工程师

  3. JDBC编程之事务处理

    JDBC中的事务处理指的是事务的一致性等问题,例如插入一条数据(id,name,password)到表中,另一条数据(address,id)到另一张表中,并且两条数据是相关联的,那么假设第一条数据插入 ...

  4. Servlet问题:servlet cannot be resolved to a type解决办法

    工程里的路径权限高,并且eclipse并到classpath里寻找jar位置,所以我就到我的java项目里 项目名-->右键 Property-->选择 Java Build Path-- ...

  5. 视图的touch事件的传播控制

    在视图控制器类中.self.view中会包含多个多层的自己定义视图. 我自己定义了一个uicollectionview类,名称为gridview,又自己定义了一个uicollectionviewcel ...

  6. C语言 对数组名取地址

    作者 : 卿笃军 你有没有想过,对一个一维数组名取地址,然后用这个地址进行加减运算.这会出现什么样的结果呢? 演示样例: int a[5] = {1,2,3,4,5}; int *p = (int * ...

  7. Myeclipse 中添加mysql的jdbc驱动

    打开myeclipse后单击菜单栏中的myeclipse——>preferences 然后在Myeclipse Enterprise workbench下的Java Enterprise Pro ...

  8. 设计模式17---设计模式之模板方法模式(Template Method)(行为型)

    1.场景模拟 使用软件模拟登录控制,普通用户和工作人员用户,工作人员的密码在数据库中是加密的. 步骤大致如下: 前台提交,后台获取登录信息,同数据库中的登陆信息进行比较,只不过工作人员是加密的,普通用 ...

  9. PLSQL Developer安装(Oracle11g+win7_64bit)

    1)安装Oracle 11g 64位 2)安装32位的Oracle客户端( instantclient-basic-win32-11.2.0.1.0)下载地址:http://www.oracle.co ...

  10. (原)anaconda 的安装与在pycharm中的版本切换

    参考网页: http://continuum.io/blog/anaconda-python-3 http://conda.pydata.org/docs/intro.html#creating-py ...