2026-06-28 02:43:22 +08:00
|
|
|
using System;
|
2026-06-28 03:17:55 +08:00
|
|
|
using System.IO;
|
2026-06-28 02:43:22 +08:00
|
|
|
using System.Linq;
|
2026-06-28 03:17:55 +08:00
|
|
|
using System.Threading.Tasks;
|
2026-06-28 02:43:22 +08:00
|
|
|
using System.Windows;
|
2026-06-28 03:17:55 +08:00
|
|
|
using System.Windows.Controls;
|
2026-06-28 02:43:22 +08:00
|
|
|
using System.Windows.Media.Animation;
|
2026-06-28 03:17:55 +08:00
|
|
|
using Microsoft.Win32;
|
|
|
|
|
using BetterEN5.Services;
|
2026-06-28 02:43:22 +08:00
|
|
|
|
|
|
|
|
namespace BetterEN5.UI
|
|
|
|
|
{
|
|
|
|
|
public partial class BetterSeewoMainWindow : Window
|
|
|
|
|
{
|
2026-06-28 03:17:55 +08:00
|
|
|
private readonly InkService _inkService = new();
|
|
|
|
|
private readonly ConversionService _conversionService = new();
|
|
|
|
|
private readonly ActivationService _activationService = new();
|
|
|
|
|
|
2026-06-28 02:43:22 +08:00
|
|
|
public BetterSeewoMainWindow()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
Loaded += OnLoaded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
|
|
|
|
{
|
2026-06-28 03:17:55 +08:00
|
|
|
var sb = (Storyboard)TryFindResource("ScaleInStoryboard");
|
|
|
|
|
if (sb != null) BeginStoryboard(sb);
|
|
|
|
|
_ = RefreshStatusAsync();
|
2026-06-28 02:43:22 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-28 03:17:55 +08:00
|
|
|
private void NavChanged(object sender, RoutedEventArgs e)
|
2026-06-28 02:43:22 +08:00
|
|
|
{
|
2026-06-28 03:17:55 +08:00
|
|
|
if (sender == NavInk) ShowPanel(PanelInk);
|
|
|
|
|
else if (sender == NavConvert) ShowPanel(PanelConvert);
|
|
|
|
|
else if (sender == NavTouch) ShowPanel(PanelTouch);
|
|
|
|
|
else if (sender == NavBoard) ShowPanel(PanelBoard);
|
|
|
|
|
else if (sender == NavActivate) ShowPanel(PanelActivate);
|
2026-06-28 02:43:22 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-28 03:17:55 +08:00
|
|
|
private void ShowPanel(StackPanel panel)
|
2026-06-28 02:43:22 +08:00
|
|
|
{
|
2026-06-28 03:17:55 +08:00
|
|
|
foreach (var p in new[] { PanelInk, PanelConvert, PanelTouch, PanelBoard, PanelActivate })
|
|
|
|
|
p.Visibility = p == panel ? Visibility.Visible : Visibility.Collapsed;
|
2026-06-28 02:43:22 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-28 03:17:55 +08:00
|
|
|
private async Task RefreshStatusAsync()
|
2026-06-28 02:43:22 +08:00
|
|
|
{
|
2026-06-28 03:17:55 +08:00
|
|
|
var touchOk = await Task.Run(() => TouchFixService.IsTouchWorkingCorrectly());
|
|
|
|
|
TouchStatus.Text = touchOk ? "✅ IWB 模式已启用" : "⚠️ 未启用 IWB 模式";
|
|
|
|
|
var info = await Task.Run(() => _activationService.GetCurrentStatus());
|
|
|
|
|
ActivationStatusText.Text = info.IsProfessional
|
|
|
|
|
? $"✅ 专业版 · {info.LastActivationDate}"
|
|
|
|
|
: "🔓 社区版";
|
2026-06-28 02:43:22 +08:00
|
|
|
}
|
|
|
|
|
|
2026-06-28 03:17:55 +08:00
|
|
|
private void Minimize_Click(object s, RoutedEventArgs e) => WindowState = WindowState.Minimized;
|
|
|
|
|
private void Maximize_Click(object s, RoutedEventArgs e) => WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
|
|
|
|
|
private void Close_Click(object s, RoutedEventArgs e) => Close();
|
|
|
|
|
|
|
|
|
|
private async void ExportInk_Click(object s, RoutedEventArgs e)
|
2026-06-28 02:43:22 +08:00
|
|
|
{
|
2026-06-28 03:17:55 +08:00
|
|
|
var dialog = new SaveFileDialog { Title = "导出墨迹", Filter = "墨迹文件|*.ink.json|JSON|*.json", DefaultExt = ".ink.json" };
|
|
|
|
|
if (dialog.ShowDialog() == true)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "导出墨迹", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在导出墨迹...", "读取课件笔迹数据");
|
|
|
|
|
await _inkService.ExportInkAsync(dialog.FileName);
|
|
|
|
|
p.UpdateStatus("导出完成", $"已保存至 {Path.GetFileName(dialog.FileName)}");
|
|
|
|
|
});
|
|
|
|
|
InkStatus.Text = $"已导出: {Path.GetFileName(dialog.FileName)}";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void ImportInk_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var dialog = new OpenFileDialog { Title = "导入墨迹", Filter = "墨迹文件|*.ink.json|JSON|*.json" };
|
|
|
|
|
if (dialog.ShowDialog() == true)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "导入墨迹", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在导入墨迹...", "写入课件笔迹");
|
|
|
|
|
await _inkService.ImportInkAsync(dialog.FileName);
|
|
|
|
|
});
|
|
|
|
|
InkStatus.Text = "墨迹已导入";
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void ConvertPptx_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var dialog = new OpenFileDialog { Title = "选择 PPT", Filter = "PowerPoint|*.pptx" };
|
|
|
|
|
if (dialog.ShowDialog() == true)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "转换文件", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在转换 PPT → ENBX...", "调用转换器");
|
|
|
|
|
var result = await _conversionService.ConvertPptxToEnbxAsync(dialog.FileName);
|
|
|
|
|
p.UpdateStatus("转换完成", Path.GetFileName(result));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void ConvertEnbx_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var dialog = new OpenFileDialog { Title = "选择 ENBX", Filter = "希沃课件|*.enbx" };
|
|
|
|
|
if (dialog.ShowDialog() == true)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "转换文件", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在转换 ENBX → PPT...", "调用转换器");
|
|
|
|
|
var result = await _conversionService.ConvertEnbxToPptxAsync(dialog.FileName);
|
|
|
|
|
p.UpdateStatus("导出完成", Path.GetFileName(result));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void CheckTouch_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var ok = await Task.Run(() => TouchFixService.IsTouchWorkingCorrectly());
|
|
|
|
|
TouchStatus.Text = ok ? "✅ IWB 模式已启用" : "⚠️ 未启用 IWB 模式";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void ApplyTouchFix_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "触摸修复", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在写入注册表配置...", "ForceIWB");
|
|
|
|
|
await Task.Run(() => TouchFixService.ApplyFixAsync());
|
|
|
|
|
p.UpdateStatus("正在配置 IWB 模式...", "IWBConfig.json");
|
|
|
|
|
await Task.Delay(300);
|
|
|
|
|
p.UpdateStatus("完成", "请重启希沃白板生效");
|
|
|
|
|
});
|
|
|
|
|
TouchStatus.Text = "修复已应用,请重启";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void EnableBoardSupport_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "大屏支持", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在配置大屏模式...", "修补 Configs.fkv");
|
|
|
|
|
await _activationService.ApplyBoardSupportPatchAsync();
|
|
|
|
|
p.UpdateStatus("正在写入注册表...", "大屏相关键值");
|
|
|
|
|
await Task.Delay(200);
|
|
|
|
|
p.UpdateStatus("完成", "大屏模式已配置");
|
|
|
|
|
});
|
|
|
|
|
BoardStatus.Text = "大屏模式已配置";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void EnableIWB_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "IWB 模式", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在启用 IWB 模式...", "注册表 + 配置文件");
|
|
|
|
|
await _activationService.EnableIWBForNonTouchAsync();
|
|
|
|
|
p.UpdateStatus("完成", "IWB 模式已启用,重启生效");
|
|
|
|
|
});
|
|
|
|
|
BoardStatus.Text = "IWB 已启用";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void ActivatePro_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var dlg = new ActivateDialog();
|
|
|
|
|
dlg.Owner = this;
|
|
|
|
|
if (dlg.ShowDialog() == true)
|
|
|
|
|
{
|
|
|
|
|
await ProgressDialog.Show(this, "激活", async p =>
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("正在验证激活码...", "");
|
|
|
|
|
var ok = await _activationService.ActivateProfessionalAsync(dlg.LicenseKey);
|
|
|
|
|
if (ok)
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("激活成功", "专业版已启用");
|
|
|
|
|
ActivationStatusText.Text = "✅ 专业版已激活";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
p.UpdateStatus("激活失败", "激活码无效");
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void LaunchInstaller_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var ok = await _activationService.LaunchBen5InstallerAsync();
|
|
|
|
|
if (!ok)
|
|
|
|
|
MessageBox.Show(this, "未找到注册补丁安装程序", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async void CheckActivation_Click(object s, RoutedEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
var info = await Task.Run(() => _activationService.GetCurrentStatus());
|
|
|
|
|
ActivationStatusText.Text = info.IsProfessional
|
|
|
|
|
? $"✅ 专业版 · {info.LastActivationDate}"
|
|
|
|
|
: "🔓 社区版";
|
2026-06-28 02:43:22 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void ShowWindow()
|
|
|
|
|
{
|
|
|
|
|
Application.Current.Dispatcher.Invoke(() =>
|
|
|
|
|
{
|
2026-06-28 03:17:55 +08:00
|
|
|
var w = Application.Current.Windows.OfType<BetterSeewoMainWindow>().FirstOrDefault();
|
|
|
|
|
if (w != null) { w.Activate(); return; }
|
|
|
|
|
new BetterSeewoMainWindow().Show();
|
2026-06-28 02:43:22 +08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|