增加放大预览功能

This commit is contained in:
zqm
2026-01-08 09:39:08 +08:00
parent bcee6c4c1b
commit 44c593941f
4 changed files with 300 additions and 12 deletions

View File

@@ -53,6 +53,9 @@ namespace JoyD.Windows.CS.Toprie
private System.Windows.Forms.ToolStripMenuItem modifyConfigToolStripMenuItem;
private const int BUFFER_HEIGHT = 384;
// 预览窗口引用
private JoyD.Windows.CS.preview _previewForm;
// 最后接收的图像
private Image _lastImage = null;
@@ -1131,7 +1134,11 @@ namespace JoyD.Windows.CS.Toprie
// 将全局缓冲一次性绘制到图像框的bitmap
imageBox.Image = tempImage;
// 通知预览窗口更新图像
if (_previewForm != null && !_previewForm.IsDisposed)
{
_previewForm.UpdateImage(tempImage);
}
// 步骤5同步更新检测配置窗口的实时图像属性
// 创建LastImage的副本并通过UpdateRealTimeImage方法传递给Setting窗口
lock (_lastImageLock)
@@ -3199,9 +3206,39 @@ namespace JoyD.Windows.CS.Toprie
/// <summary>
/// imageBox双击事件处理方法
/// 双击后弹出检测配置窗口
/// 双击后弹出预览窗口
/// </summary>
private void ImageBox_DoubleClick(object sender, EventArgs e)
{
try
{
// 关闭已存在的预览窗口
if (_previewForm != null && !_previewForm.IsDisposed)
{
_previewForm.Close();
}
// 创建新的预览窗口实例
_previewForm = new JoyD.Windows.CS.preview();
// 设置初始图像
_previewForm.UpdateImage(_lastImage);
// 模态显示预览窗口
_previewForm.ShowDialog();
// 预览窗口关闭后清空引用
_previewForm = null;
}
catch (Exception ex)
{
Console.WriteLine($"打开预览窗口时出错: {ex.Message}");
MessageBox.Show($"打开预览窗口时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// "修改配置"菜单项点击事件处理方法
/// 点击后弹出检测配置窗口
/// </summary>
private void ModifyConfigToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
@@ -3216,15 +3253,5 @@ namespace JoyD.Windows.CS.Toprie
MessageBox.Show($"打开配置窗口时出错: {ex.Message}", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// "修改配置"菜单项点击事件处理方法
/// 点击后弹出检测配置窗口,与双击效果相同
/// </summary>
private void ModifyConfigToolStripMenuItem_Click(object sender, EventArgs e)
{
// 调用与双击相同的逻辑
ImageBox_DoubleClick(sender, e);
}
}
}

View File

@@ -0,0 +1,68 @@
namespace JoyD.Windows.CS
{
partial class preview
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 预览图像控件
/// </summary>
private System.Windows.Forms.PictureBox previewImageBox;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.previewImageBox = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.previewImageBox)).BeginInit();
this.SuspendLayout();
//
// previewImageBox
//
this.previewImageBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.previewImageBox.Location = new System.Drawing.Point(0, 0);
this.previewImageBox.Name = "previewImageBox";
this.previewImageBox.Size = new System.Drawing.Size(973, 708);
this.previewImageBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
this.previewImageBox.TabIndex = 0;
this.previewImageBox.TabStop = false;
//
// preview
//
this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(973, 708);
this.Controls.Add(this.previewImageBox);
this.MinimizeBox = false;
this.Name = "preview";
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "预览";
((System.ComponentModel.ISupportInitialize)(this.previewImageBox)).EndInit();
this.ResumeLayout(false);
}
#endregion
}
}

View File

@@ -0,0 +1,73 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace JoyD.Windows.CS
{
/// <summary>
/// 预览窗口类,用于显示图像或数据预览
/// </summary>
public partial class preview : Form
{
/// <summary>
/// 初始化预览窗口的构造函数
/// </summary>
public preview()
{
InitializeComponent();
}
/// <summary>
/// 动态更新预览图像(线程安全)
/// </summary>
/// <param name="image">要显示的图像</param>
public void UpdateImage(Image image)
{
if (this.InvokeRequired)
{
this.Invoke(new Action<Image>(UpdateImage), image);
return;
}
try
{
// 释放旧图像资源
if (previewImageBox.Image != null)
{
previewImageBox.Image.Dispose();
previewImageBox.Image = null;
}
// 克隆新图像
if (image != null)
{
previewImageBox.Image = (Image)image.Clone();
}
}
catch (Exception ex)
{
Console.WriteLine($"更新预览图像时出错: {ex.Message}");
}
}
/// <summary>
/// 窗口关闭时释放资源
/// </summary>
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
// 释放图像资源
if (previewImageBox.Image != null)
{
previewImageBox.Image.Dispose();
previewImageBox.Image = null;
}
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>