使用WM_COPYDATA消息在不同进程间或窗口间通信传递数据

WM_COPYDATA消息类型属于windows系统标准消息类型,主要用于进程间或不同窗口间进行信息传递,使用此消息的同时在接收端需要重写窗口的消息处理函数DefWndProc,以便读取消息内容。

为便于使用,本人写了个MySendMessage及MySendMessageByte辅助类实现消息功能。MySendMessage类可传递string类型消息,MySendMessageByte类可传递byte[]类型消息。

里面提供了3种发送方法:窗口句柄、窗口名称(标题)、进程ID等方式传递消息。以下是源代码(代码结尾处有使用示例参考):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;

namespace test
{
    /// <summary>
    /// 使用本类发生窗口消息,需要接收窗口重写消息处理函数DefWndProc,以便读取消息内容
    /// </summary>
    class MySendMessage
    {
        public struct COPYDATASTRUCT
        {
            /// <summary>
            /// 消息附加标识(可自定义用途)
            /// </summary>
            public IntPtr dwData;
            /// <summary>
            /// 消息内容长度
            /// </summary>
            public int cbData;
            /// <summary>
            /// 消息内容
            /// </summary>
            [MarshalAs(UnmanagedType.LPStr)] public string lpData;
        }

        
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, // handle to destination window
                                                uint Msg, // message
                                                uint wParam, // first message parameter
                                                ref COPYDATASTRUCT lParam // second message parameter
                                                );

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        public const int WM_COPYDATA = 0x004A;//系统特定的消息类型
        /// <summary>
        /// 向指定窗体发送消息
        /// </summary>
        /// <param name="hWnd">窗体句柄</param>
        /// <param name="msg">要发送的消息内容</param>
        /// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
        /// <returns></returns>
        public static int send(IntPtr hWnd,string msg, int flag = 0)
        {
            COPYDATASTRUCT cds = new COPYDATASTRUCT();
            cds.dwData = (IntPtr)flag;
            cds.cbData = System.Text.Encoding.Default.GetByteCount(msg)+1;
            cds.lpData = msg;
            return SendMessage(hWnd, WM_COPYDATA,0,ref cds);
        }
        /// <summary>
        /// 向指定进程的主窗体发送消息
        /// </summary>
        /// <param name="processID">进程ID号</param>
        /// <param name="msg">要发送的消息内容</param>
        /// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
        /// <returns></returns>
        public static int send(int processID,string msg, int flag = 0)
        {
            System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(processID);
            IntPtr hWnd = p.MainWindowHandle;
            return send(hWnd, msg,flag);
        }
        /// <summary>
        /// 向指定窗体发送消息
        /// </summary>
        /// <param name="title">目标窗体的标题</param>
        /// <param name="msg">要发送的消息内容</param>
        /// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
        /// <returns></returns>
        public static int send(string title,string msg, int flag = 0)
        {
            IntPtr hWnd = FindWindow(null, title);
            return send(hWnd, msg, flag);
        }

    }

    /// <summary>
    /// 使用本类发生窗口消息,需要接收窗口重写消息处理函数DefWndProc,以便读取消息内容
    /// </summary>
    class MySendMessageByte
    {
        public struct COPYDATASTRUCT
        {
            /// <summary>
            /// 消息附加标识(可自定义用途)
            /// </summary>
            public IntPtr dwData;
            /// <summary>
            /// 数据大小
            /// </summary>
            public int cbData;
            /// <summary>
            /// 数据地址(指针)
            /// </summary>
            public IntPtr lpData;
        }


        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(IntPtr hWnd, // handle to destination window
                                                uint Msg, // message
                                                uint wParam, // first message parameter
                                                ref COPYDATASTRUCT lParam // second message parameter
                                                );

        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        public const int WM_COPYDATA = 0x004A;//系统特定的消息类型
        /// <summary>
        /// 向指定窗体发送消息
        /// </summary>
        /// <param name="hWnd">窗体句柄</param>
        /// <param name="data">要发送的消息内容</param>
        /// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
        /// <returns></returns>
        public static int send(IntPtr hWnd, byte[] data, int flag=0)
        {
            COPYDATASTRUCT cds = new COPYDATASTRUCT();
            cds.dwData = (IntPtr)flag;
            cds.cbData = data.Length;
            cds.lpData = Marshal.UnsafeAddrOfPinnedArrayElement(data,0);
            return SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
        }
        /// <summary>
        /// 向指定进程的主窗体发送消息
        /// </summary>
        /// <param name="processID">进程ID号</param>
        /// <param name="data">要发送的消息内容</param>
        /// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
        /// <returns></returns>
        public static int send(int processID, byte[] data, int flag = 0)
        {
            System.Diagnostics.Process p = System.Diagnostics.Process.GetProcessById(processID);
            IntPtr hWnd = p.MainWindowHandle;
            return send(hWnd, data,flag);
        }
        /// <summary>
        /// 向指定窗体发送消息
        /// </summary>
        /// <param name="title">目标窗体的标题</param>
        /// <param name="data">要发送的消息内容</param>
        /// <param name="flag">可选项:消息附加标识(可自定义用途)</param>
        /// <returns></returns>
        public static int send(string title, byte[] data, int flag = 0)
        {
            IntPtr hWnd = FindWindow(null, title);
            return send(hWnd, data, flag);
        }

    }
    /* 使用示例一:发送字符串消息
    MySendMessage.send(process.MainWindowHandle, str);//向窗口发送字符串消息


    //接收窗口要重写消息处理函数DefWndProc,以便处理消息内容
    protected override void DefWndProc(ref System.Windows.Forms.Message m)
    {
        switch (m.Msg)
        {
            case MySendMessage.WM_COPYDATA:
                MySendMessage.COPYDATASTRUCT cds = new MySendMessage.COPYDATASTRUCT();
                Type mytype = cds.GetType();
                cds = (MySendMessage.COPYDATASTRUCT)m.GetLParam(mytype);
                string str=cds.lpData;                
                break;
            default:
                base.DefWndProc(ref m);
                break;
        }
    }
     //*/

    /* 使用示例二:发送字节型数据
     MySendMessageByte.send(process.MainWindowHandle, System.Text.Encoding.Default.GetBytes(str));//向窗口发送字节数据

    //接收窗口要重写消息处理函数DefWndProc,以便处理消息内容
    protected override void DefWndProc(ref System.Windows.Forms.Message m)
    {
        switch (m.Msg)
        {
            case MySendMessageByte.WM_COPYDATA:                    
                MySendMessageByte.COPYDATASTRUCT cds = new MySendMessageByte.COPYDATASTRUCT();
                Type mytype = cds.GetType();
                cds = (MySendMessageByte.COPYDATASTRUCT)m.GetLParam(mytype);
                byte[] data = new byte[cds.cbData];
                Marshal.Copy(cds.lpData, data, 0, cds.cbData);                    
                string str=System.Text.Encoding.Default.GetString(data);
                break;
            default:
                base.DefWndProc(ref m);
                break;
        }
    }
     //*/
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzl_li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值