C# Winform 多个程序之间的通信(非Scoket)

效果

功能:打开窗体自动连接主程序,并自动添加到列表,可以向子程序群发消息

https://img-blog.csdnimg.cn/055db25deb484d248a460db071dbea45.gif

可以向单个程序单独发送消息

https://img-blog.csdnimg.cn/8c71c63fa44b4f038060f88664973a1d.gif

在退出程序后,添加的程序列表会自动移除

https://img-blog.csdnimg.cn/5496486a149647d5a7f83d5b0119a6f1.gif

一、概述

参考:C# Winfrom程序之间通讯_c# sendmessege copydatastruct 返回多个值_熊思宇的博客-CSDN博客

在之前我写过 winform 程序与程序之间的通信,但是这个版本有个问题,那就是只能由两个程序进行通信,同时打开多个程序的话,接收方收到的数据就会一模一样,这次发表这个教程,也就是要解决这个问题。

归根结底,还是 FindWindow这个函数的用法没用对,下面是对应的解释:

函数获得一个顶层窗体的句柄,该窗体的类名和窗体名与给定的字符串相匹配。这个函数不查找子窗体。在查找时不区分大写和小写。 函数原型

int FindWindow(string lpClassName, string lpWindowName)

在测试中,我发现,如果用 FindWindow 这个函数去寻找对应的窗体,如果哪个窗体打开了多个,那么每个窗体的句柄就是一样的,解决这个问题也很简单,不用就行了。

有人可能会问,这种通信方式有什么用呢?主要用途当然是通信啦,因为使用 Scoket 通信有一定的难度,TCP 协议写起来也比较复杂,网上的资料也少,并且都很基础,程序运行一段时间就会自动退出,或者自动掉线,这个是很常见的事。

二、实现需求

新建一个 .Net Framework 的 Winform 项目,这次实现一个主程序和多个子程序通信的案例。

主程序的界面

https://img-blog.csdnimg.cn/a36897962538441bb6d77f3923f3b72d.png

后面源码我会提供,先可以不用管这些控件的具体参数

Form1 代码

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace 程序之间的通信
{
   
    public partial class Form1 : Form
    {
   
        public Form1()
        {
   
            InitializeComponent();
        }

        #region 字段

        public struct CopyDataStruct
        {
   
            public IntPtr dwData;
            public int cbData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        //当一个应用程序传递数据给另一个应用程序时发送此消息指令
        public const int WM_COPYDATA = 0x004A;

        //在DLL库中的发送消息函数
        [DllImport("User32.dll", EntryPoint = "SendMessage")]
        private static extern int SendMessage(int hWnd, int Msg, int wParam, ref CopyDataStruct lParam);

        /// <summary>
        /// 句柄列表
        /// </summary>
        List<int> IntPtrList = new List<int>();

        #endregion


        #region 窗体相关

        private void Form1_Load(object sender, EventArgs e)
        {
   
            TextBox_IntPtr.Text = this.Handle.ToString();
        }

        #endregion

        #region 按钮相关

        /// <summary>
        /// 发送
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Send_Click(object sender, EventArgs e)
        {
   
            if (IntPtrList.Count == 0)
            {
   
                Console.WriteLine("句柄列表为空");
                return;
            }

            //将文本框中的值, 发送给接收端           
            string message = TextBox_Message.Text;
            if (string.IsNullOrEmpty(message))
            {
   
                Console.WriteLine("消息输入框不能为空");
                return;
            }

            CopyDataStruct cds;
            cds.dwData = (IntPtr)1; //这里可以传入一些自定义的数据,但只能是4字节整数      
            cds.lpData = message;    //消息字符串
            cds.cbData = System.Text.Encoding.Default.GetBytes(message
  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值