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

原文: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。

 

时间: 2024-10-27 18:04:57

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

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

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

c-C语言:进程间传递指针来实现数据操作是否会有安全隐患?

问题描述 C语言:进程间传递指针来实现数据操作是否会有安全隐患? 涉及两个进程,A和B,A和B可通信. 进程A管理一个链表,A会把某个链表节点的一些特征参数发送给进程B,后面进程B会把一开始得到的节点特征发送回A,A再对链表进行遍历匹配,匹配对应的节点,进行操作. 如果A一开始把节点指针直接给B,B后面需要对节点操作时直接把指针发回给A,这样就不用遍历链表.但是这样做是不是不合理?就是是不是有安全性之类的问题? 解决方案 跨进程传递指针没有意义,对方进程拿到指针也访问不了内存.既然如此,为何要传

事件和进程间的数据交换 .

//======================================================================== //TITLE: //    事件和进程间的数据交换 //AUTHOR: //    norains //DATE: //    Monday  13-July-2009 //Environment: //    WINCE5.0 + VS2005 //================================================

在.net中轻松掌握Windows窗体间的数据交互

window|交互|数据 Windows 窗体是用于 Microsoft Windows 应用程序开发的.基于 .NET Framework 的新平台.此框架提供一个有条理的.面向对象的.可扩展的类集,它使您得以开发丰富的 Windows 应用程序.一个Windows窗体就代表了.NET架构里的System.Windows.Forms.Form类的一个实例. 作者在CSDN技术论坛.NET板块下的C#分类经常看到有人问起如何在两个Form间传递数据,访问修改对方窗体里面的值.对于有经验的程序员来

在.net中轻松掌握Windows窗体间的数据交互(一)

window|交互|数据 在.net中轻松掌握Windows窗体间的数据交互(一) zhzuo(秋枫) Windows 窗体是用于 Microsoft Windows 应用程序开发的.基于 .NET Framework 的新平台.此框架提供一个有条理的.面向对象的.可扩展的类集,它使您得以开发丰富的 Windows 应用程序.一个Windows窗体就代表了.NET架构里的System.Windows.Forms.Form类的一个实例. 作者在CSDN技术论坛.NET板块下的C#分类经常看到有人问

在.net中轻松掌握Windows窗体间的数据交互(二)

window|交互|数据 在.net中轻松掌握Windows窗体间的数据交互(二) zhzuo(秋枫) <在.net中轻松掌握Windows窗体间的数据交互(一)>一文中我们讲了使用带参数的构造函数来实现窗体间的数据传递,我认为是用的比较多的一种,接下来让我们看看另外两种实现方法. 二.给窗体添加属性或方法 1.使用Form类的Owner属性 获取或设置拥有此窗体的窗体.若要使某窗体归另一个窗体所有,请为其 Owner 属性分配一个对将成为所有者的窗体的引用.当一个窗体归另一窗体所有时,它便随

windows phone页面间传递数据

 页面间传递数据包括两个问题1.如何从源页面传递数据到目标页面?下面例子提供解决上面问题的方案.源页面MainPage.xaml内容区域包含一个TextBlock,如<TextBlock HorizontalAlignment="Center" Name="txt1" Text="navigate to 2nd page" VerticalAlignment="Center" ManipulationStarted=&q

各位大神们,求助求助!窗口间传递数据!!

问题描述 本人只学习过C语言,对.NET几乎小白.自己看了些资料做了个软件,是毕业设计!现在需要在两个窗口间传递数据,查看了好多资料看的我云里雾里,没办法,实在是不懂!希望从Form1中将数组传递到Form2中去,我把(自己认为的)一些没必要的代码我就删去了,免得大家看的麻烦!就是将Form1最下面申请的buf内存地址传递给Form2中最下面的huidu数组,只要告诉我怎么写代码就可以了,顺便说出方法就更好了,谢谢!对了,Form1和Form2不是MDI父子关系,因为设成MDI父子关系,Form

在不同窗体间传递数据

问题描述 想在不同窗体间传递数据,已经试过构造函数了,还想试一下用属性传递,但是我在第一个窗体中查看该属性的值是有变化的,但在第二个窗体中,却无法得到该值,该属性值为空,请问为什么? 解决方案 解决方案二:那你在第一个窗体调用第二个窗体的时候中有没有把属性值传给第二个窗体呢?解决方案三:引用1楼jsnjlhb的回复: 那你在第一个窗体调用第二个窗体的时候中有没有把属性值传给第二个窗体呢? 构造方法?重载构造方法是可以的我是说,单独建立一个类用于接收和传递属性值,在第二个窗体中初始化第一个窗体对象