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;
}
}
}
}

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。
---------------------
作者:三五月儿
来源:CSDN
原文:https://blog.csdn.net/yl2isoft/article/details/20222679
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/asdyzh/p/9940468.html

时间: 2024-11-13 08:10:50

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

记一次WinForm程序中主进程打开子进程并传递参数的操作过程(进程间传递参数)

目标:想在WinForm程序之间传递参数.以便子进程作出相应的处理. 一种错误的方法 父进程的主程序: 1 ProcessStartInfo psi = new ProcessStartInfo(); 2 psi.FileName = "ProcessChild.exe"; 3 psi.Arguments = txtArgs.Text; 4 Process.Start(psi);//主要问题在这里 子进程的主程序: 1 txtArgs.Text = Process.GetCurrent

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

命题 当service经常被远程调用时,我们经常常使用到aidl来定一个接口供service和client来使用,这个事实上就是使用Binder机制的IPC通信.当client bind service成功之后,系统AM会调用回调函数onServiceConnected将service的IBinder传递给client, client再通过调用aidl生成的asInterface()方法获得service的调用接口,此时一个bind过程结束了,我们在client端就能够远程调用service的方

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

原文:C#中使用SendMessage进行进程通信的实例 1 新建解决方案SendMessageSecondExample 在解决方案下面新建两个项目:Sender和Receiver,两者的输出类型均为"Windows 应用程序".整个程序的结构如下图所示. 2 实现项目Sender Sender仅包含一个名为"消息发送者"的窗体,如下图所示. 编写窗体后端代码,如下所示. using System; using System.Diagnostics; using

进程间传递文件描述符

下面的实例展示了如何使用Unix域套接字在进程间传递文件描述符 参考文献:1) <Unix网络编程> 2)  http://book.51cto.com/art/200912/168560.htm 最近学习了使用Unix域套接字在进程间传递文件描述符,仿照参考资料,自己也写了简单的程序来实践这种技术. 其他不多说了,具体理论知识参见参考资料,开始我自己的程序介绍(在OpenSolaris 2009.06平台上测试): 1  程序作用说明:父进程,子进程以及另外一个进程向同一个文件的文件描述符向

WPF 进程间传递参数

WPF 进程间传递参数 在软件开发中有时需要在一个软件中启动另一个软件,这时用Process.Start("软件路径")可以启动另一个软件.如果在这个过程中还需要传递一些参数给新启动的软件,可以通过WPF中的Application_Startup来完成: 首先,在需要启动的WPF项目中的APP中注册Application_Startup事件: private void Application_Startup(object sender, StartupEventArgs e) { if

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

先引入一个例子,该程序的目的是子进程向父进程传递文件描述符,并通过该文件描述符读取buf. #include <func.h> int main(){ int fds[2]; pipe(fds); if(!fork()){ close(fds[1]); int fd; read(fds[0], &fd, sizeof(fd)); printf("child fd = %d\n", fd); char buf[128] = {0}; read(fd, buf, siz

在进程间传递文件描述符

由于fork调用之后,父进程中打开的文件描述符在子进程中仍然保持打开,所以文件描述符可以很方便地从父进程传递到子进程.需要注意的是,传递一个文件描述符并不是传递一个文件描述符的值,而是要在接收进程中创建一个新的文件描述符,并且该文件描述符和发送进程中被传递的文件描述符指向内核中相同的文件表项. 在Linux下,我们可以利用UNIX城socket在进程间传递特殊的辅助数据,以实现文件描述符的传递,它在子进程中打开一个文件描述符,然后将它传递给父进程,父进程则通过读取该文件描述符来获得文件的内容.

Android程序中Acticity间传递数据

在Android开发过程中,在不同的Acitivity之间传递数据的情况是非常常见的.我花费了一点时间来总结Acitivity之间的数据传递,记录下来. 1.简单传递键值对 这种传递方式非常简单,只需要在构造Intent加入相应的键值对. 在ActivityA中,调用Intent的代码如下: 1 Intent i = new Intent(ActivityA.this,ActivityB.class); 2 i.putExtra("name", "Finlay Liu&quo

windows核心编程之进程间共享数据

有时候我们会遇到window进程间共享数据的需求,例如说我想知道系统当前有多少某个进程的实例. 我们能够在程序中定义一个全局变量.初始化为0.每当程序启动后就加1.当然我们我们能够借助第三方介质来储存这个变量,然后解析. 这样做必须做到先写入后解析.不能实时更新数据.假设不考虑其它储存介质.仅仅是进程中的通信,应该怎么做呢?windows提供了一些可行的方法,以下介绍经常使用的两种. 一.共享数据段 #include "stdafx.h" #include <Windows.h&