diff --git a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs index 21d2359..8130c97 100644 --- a/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs +++ b/Windows/CS/Framework4.0/Toprie/Toprie/Camera.cs @@ -67,7 +67,7 @@ namespace JoyD.Windows.CS.Toprie } // 显示错误的定时器 - private System.Windows.Forms.Timer _errorDisplayTimer; + /// /// 更新设计模式状态到DeviceManager @@ -85,7 +85,9 @@ namespace JoyD.Windows.CS.Toprie /// 3. 最后调用更新UI /// private void UpdateInfo() - { + { + // 更新Ping状态到Info文本 + Console.WriteLine($"Ping状态更新: {(IsDevicePingable ? "可Ping通" : "不可Ping通")}"); if (DesignMode) return; try @@ -128,17 +130,21 @@ namespace JoyD.Windows.CS.Toprie Color textColor = Color.White; if (isDisconnected || isReconnecting) - { + { // 断开或重连状态 text = isReconnecting ? "正在重连..." : "连接断开"; textColor = isReconnecting ? Color.Yellow : Color.Red; } else if (isPaused) - { + { // 暂停状态 text = "暂停"; textColor = Color.Red; } + // 添加Ping状态信息 + string pingStatus = IsDevicePingable ? "Ping通" : "Ping不通"; + string pingText = $"设备{pingStatus}"; + Color pingColor = IsDevicePingable ? Color.Green : Color.Red; // 绘制文本 using (Font font = new Font("Arial", 48, FontStyle.Bold)) @@ -146,8 +152,24 @@ namespace JoyD.Windows.CS.Toprie { StringFormat format = new StringFormat(); format.Alignment = StringAlignment.Center; - format.LineAlignment = StringAlignment.Center; - g.DrawString(text, font, textBrush, new RectangleF(0, 0, BUFFER_WIDTH, BUFFER_HEIGHT), format); + + // 将主文本位置调整到上方 + g.DrawString(text, font, textBrush, + new RectangleF(0, BUFFER_HEIGHT / 4, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + format); + } + + // 绘制Ping状态信息 + using (Font pingFont = new Font("Arial", 36, FontStyle.Regular)) + using (SolidBrush pingBrush = new SolidBrush(pingColor)) + { + StringFormat format = new StringFormat(); + format.Alignment = StringAlignment.Center; + + // 将Ping状态文本位置放在主文本下方 + g.DrawString(pingText, pingFont, pingBrush, + new RectangleF(0, BUFFER_HEIGHT * 2 / 3, BUFFER_WIDTH, BUFFER_HEIGHT / 3), + format); } } } @@ -230,6 +252,9 @@ namespace JoyD.Windows.CS.Toprie // 初始化图像缓冲区 InitializeImageBuffer(); + // 初始化Ping定时器 + _pingTimer = new System.Threading.Timer(PingTimer_Tick, null, Timeout.Infinite, Timeout.Infinite); + // 只有在非设计模式下才初始化设备管理器和错误定时器 if (!DesignMode) { @@ -251,7 +276,6 @@ namespace JoyD.Windows.CS.Toprie catch { } InitializeDeviceManager(); - InitializeErrorTimer(); } } @@ -331,20 +355,15 @@ namespace JoyD.Windows.CS.Toprie } } - /// - /// 初始化错误显示定时器 - /// - private void InitializeErrorTimer() - { - _errorDisplayTimer = new System.Windows.Forms.Timer { Interval = 3000 }; // 显示3秒后清除 - _errorDisplayTimer.Tick += ErrorDisplayTimer_Tick; - } + /// /// 启动相机 /// public void StartCamera() - { + { + // 启动设备Ping + StartDevicePing(); if (DesignMode) return; try { @@ -453,7 +472,9 @@ namespace JoyD.Windows.CS.Toprie /// 停止接收图像 /// public void StopCamera() - { + { + // 停止设备Ping + StopDevicePing(); if (DesignMode) return; try { @@ -471,6 +492,29 @@ namespace JoyD.Windows.CS.Toprie private bool _isPaused = false; // 暂停状态标志 + // Ping相关字段 + private System.Threading.Timer _pingTimer; + private bool _isDevicePingable = false; + private const int _pingInterval = 500; // 0.5秒Ping一次 + + /// + /// 获取设备是否可Ping通 + /// + public bool IsDevicePingable + { + get { return _isDevicePingable; } + private set + { + if (_isDevicePingable != value) + { + _isDevicePingable = value; + Console.WriteLine($"设备Ping状态变更: {(_isDevicePingable ? "可Ping通" : "不可Ping通")}"); + // 状态变化时调用更新Info + UpdateInfo(); + } + } + } + /// /// 设备管理器图像接收事件处理 /// @@ -1069,82 +1113,9 @@ namespace JoyD.Windows.CS.Toprie { if (DesignMode) return; Console.WriteLine(message); - - // 可以根据需要添加UI上的错误显示 - // 这里简化处理,只在控制台输出 - - // 检查imageBox是否存在且尺寸有效 - if (imageBox == null || imageBox.Width <= 0 || imageBox.Height <= 0) - { - Console.WriteLine("imageBox尺寸无效,跳过错误显示图像创建"); - return; - } - - // 确保使用有效的尺寸创建Bitmap - int width = Math.Max(100, imageBox.Width); - int height = Math.Max(100, imageBox.Height); - - // 如果需要在图像区域显示错误文字,可以使用以下代码 - using (Bitmap errorBitmap = new Bitmap(width, height)) - using (Graphics g = Graphics.FromImage(errorBitmap)) - { - g.Clear(Color.Black); - using (Font font = new Font("Arial", 10)) - using (Brush brush = new SolidBrush(Color.Red)) - { - SizeF textSize = g.MeasureString(message, font); - PointF textLocation = new PointF( - (errorBitmap.Width - textSize.Width) / 2, - (errorBitmap.Height - textSize.Height) / 2); - g.DrawString(message, font, brush, textLocation); - } - - UpdateImageOnUI(errorBitmap); - } - - // 启动定时器,3秒后清除错误显示 - _errorDisplayTimer.Stop(); - _errorDisplayTimer.Start(); + // 错误消息仅写入日志即可,不需要在UI上显示 } - /// - /// 错误显示定时器事件 - /// - private void ErrorDisplayTimer_Tick(object sender, EventArgs e) - { - if (DesignMode) return; - _errorDisplayTimer.Stop(); - // 清除错误显示,恢复到等待图像状态 - - // 检查imageBox是否存在且尺寸有效 - if (imageBox == null || imageBox.Width <= 0 || imageBox.Height <= 0) - { - Console.WriteLine("imageBox尺寸无效,跳过等待图像创建"); - return; - } - - // 确保使用有效的尺寸创建Bitmap - int width = Math.Max(100, imageBox.Width); - int height = Math.Max(100, imageBox.Height); - - using (Bitmap waitingBitmap = new Bitmap(width, height)) - using (Graphics g = Graphics.FromImage(waitingBitmap)) - { - g.Clear(Color.Black); - using (Font font = new Font("Arial", 10)) - using (Brush brush = new SolidBrush(Color.White)) - { - string waitingText = "正在等待热图数据..."; - SizeF textSize = g.MeasureString(waitingText, font); - PointF textLocation = new PointF( - (waitingBitmap.Width - textSize.Width) / 2, - (waitingBitmap.Height - textSize.Height) / 2); - g.DrawString(waitingText, font, brush, textLocation); - } - - UpdateImageOnUI(waitingBitmap); - } - } /// /// 右键菜单显示前的事件处理方法 @@ -1463,6 +1434,110 @@ namespace JoyD.Windows.CS.Toprie #endregion + #region 设备Ping相关方法 + + /// + /// Ping定时器的回调方法 + /// + /// 状态对象 + private void PingTimer_Tick(object state) + { + if (_deviceManager != null && !string.IsNullOrEmpty(_deviceManager.IPAddress)) + { + Task.Run(() => + { + bool pingResult = PingDevice(_deviceManager.IPAddress); + try + { + // 在线程安全的方式下更新状态 + if (this.InvokeRequired) + { + this.Invoke(new Action(UpdatePingState), pingResult); + } + else + { + UpdatePingState(pingResult); + } + } + catch (ObjectDisposedException) + { + // 控件可能已被释放,忽略此更新 + } + }); + } + } + + /// + /// 执行Ping操作 + /// + /// 要Ping的IP地址 + /// 是否Ping通 + private bool PingDevice(string ipAddress) + { + try + { + using (var ping = new System.Net.NetworkInformation.Ping()) + { + var reply = ping.Send(ipAddress, 2000); // 2秒超时 + return reply != null && reply.Status == System.Net.NetworkInformation.IPStatus.Success; + } + } + catch (Exception ex) + { + Console.WriteLine($"Ping设备失败: {ex.Message}"); + return false; + } + } + + /// + /// 更新Ping状态 + /// + /// 是否可Ping通 + private void UpdatePingState(bool isPingable) + { + IsDevicePingable = isPingable; + } + + /// + /// 开始设备Ping + /// + private void StartDevicePing() + { + try + { + if (_pingTimer != null) + { + _pingTimer.Change(0, _pingInterval); // 立即开始,然后按间隔执行 + Console.WriteLine("设备Ping已启动"); + } + } + catch (Exception ex) + { + Console.WriteLine($"启动设备Ping失败: {ex.Message}"); + } + } + + /// + /// 停止设备Ping + /// + private void StopDevicePing() + { + try + { + if (_pingTimer != null) + { + _pingTimer.Change(Timeout.Infinite, Timeout.Infinite); + Console.WriteLine("设备Ping已停止"); + } + } + catch (Exception ex) + { + Console.WriteLine($"停止设备Ping失败: {ex.Message}"); + } + } + + #endregion + /// /// 清理资源 /// @@ -1497,15 +1572,16 @@ namespace JoyD.Windows.CS.Toprie _deviceManager = null; } - // 无论是否在设计模式下,都需要释放定时器 - if (_errorDisplayTimer != null) - { - _errorDisplayTimer.Stop(); - _errorDisplayTimer.Dispose(); - _errorDisplayTimer = null; - } + // 无论是否在设计模式下,都需要释放图像资源 + + // 释放Ping定时器 + if (_pingTimer != null) + { + _pingTimer.Dispose(); + _pingTimer = null; + } if (imageBox != null && !imageBox.IsDisposed && imageBox.Image != null) { imageBox.Image.Dispose();