You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#蓝牙串口共享绘图板故障:连接异常且鼠标轨迹不显示

基于C#的蓝牙串口共享绘图板问题求助

我开发了一个基于C#的类Paint项目,通过蓝牙Serial Port实现两台电脑间绘图板共享,但目前存在两个问题:

  • 绘图时无法显示鼠标轨迹
  • 串口连接无法正常建立

项目代码

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO.Ports;
using System.Linq;
using System.Windows.Forms;

namespace Paint_Comunicacion_Serial_C_
{
    public partial class frmMain : Form
    {
        private bool dibujando = false;
        private Point ultimoPunto = Point.Empty;
        private List<Point> bufferPuntos = new List<Point>();
        private const string mensajeSolicitudConexion = "SOLICITUD_CONEXION";
        private const string mensajeConfirmacionConexion = "CONFIRMACION_CONEXION";

        public frmMain()
        {
            InitializeComponent();
        }

        private void frmMain_Load(object sender, EventArgs e)
        {
            pbxDibujo.BackColor = Color.White;
            pbxDibujo.BorderStyle = BorderStyle.FixedSingle;

            pbxDibujo.Width = 650;
            pbxDibujo.Height = 328;

            pbxDibujo.Image = new Bitmap(pbxDibujo.Width, pbxDibujo.Height);

            ActualizarPuertos();

            spSerial.BaudRate = 9600;
            spSerial.Parity = Parity.None;
            spSerial.DataBits = 8;
            spSerial.StopBits = StopBits.One;

            tmrActualizacion.Interval = 5000;
            tmrActualizacion.Tick += tmrActualizacion_Tick;
            tmrActualizacion.Start();
        }

        private void ActualizarPuertos()
        {
            string puertoSeleccionado = cbxPuertos.SelectedItem?.ToString() ?? "";

            cbxPuertos.Items.Clear();
            string[] puertos = SerialPort.GetPortNames();
            cbxPuertos.Items.AddRange(puertos);

            if (puertos.Contains(puertoSeleccionado))
            {
                cbxPuertos.SelectedItem = puertoSeleccionado;
            }
            else if (puertos.Length > 0)
            {
                cbxPuertos.SelectedIndex = 0;
            }
        }

        private void tmrActualizacion_Tick(object sender, EventArgs e)
        {
            ActualizarPuertos();
        }

        private void btnConectar_Click(object sender, EventArgs e)
        {
            if (cbxPuertos.SelectedIndex >= 0)
            {
                try
                {
                    if (spSerial.IsOpen)
                        spSerial.Close();

                    spSerial.PortName = cbxPuertos.SelectedItem.ToString();
                    spSerial.Open();
                    MessageBox.Show("Conexión establecida.");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Error al conectar: " + ex.Message);
                }
            }
            else
            {
                MessageBox.Show("Por favor, selecciona un puerto serial.");
            }
        }

        private void btnDesconectar_Click(object sender, EventArgs e)
        {
            if (spSerial.IsOpen)
            {
                spSerial.Close();
            }
        }

        private void btnLimpiar_Click(object sender, EventArgs e)
        {
            pbxDibujo.Image = new Bitmap(pbxDibujo.Width, pbxDibujo.Height);
        }

        private void pbxDibujo_MouseDown(object sender, MouseEventArgs e)
        {
            dibujando = true;
            ultimoPunto = e.Location;
        }

        private void pbxDibujo_MouseMove(object sender, MouseEventArgs e)
        {
            if (!dibujando) return;

            if (dibujando)
            {
                if (pbxDibujo.Image == null)
                {
                    
                    pbxDibujo.Image = new Bitmap(pbxDibujo.Width, pbxDibujo.Height);
                }

                using (Graphics g = Graphics.FromImage(pbxDibujo.Image))
                {
                    g.DrawLine(Pens.Black, ultimoPunto, e.Location);
                }
                pbxDibujo.Refresh(); 
                ultimoPunto = e.Location; 
                bufferPuntos.Add(e.Location); 
            }
        }

        private void pbxDibujo_MouseUp(object sender, MouseEventArgs e)
        {
            dibujando = false;

            if (spSerial != null && spSerial.IsOpen && bufferPuntos.Any())
            {
                string puntosSerializados = string.Join(";", bufferPuntos.Select(p => $"{p.X},{p.Y}"));
                spSerial.WriteLine(puntosSerializados);
                bufferPuntos.Clear();
            }
        }

        private void spSerial_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            string datosEntrada = spSerial.ReadLine().Trim();

            if (datosEntrada == mensajeSolicitudConexion)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    DialogResult respuesta = MessageBox.Show("¿Quieres conectarte a esta computadora?", "Solicitud de Conexión", MessageBoxButtons.YesNo);
                    if (respuesta == DialogResult.Yes)
                    {
                        spSerial.WriteLine(mensajeConfirmacionConexion);
                    }
                });
            }
            else if (datosEntrada == mensajeConfirmacionConexion)
            {
                this.Invoke((MethodInvoker)delegate
                {
                    MessageBox.Show("Conexión establecida exitosamente.");
                });
            }
            else
            {
                this.Invoke((MethodInvoker)delegate
                {
                    DecodificarYDibujar(datosEntrada);
                });
            }
        }

        private void DecodificarYDibujar(string datos)
        {
            if (pbxDibujo.Image == null)
            {
                pbxDibujo.Image = new Bitmap(pbxDibujo.Width, pbxDibujo.Height);
            }

            string[] datosPuntos = datos.Split(';');
            List<Point> listaPuntos = new List<Point>();

            foreach (string puntoStr in datosPuntos)
            {
                string[] partes = puntoStr.Split(',');

                if (partes.Length == 2)
                {
                    int x = int.Parse(partes[0]);
                    int y = int.Parse(partes[1]);
                    listaPuntos.Add(new Point(x, y));
                }
            }

            this.Invoke((MethodInvoker)delegate
            {
                using (Graphics g = Graphics.FromImage(pbxDibujo.Image))
                {
                    for (int i = 0; i < listaPuntos.Count - 1; i++)
                    {
                        g.DrawLine(Pens.Black, listaPuntos[i], listaPuntos[i + 1]);
                    }
                }
                pbxDibujo.Refresh();
            });
        }
    }
}

UI界面说明

界面包含一个白色绘图区域(PictureBox)、串口选择下拉框、「连接」「断开」「清空」三个按钮,整体为Windows Forms风格。

内容的提问来源于stack exchange,提问作者Amir Barraza Meza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 01:17:02