zoukankan      html  css  js  c++  java
  • WM_COPYDATA 进程间通信

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    
    /// <summary>
    /// Windows 的COPYDATA消息封装类。
    /// </summary>
    public class Messager : System.Windows.Forms.Form
    {
        /// <summary>
        /// 必需的设计器变量。
        /// </summary>
        private System.ComponentModel.Container components = null;
    
        //消息标识
        private const int WM_COPYDATA = 0x004A;
    
        //消息数据类型(typeFlag以上二进制,typeFlag以下字符)
        private const uint typeFlag = 0x8000;
    
        /// <summary>
        /// 重载CopyDataStruct
        /// </summary>
        [StructLayout(LayoutKind.Sequential)]
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            public IntPtr lpData;
        }
    
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(
                int hWnd,                    // handle to destination window
                int Msg,                     // message
                int wParam,                  // first message parameter
                ref COPYDATASTRUCT lParam    // second message parameter
                );
    
        [DllImport("User32.dll", EntryPoint = "FindWindow")]
        private static extern int FindWindow(string lpClassName, string lpWindowName);
    
        // 接收到数据委托与事件定义
        public delegate void ReceiveStringEvent(object sender, uint flag, string str);
        public delegate void ReceiveBytesEvent(object sender, uint flag, byte[] bt);
        public event ReceiveStringEvent OnReceiveString;
        public event ReceiveBytesEvent OnReceiveBytes;
    
        // 发送数据委托与事件定义
        public delegate void SendStringEvent(object sender, uint flag, string str);
        public delegate void SendBytesEvent(object sender, uint flag, byte[] bt);
        public event SendStringEvent OnSendString;
        public event SendBytesEvent OnSendBytes;
    
        public Messager()
        {
            InitializeComponent();
        }
    
        /// <summary>
        /// 清理所有正在使用的资源。
        /// </summary>
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (components != null)
                {
                    components.Dispose();
                }
            }
            base.Dispose(disposing);
        }
    
    
        #region Windows 窗体设计器生成的代码
    
        /// <summary>
        /// 设计器支持所需的方法 - 不要使用代码编辑器修改
        /// 此方法的内容。
        /// </summary>
        private void InitializeComponent()
        {
                this.SuspendLayout();
                // 
                // Messager
                // 
                this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
                this.ClientSize = new System.Drawing.Size(342, 242);
                this.Name = "Messager";
                this.ShowInTaskbar = false;
                this.WindowState = System.Windows.Forms.FormWindowState.Minimized;
                this.ResumeLayout(false);
    
        }
    
        #endregion
    
        /// <summary>
        /// 重载窗口消息处理函数
        /// </summary>
        /// <param name="m"></param>
        protected override void DefWndProc(ref System.Windows.Forms.Message m)
        {
            switch (m.Msg)
            {
                // 接收CopyData消息,读取发送过来的数据
                case WM_COPYDATA:
                    COPYDATASTRUCT cds = new COPYDATASTRUCT();
                    Type mytype = cds.GetType();
                    cds = (COPYDATASTRUCT)m.GetLParam(mytype);
                    uint flag = (uint)(cds.dwData);
                    byte[] bt = new byte[cds.cbData];
                    Marshal.Copy(cds.lpData, bt, 0, bt.Length);
                    if (flag <= typeFlag)
                    {
                        if (OnReceiveString != null)
                        {
                            OnReceiveString(this, flag, System.Text.Encoding.Default.GetString(bt));
                        }
                    }
                    else
                    {
                        if (OnReceiveBytes != null)
                        {
                            OnReceiveBytes(this, flag, bt);
                        }
                    }
                    break;
                default:
                    base.DefWndProc(ref m);
                    break;
            }
        }
    
        /// <summary>
        /// 发送字符串格式数据
        /// </summary>
        /// <param name="destWindow">目标窗口标题</param>
        /// <param name="flag">数据标志</param>
        /// <param name="str">数据</param>
        /// <returns></returns>
        public bool SendString(string destWindow, uint flag, string str)
        {
            if (flag > typeFlag)
            {
                MessageBox.Show("要发送的数据不是字符格式");
                return false;
            }
    
            int WINDOW_HANDLER = FindWindow(null, @destWindow);
            if (WINDOW_HANDLER == 0) return false;
    
            try
            {
                byte[] sarr = System.Text.Encoding.Default.GetBytes(str);
                COPYDATASTRUCT cds;
                cds.dwData = (IntPtr)flag;
                cds.cbData = sarr.Length;
                cds.lpData = Marshal.AllocHGlobal(sarr.Length);
                Marshal.Copy(sarr, 0, cds.lpData, sarr.Length);
                SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);
                if (OnSendString != null)
                {
                    OnSendString(this, flag, str);
                }
                return true;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return false;
            }
        }
    
        /// <summary>
        /// 发送二进制格式数据
        /// </summary>
        /// <param name="destWindow">目标窗口</param>
        /// <param name="flag">数据标志</param>
        /// <param name="data">数据</param>
        /// <returns></returns>
        public bool SendBytes(string destWindow, uint flag, byte[] data)
        {
            if (flag <= typeFlag)
            {
                MessageBox.Show("要发送的数据不是二进制格式");
                return false;
            }
    
            int WINDOW_HANDLER = FindWindow(null, @destWindow);
            if (WINDOW_HANDLER == 0) return false;
    
            try
            {
                COPYDATASTRUCT cds;
                cds.dwData = (IntPtr)flag;
                cds.cbData = data.Length;
                cds.lpData = Marshal.AllocHGlobal(data.Length);
                Marshal.Copy(data, 0, cds.lpData, data.Length);
                SendMessage(WINDOW_HANDLER, WM_COPYDATA, 0, ref cds);
                if (OnSendBytes != null)
                {
                    OnSendBytes(this, flag, data);
                }
                return true;
            }
    
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                return false;
            }
        }
    }
  • 相关阅读:
    js高级程序设计 笔记 --- 引用类型
    es6 简单封装一个 省市县三级下拉框
    js中元素、触点等各种距离的总结
    css实现视觉差的滚动
    js的节流和防抖
    js关于原型,原型链的面试题
    深入理解promise
    vue 同一个组件的跳转, 返回时保留原来的下拉位置
    es6 封装一个登录注册的验证滑块
    洛谷P3203 [HNOI2010]弹飞绵羊(lct)
  • 原文地址:https://www.cnblogs.com/jshchg/p/12788378.html
Copyright © 2011-2022 走看看