Files
AohDrllTools/App.xaml.cs
Mr.Xia cacbbe6c33 feat: 增加钻带涨缩功能,支持倍率/PPM模式缩放坐标
- 新增 ExcellonScaler 引擎:普通孔缩放坐标,G85槽孔保护槽长,刀具定义行原样保留
- 新增 DrillScalingWindow 参数设置窗口:倍率/PPM模式切换,X/Y独立输入
- 集成到启动功能菜单:.dr2/.dpin 文件显示"涨缩"按钮
- 输出覆盖原文件 + .bak 备份,GB2312 编码
2026-06-05 22:17:15 +08:00

279 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.Configuration;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows;
namespace DrillTools
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : System.Windows.Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
RegisterShellContextMenu();
string? filePath = null;
if (e.Args.Length > 0)
{
filePath = e.Args[0];
if (!IsValidDrillTapeFile(filePath))
filePath = null;
}
if (filePath == null)
{
ShowMainWindow(null);
return;
}
// 防止选择窗口关闭后触发 OnLastWindowClose 导致应用退出
ShutdownMode = ShutdownMode.OnExplicitShutdown;
// 只读取和解析文件一次,提取所有需要的信息
string content = CommandTypeFileReader.ReadAllText(filePath);
var viewModel = new MainWindowViewModel
{
IsStartupDrillTapeFile = true,
OriginalFilePath = filePath,
ShouldCheckSortFileOnLoad = false
};
viewModel.LoadToolsFromDrillTape(content);
bool canClearParameters = DrillTapeParameterCleaner.CanClearParameters(content);
bool canGeneratePpDrillTape = viewModel.CanGeneratePpDrillTape;
string extension = Path.GetExtension(filePath).ToLowerInvariant();
bool canScaleDrillTape = extension == ".dr2" || extension == ".dpin";
double minDrill = viewModel.MinDrillDiameter;
double minSlot = viewModel.MinSlotDiameter;
double minEA = viewModel.MinEADiameter;
bool isPpDrillTape = viewModel.IsPpDrillTape;
double ppXSpacing = viewModel.PpXSpacing;
double ppYSpacing = viewModel.PpYSpacing;
bool hasOuter3175Spacing = viewModel.HasOuter3175Spacing;
double outer3175XSpacing = viewModel.Outer3175XSpacing;
double outer3175YSpacing = viewModel.Outer3175YSpacing;
var selectionWindow = new StartupSelectionWindow(
filePath,
canClearParameters,
canGeneratePpDrillTape,
canScaleDrillTape,
minDrill,
minSlot,
minEA,
isPpDrillTape,
ppXSpacing,
ppYSpacing,
hasOuter3175Spacing,
outer3175XSpacing,
outer3175YSpacing);
selectionWindow.ShowDialog();
switch (selectionWindow.SelectedAction)
{
case StartupAction.AdjustToolOrder:
ShutdownMode = ShutdownMode.OnLastWindowClose;
ShowMainWindow(filePath);
break;
case StartupAction.ExportHoleCount:
PerformHeadlessExport(filePath);
Shutdown();
break;
case StartupAction.ClearParameters:
PerformParameterCleanup(filePath);
Shutdown();
break;
case StartupAction.GeneratePpDrillTape:
PerformPpDrillTapeGeneration(filePath);
Shutdown();
break;
case StartupAction.ScaleDrillTape:
PerformDrillScaling(filePath);
Shutdown();
break;
default:
Shutdown();
break;
}
}
private static void ShowMainWindow(string? filePath)
{
try
{
MainWindow mainWindow = new MainWindow(filePath);
mainWindow.Show();
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"创建MainWindow时发生异常:\n{ex.GetType().Name} - {ex.Message}\n\n{ex.StackTrace}",
"启动失败", MessageBoxButton.OK, MessageBoxImage.Error);
throw;
}
}
private static void PerformHeadlessExport(string filePath)
{
try
{
var viewModel = new MainWindowViewModel
{
ShouldCheckSortFileOnLoad = false
};
string content = CommandTypeFileReader.ReadAllText(filePath);
viewModel.OriginalFilePath = filePath;
viewModel.LoadToolsFromDrillTape(content);
if (viewModel.Tools.Count == 0)
{
System.Windows.MessageBox.Show("钻带文件中未找到有效的刀具数据,无法导出孔数报表。",
"提示", MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
viewModel.ExportDrillUsageReport();
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"导出孔数报表失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private static void PerformPpDrillTapeGeneration(string filePath)
{
try
{
var viewModel = new MainWindowViewModel
{
IsStartupDrillTapeFile = true,
OriginalFilePath = filePath,
ShouldCheckSortFileOnLoad = false
};
string content = CommandTypeFileReader.ReadAllText(filePath);
viewModel.LoadToolsFromDrillTape(content);
string outputFilePath = viewModel.GeneratePpDrillTape();
System.Windows.MessageBox.Show(
$"PP钻带已生成\n{outputFilePath}",
"生成PP钻带完成",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"生成PP钻带失败\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private static void PerformParameterCleanup(string filePath)
{
try
{
DrillTapeParameterCleaner.ClearParametersAndSave(filePath);
System.Windows.MessageBox.Show(
$"参数已清空,原文件已备份为:\n{Path.GetFileName(filePath)}.bak",
"清空参数完成",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"清空参数失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private static void PerformDrillScaling(string filePath)
{
try
{
var scalingWindow = new DrillScalingWindow();
scalingWindow.ShowDialog();
if (scalingWindow.ScalingResult == null)
return;
var (kx, ky) = scalingWindow.ScalingResult.Value;
string content = CommandTypeFileReader.ReadAllText(filePath);
string scaledContent = Integration.ExcellonScaler.Scale(content, kx, ky);
// 备份原文件
string backupFilePath = filePath + ".bak";
File.Copy(filePath, backupFilePath, true);
// 写入缩放后的内容
using var writer = new StreamWriter(filePath, false, Encoding.GetEncoding(936));
writer.Write(scaledContent);
System.Windows.MessageBox.Show(
$"涨缩完成,原文件已备份为:\n{Path.GetFileName(filePath)}.bak",
"涨缩完成",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
catch (Exception ex)
{
System.Windows.MessageBox.Show($"涨缩失败:\n{ex.Message}",
"错误", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private static void RegisterShellContextMenu()
{
try
{
string exePath = Process.GetCurrentProcess().MainModule!.FileName!;
string[] extensions = { ".drl", ".dr2", ".dr3", ".trg", ".dpin", ".txt" };
string menuText = "用DrillTools打开";
foreach (string ext in extensions)
{
string keyPath = $@"SystemFileAssociations\{ext}\shell\{menuText}\command";
using var key = Microsoft.Win32.Registry.ClassesRoot.CreateSubKey(keyPath);
key.SetValue("", $"\"{exePath}\" \"%1\"");
}
}
catch
{
// 非管理员权限时注册可能失败,静默忽略不影响主功能
}
}
/// <summary>
/// 验证是否为有效的钻带文件
/// </summary>
/// <param name="filePath">文件路径</param>
/// <returns>是否为有效钻带文件</returns>
private static bool IsValidDrillTapeFile(string filePath)
{
if (string.IsNullOrEmpty(filePath))
return false;
if (!File.Exists(filePath))
return false;
// 检查文件扩展名是否为支持的钻带文件格式
string extension = Path.GetExtension(filePath).ToLowerInvariant();
string[] supportedExtensions = { ".txt", ".drl", ".dr2", ".dr3", ".trg", ".dpin" };
return supportedExtensions.Contains(extension);
}
}
}