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


    新建解决方案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;

                }

            }

        }

    }

    运行结果

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

     

     

    实例说明

    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。

  • 相关阅读:
    跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探
    跟我学SpringCloud | 第十一篇:使用Spring Cloud Sleuth和Zipkin进行分布式链路跟踪
    跟我学SpringCloud | 第十篇:服务网关Zuul高级篇
    跟我学SpringCloud | 第九篇:服务网关Zuul初
    跟我学SpringCloud | 第八篇:Spring Cloud Bus 消息总线
    跟我学SpringCloud | 第七篇:Spring Cloud Config 配置中心高可用和refresh
    跟我学SpringCloud | 第六篇:Spring Cloud Config Github配置中心
    跟我学SpringCloud | 第五篇:熔断监控Hystrix Dashboard和Turbine
    跟我学SpringCloud | 第四篇:熔断器Hystrix
    跟我学SpringCloud | 第三篇:服务的提供与Feign调用
  • 原文地址:https://www.cnblogs.com/lgx5/p/6695506.html
Copyright © 2020-2023  润新知