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

2021-07-02 01:34

阅读:358

标签:接受   实现   win   ring   classname   获取   switch   err   输出   

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
版权声明:本文为博主原创文章,转载请附上博文链接!

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

标签:接受   实现   win   ring   classname   获取   switch   err   输出   

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


评论


亲,登录后才可以留言!