// 关于软件:经典关于页模板(页头 图标/名称/版本/简介 + 选项卡 功能介绍|开源致谢 + 底部版权栏) // 富文本用 SelectionColor/Font 逐段设置(■ 小节标题深蓝加粗、协议名按协议配色,纯 WinForms 无新依赖) using System; using System.Drawing; using System.Windows.Forms; namespace 成套报价软件 { public partial class 关于软件 : Form { public 关于软件() { InitializeComponent(); this.BackColor = System.Drawing.Color.White; // 页头排版在 Load 里做(AutoScale 完成后):版本号紧随软件名实际宽度、 // 简介对齐软件名左侧,避免高 DPI 下固定坐标互相压字;图标 Zoom 充满框 pic图标.SizeMode = PictureBoxSizeMode.Zoom; // ★ 版本号从程序集读取(唯一事实源=AssemblyInfo 的 AssemblyVersion,递增后这里自动跟随; // Designer 里的 v1.0.0 只是设计期占位文本)。显示三段:主.次.修订 lbl版本.Text = "v" + System.Reflection.Assembly.GetExecutingAssembly() .GetName().Version.ToString(3); this.Load += (s, e) => { try { lbl版本.Left = lbl软件名.Right + 12; lbl版本.Top = lbl软件名.Top + Math.Max(0, (lbl软件名.Height - lbl版本.Height) / 2); lbl简介.Left = lbl软件名.Left; lbl简介.Top = lbl软件名.Bottom + 4; using (var ic = Icon.ExtractAssociatedIcon(Application.ExecutablePath)) pic图标.Image = new Bitmap(ic.ToBitmap(), pic图标.Width, pic图标.Height); } catch { } }; 填功能介绍(); 填开源致谢(); } // ---------- 富文本辅助:追加一段带样式的文本 ---------- private static void 追加(RichTextBox rtb, string text, Color color, bool bold, float size) { rtb.SelectionStart = rtb.TextLength; rtb.SelectionLength = 0; rtb.SelectionColor = color; rtb.SelectionFont = new Font("Microsoft YaHei UI", size, bold ? FontStyle.Bold : FontStyle.Regular); rtb.AppendText(text); rtb.SelectionColor = rtb.ForeColor; rtb.SelectionFont = rtb.Font; } private static void 标题(RichTextBox rtb, string text) { 追加(rtb, text + "\r\n", Color.FromArgb(43, 87, 154), true, 10.5f); // 深蓝粗 } private static void 条目(RichTextBox rtb, string text) { 追加(rtb, text + "\r\n", SystemColors.WindowText, false, 9f); } private static void 协议(RichTextBox rtb, string name) { // 协议配色(徽章感):MIT 绿 / Apache 橙 / BSD 蓝 / ISC 紫 / MS-PL 青 / 公有领域 灰 / 微软条款 深灰 Color c = Color.Gray; if (name.IndexOf("MIT", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(33, 115, 70); else if (name.IndexOf("Apache", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(200, 102, 30); else if (name.IndexOf("BSD", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(43, 87, 154); else if (name.IndexOf("ISC", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(122, 82, 168); else if (name.IndexOf("MS-PL", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.FromArgb(0, 138, 158); else if (name.IndexOf("公有领域", StringComparison.Ordinal) >= 0 || name.IndexOf("Public", StringComparison.OrdinalIgnoreCase) >= 0) c = Color.DimGray; else if (name.IndexOf("微软", StringComparison.Ordinal) >= 0) c = Color.DimGray; 追加(rtb, "[" + name + "]", c, true, 9f); } private static void 空行(RichTextBox rtb) { 追加(rtb, "\r\n", SystemColors.WindowText, false, 4f); } // ---------- 选项卡一:功能介绍 ---------- private void 填功能介绍() { var rtb = txt功能; rtb.ReadOnly = false; // 追加着色需要,结束后置回只读 标题(rtb, "■ 项目管理"); 条目(rtb, " 新建 / 修改 / 删除 / 复制项目,zip 项目包导入导出,最近项目自动恢复。"); 空行(rtb); 标题(rtb, "■ 报价三表"); 条目(rtb, " 图号 / 箱号 / 元件三级联动;虚拟模式万行秒开;编辑实时保存;"); 条目(rtb, " 公式自动计算(成本价 / 报出价 / 利润 / 毛利率,公式可自定义);"); 条目(rtb, " 批量粘贴 / 删除 / 撤销,行移动排序。"); 空行(rtb); 标题(rtb, "■ CAD 扒图"); 条目(rtb, " 网页 CAD 查看器打开 DWG/DXF 图纸;框选扒图号 / 箱号 / 扒元件;"); 条目(rtb, " 箱号自动记图纸名,元件记图纸规格原文;F1/F2/F3 元件合并;"); 条目(rtb, " 表格点行定位图上蒙版、删行删框。"); 空行(rtb); 标题(rtb, "■ PDF 扒图"); 条目(rtb, " PDF 渲染查看 + 框选 OCR,五种引擎:百度高精度 / 智谱 GLM-OCR /"); 条目(rtb, " 百度千帆 PaddleOCR-VL / UApiPro / Umi-OCR 本地离线;自动纠正文本"); 条目(rtb, " 方向;图形符号误读过滤;入库 / 合并 / 定位同 CAD 扒图。"); 空行(rtb); 标题(rtb, "■ 元件库与选型"); 条目(rtb, " 厂家 / 系列 / 价格网页选型;收藏一键跳转系列;选中即插入报价;"); 条目(rtb, " 方案库独立库文件双击打开;用户库 / 柜体库管理与 CSV 导入导出。"); 空行(rtb); 标题(rtb, "■ 计算与报表"); 条目(rtb, " GCS 母排计算与铜排推荐;批量调系数;元件排序;甲方报表导出。"); 空行(rtb); 标题(rtb, "■ 其它"); 条目(rtb, " 停靠布局保存恢复;数据备份与恢复;功能区页签与窗口双向联动;登录门禁。"); rtb.ReadOnly = true; rtb.SelectionStart = 0; rtb.SelectionLength = 0; rtb.ScrollToCaret(); } // ---------- 选项卡二:开源致谢(TreeView 树形折叠,默认全部收起) ---------- /// 建父节点:标题行「组件名 [协议] 用途」,子节点=版权/要求/查看全文。默认折叠。 /// 许可文件覆盖:同协议但需展示某组件自带许可证全文时指定(如 ZCode 的 Apache-2.0-ZCode.txt)。 private TreeNode 建节点(string 标题, string 协议名, string 副标题, string[] 子节点文本, string 许可文件覆盖 = null) { string text = 标题; if (!string.IsNullOrEmpty(协议名)) text += " [" + 协议名 + "]"; if (!string.IsNullOrEmpty(副标题)) text += " —— " + 副标题; var n = new TreeNode(text); n.NodeFont = new Font("Microsoft YaHei UI", 9F, FontStyle.Bold); n.ForeColor = SystemColors.WindowText; foreach (var t in 子节点文本) { var c = new TreeNode(t); c.NodeFont = new Font("Microsoft YaHei UI", 9F); c.ForeColor = t.StartsWith("协议要求") || t.StartsWith("修改") ? Color.FromArgb(80, 80, 80) : Color.DimGray; n.Nodes.Add(c); } // ★ 追加「查看许可证全文」链接子节点(按协议名映射 licenses 文件;协议为空不加) string 许可文件 = 许可文件覆盖 ?? 许可证文件名(协议名); if (许可文件 != null) { var link = new TreeNode("查看许可证全文 →"); link.NodeFont = new Font("Microsoft YaHei UI", 9F, FontStyle.Underline); link.ForeColor = Color.FromArgb(43, 87, 154); link.Tag = new string[] { 协议名, 许可文件 }; // 点击时取出 n.Nodes.Add(link); } return n; // 新节点默认收起,不调 ExpandAll 即全部折叠 } /// 协议名 → licenses 目录文件名(无对应文件的返回 null)。 /// Umi-OCR 的 "MIT / Apache-2.0" 双协议按 Apache-2.0 全文展示(MIT 全文见其它 MIT 条目)。 private static string 许可证文件名(string 协议名) { if (string.IsNullOrEmpty(协议名)) return null; if (协议名.IndexOf("Apache", StringComparison.OrdinalIgnoreCase) >= 0) return "Apache-2.0.txt"; if (协议名.IndexOf("BSD", StringComparison.OrdinalIgnoreCase) >= 0) return "BSD-3-Clause.txt"; if (协议名.IndexOf("ISC", StringComparison.OrdinalIgnoreCase) >= 0) return "ISC.txt"; if (协议名.IndexOf("MS-PL", StringComparison.OrdinalIgnoreCase) >= 0) return "MS-PL.txt"; if (协议名.IndexOf("公有领域", StringComparison.Ordinal) >= 0) return "PublicDomain.txt"; if (协议名.IndexOf("微软", StringComparison.Ordinal) >= 0) return "WebView2-terms.txt"; if (协议名.IndexOf("MIT", StringComparison.OrdinalIgnoreCase) >= 0) return "MIT.txt"; return null; } private void tree开源_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e) { // 点「查看许可证全文 →」子节点 → 弹窗显示该协议标准全文 var arr = e.Node.Tag as string[]; if (arr != null && arr.Length == 2) { using (var dlg = new 许可证文本(arr[0], arr[1])) dlg.ShowDialog(this); } } private void 填开源致谢() { var tv = tree开源; tv.BeginUpdate(); tv.Nodes.Clear(); // ---- 开源组件(13 项):子节点=版权声明 + 协议要求 ---- tv.Nodes.Add(建节点("WeifenLuo WinFormsUI Docking", "MIT", "停靠窗口框架", new string[] { "Copyright © Weifen Luo 及贡献者", "协议要求:分发时保留版权声明与许可证文本,其余无义务,可商用可闭源。" })); tv.Nodes.Add(建节点("Zuby ADGV / AdvancedDataGridView", "MIT", "增强数据表格", new string[] { "Copyright © 2017 Zuby", "协议要求:分发时保留版权声明与许可证文本。" })); tv.Nodes.Add(建节点("NPOI", "Apache-2.0", "Excel/OOXML 文件生成", new string[] { "Copyright © 2008-2023 NPOI Contributors", "协议要求:提供许可证副本并保留声明;有 NOTICE 文件须传递;修改文件须标注;含专利授权;不得用原作者商标推广。" })); tv.Nodes.Add(建节点("DotNetZip", "MS-PL", "zip 压缩", new string[] { "Copyright © 2008-2018 Dino Chiesa", "协议要求:分发时保留版权/专利/商标/署名声明并随附许可条款;含专利授权,允许闭源。" })); tv.Nodes.Add(建节点("ICSharpCode.SharpZipLib", "MIT", "zip/gzip 压缩", new string[] { "Copyright © 2000-2022 SharpZipLib 贡献者", "协议要求:分发时保留版权声明与许可证文本。" })); tv.Nodes.Add(建节点("unvell.ReoGrid", "MIT", "表格控件", new string[] { "Copyright © 2012 unvell Inc., Jing Lu", "协议要求:分发时保留版权声明与许可证文本。" })); tv.Nodes.Add(建节点("System.Data.SQLite", "公有领域", "SQLite 数据库驱动", new string[] { "Public Domain · Robert Simpson 及 SQLite 团队贡献", "协议要求:作者放弃版权,无附加义务。" })); tv.Nodes.Add(建节点("pdfium (Google)", "BSD-3-Clause", "PDF 渲染引擎", new string[] { "Copyright 2014-2024 The PDFium Authors", "协议要求:源码/二进制分发保留版权声明与免责声明;不得以原作者名义为衍生品背书。" })); tv.Nodes.Add(建节点("Microsoft Edge WebView2 运行时", "微软补充条款", "内嵌网页组件", new string[] { "© Microsoft Corporation. 保留所有权利", "协议要求:运行时可免费随本软件再分发,按微软《软件补充许可条款》使用。" })); tv.Nodes.Add(建节点("Node.js", "MIT", "本地静态服务运行时", new string[] { "Copyright Node.js contributors · OpenSSL: Copyright © OpenSSL Project Authors", "协议要求:分发时保留版权声明与许可证文本(OpenSSL 按 Apache-2.0)。" })); tv.Nodes.Add(建节点("ZCode(zai-org/ZCode 开源版)", "Apache-2.0", "AI 助手引擎(终端/网页 Agent)", new string[] { "Copyright 2026 Z.AI Co., Ltd · 源码仓库 github.com/zai-org/ZCode", "协议要求:提供许可证副本并保留声明;随附其 NOTICE 文件;修改文件须标注;含专利授权;不得用原作者商标推广。", "本软件从其开源仓库官方源码构建并原样分发,未修改其代码。" }, "Apache-2.0-ZCode.txt")); tv.Nodes.Add(建节点("mlightcad / CAD-Viewer", "MIT", "网页 CAD 引擎(含 three.js)", new string[] { "Copyright © mlightcad · three.js: Copyright © 2010-2024 three.js authors", "协议要求:分发时保留版权声明与许可证文本。本软件对其有修改,见下方修改说明。" })); tv.Nodes.Add(建节点("Umi-OCR", "MIT / Apache-2.0", "本地离线 OCR(可选下载)", new string[] { "Copyright © 2022 hiroi-sora · PaddleOCR: Copyright © Baidu Inc.", "协议要求:MIT 项保留版权声明;PaddleOCR(Apache-2.0)另需保留 NOTICE 与修改标注。" })); tv.Nodes.Add(建节点("Lucide", "ISC", "图标库", new string[] { "Copyright © 2020 Lucide Labs", "协议要求:与 MIT 等价,分发时保留版权声明与许可证文本。本软件对图标有换色调整,见下方修改说明。" })); // ---- 修改说明与汇总 ---- tv.Nodes.Add(建节点("修改说明:mlightcad / CAD-Viewer —— 已修改", "", "", new string[] { "为适配本软件,对其网页构建产物(dist)作了以下修改并随软件分发:", "修改① 字体与模板加载路径本地化(base-url 改为根相对,离线可用);", "修改② 扒图完成消息(paPicked)附带当前图纸文件名,并在打开图纸时主动上报文档标题,供报价表格记录图纸名;", "修改③ 静态服务脚本(server.cjs)响应头增加 Cache-Control: no-store。", "其余代码未改动;原项目版权归 mlightcad 所有。" })); tv.Nodes.Add(建节点("修改说明:Lucide —— 已修改", "", "", new string[] { "修改内容:图标 SVG 经描边配色替换与线宽调整(stroke-width 调细)后渲染为 PNG 使用,未改动图形本身。" })); tv.Nodes.Add(建节点("其余组件 —— 未修改", "", "", new string[] { "WeifenLuo Docking、ADGV、NPOI、DotNetZip、SharpZipLib、ReoGrid、System.Data.SQLite、pdfium、WebView2 运行时、Node.js、Umi-OCR、ZCode 均为官方原版分发,未作任何修改。", "另:Smart.CustomComponents 与 CJZZ.Controls 为本软件配套自研组件,非开源第三方库。" })); tv.Nodes.Add(建节点("※ 共同底线", "", "", new string[] { "所有宽松协议都要求在分发时保留原作者的版权声明与许可证文本;", "本软件的分发已包含并遵循以上要求。完整许可证文本以官方发布为准。" })); tv.CollapseAll(); // 默认全部折叠 tv.EndUpdate(); } private void pnl页头_Paint(object sender, PaintEventArgs e) { // 页头底部分隔线 using (var pen = new Pen(Color.FromArgb(220, 220, 220))) e.Graphics.DrawLine(pen, 0, pnl页头.Height - 1, pnl页头.Width, pnl页头.Height - 1); } private void btn确定_Click(object sender, EventArgs e) { Close(); } } }