From 365459f64957394d51b0b6d367c80c6491d76a8d Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Sun, 24 Aug 2025 02:27:57 +0800 Subject: [PATCH] =?UTF-8?q?improve:=E5=BF=AB=E6=8D=B7=E9=94=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/Helpers/GlobalHotkeyManager.cs | 314 +++++++++++++++++- Ink Canvas/HotkeyConfig.json | 96 ++++++ Ink Canvas/Windows/HotkeyItem.xaml.cs | 7 +- .../Windows/HotkeySettingsWindow.xaml.cs | 47 ++- 4 files changed, 456 insertions(+), 8 deletions(-) create mode 100644 Ink Canvas/HotkeyConfig.json diff --git a/Ink Canvas/Helpers/GlobalHotkeyManager.cs b/Ink Canvas/Helpers/GlobalHotkeyManager.cs index 4ab1a459..cb5a1d21 100644 --- a/Ink Canvas/Helpers/GlobalHotkeyManager.cs +++ b/Ink Canvas/Helpers/GlobalHotkeyManager.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; using System.Windows.Input; +using System.IO; +using Newtonsoft.Json; using NHotkey.Wpf; namespace Ink_Canvas.Helpers @@ -14,6 +16,10 @@ namespace Ink_Canvas.Helpers private readonly Dictionary _registeredHotkeys; private readonly MainWindow _mainWindow; private bool _isDisposed = false; + + // 配置文件路径 + private static readonly string HotkeyConfigFile = Path.Combine(App.RootPath, "HotkeyConfig.json"); + private static readonly string HotkeyConfigBackupFile = Path.Combine(App.RootPath, "HotkeyConfig.json.bak"); #endregion #region Constructor @@ -207,13 +213,28 @@ namespace Ink_Canvas.Helpers { try { - // 这里可以从配置文件或设置中加载自定义快捷键 - // 暂时使用默认快捷键 - RegisterDefaultHotkeys(); + LogHelper.WriteLogToFile("开始从配置文件加载快捷键设置", LogHelper.LogType.Event); + + // 先注销所有现有快捷键 + UnregisterAllHotkeys(); + + // 尝试从配置文件加载 + if (LoadHotkeysFromConfigFile()) + { + LogHelper.WriteLogToFile("成功从配置文件加载快捷键设置", LogHelper.LogType.Event); + } + else + { + // 如果配置文件不存在或加载失败,使用默认快捷键 + LogHelper.WriteLogToFile("配置文件不存在或加载失败,使用默认快捷键", LogHelper.LogType.Warning); + RegisterDefaultHotkeys(); + } } catch (Exception ex) { LogHelper.WriteLogToFile($"从设置加载快捷键时出错: {ex.Message}", LogHelper.LogType.Error); + // 出错时使用默认快捷键 + RegisterDefaultHotkeys(); } } @@ -224,14 +245,64 @@ namespace Ink_Canvas.Helpers { try { - // 这里可以将快捷键配置保存到配置文件或设置中 - LogHelper.WriteLogToFile("快捷键配置已保存", LogHelper.LogType.Event); + LogHelper.WriteLogToFile("开始保存快捷键配置到配置文件", LogHelper.LogType.Event); + + if (SaveHotkeysToConfigFile()) + { + LogHelper.WriteLogToFile("快捷键配置已成功保存到配置文件", LogHelper.LogType.Event); + } + else + { + LogHelper.WriteLogToFile("保存快捷键配置失败", LogHelper.LogType.Error); + } } catch (Exception ex) { LogHelper.WriteLogToFile($"保存快捷键配置时出错: {ex.Message}", LogHelper.LogType.Error); } } + + /// + /// 更新快捷键配置 + /// + /// 快捷键名称 + /// 新按键 + /// 新修饰键 + /// 是否更新成功 + public bool UpdateHotkey(string hotkeyName, Key key, ModifierKeys modifiers) + { + try + { + if (!_registeredHotkeys.ContainsKey(hotkeyName)) + { + LogHelper.WriteLogToFile($"快捷键 {hotkeyName} 不存在,无法更新", LogHelper.LogType.Warning); + return false; + } + + // 获取原有的动作 + var originalAction = _registeredHotkeys[hotkeyName].Action; + + // 注销原有快捷键 + UnregisterHotkey(hotkeyName); + + // 注册新的快捷键 + var success = RegisterHotkey(hotkeyName, key, modifiers, originalAction); + + if (success) + { + LogHelper.WriteLogToFile($"成功更新快捷键 {hotkeyName}: {modifiers}+{key}", LogHelper.LogType.Event); + // 自动保存配置 + SaveHotkeysToSettings(); + } + + return success; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"更新快捷键 {hotkeyName} 时出错: {ex.Message}", LogHelper.LogType.Error); + return false; + } + } #endregion #region Private Helper Methods @@ -266,6 +337,219 @@ namespace Ink_Canvas.Helpers LogHelper.WriteLogToFile($"切换到笔类型{penTypeIndex}时出错: {ex.Message}", LogHelper.LogType.Error); } } + + /// + /// 从配置文件加载快捷键设置 + /// + /// 是否加载成功 + private bool LoadHotkeysFromConfigFile() + { + try + { + if (!File.Exists(HotkeyConfigFile)) + { + LogHelper.WriteLogToFile($"快捷键配置文件不存在: {HotkeyConfigFile}", LogHelper.LogType.Warning); + return false; + } + + // 读取配置文件内容 + string jsonContent = File.ReadAllText(HotkeyConfigFile, System.Text.Encoding.UTF8); + if (string.IsNullOrEmpty(jsonContent)) + { + LogHelper.WriteLogToFile("快捷键配置文件为空", LogHelper.LogType.Warning); + return false; + } + + // 反序列化配置 + var config = JsonConvert.DeserializeObject(jsonContent); + if (config?.Hotkeys == null || config.Hotkeys.Count == 0) + { + LogHelper.WriteLogToFile("快捷键配置为空或格式错误", LogHelper.LogType.Warning); + return false; + } + + // 注册配置中的快捷键 + int successCount = 0; + foreach (var hotkeyConfig in config.Hotkeys) + { + try + { + // 根据快捷键名称获取对应的动作 + var action = GetActionByName(hotkeyConfig.Name); + if (action != null) + { + if (RegisterHotkey(hotkeyConfig.Name, hotkeyConfig.Key, hotkeyConfig.Modifiers, action)) + { + successCount++; + } + } + else + { + LogHelper.WriteLogToFile($"未找到快捷键 {hotkeyConfig.Name} 对应的动作", LogHelper.LogType.Warning); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"注册快捷键 {hotkeyConfig.Name} 时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + + LogHelper.WriteLogToFile($"成功加载 {successCount}/{config.Hotkeys.Count} 个快捷键配置", LogHelper.LogType.Event); + return successCount > 0; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"从配置文件加载快捷键时出错: {ex.Message}", LogHelper.LogType.Error); + + // 尝试从备份文件加载 + if (File.Exists(HotkeyConfigBackupFile)) + { + LogHelper.WriteLogToFile("尝试从备份文件加载快捷键配置", LogHelper.LogType.Warning); + try + { + string backupContent = File.ReadAllText(HotkeyConfigBackupFile, System.Text.Encoding.UTF8); + var backupConfig = JsonConvert.DeserializeObject(backupContent); + if (backupConfig?.Hotkeys != null && backupConfig.Hotkeys.Count > 0) + { + // 恢复备份文件 + File.Copy(HotkeyConfigBackupFile, HotkeyConfigFile, true); + LogHelper.WriteLogToFile("已从备份文件恢复快捷键配置", LogHelper.LogType.Event); + return LoadHotkeysFromConfigFile(); + } + } + catch (Exception backupEx) + { + LogHelper.WriteLogToFile($"从备份文件加载快捷键配置时出错: {backupEx.Message}", LogHelper.LogType.Error); + } + } + + return false; + } + } + + /// + /// 保存快捷键配置到配置文件 + /// + /// 是否保存成功 + private bool SaveHotkeysToConfigFile() + { + try + { + // 确保配置目录存在 + string configDir = Path.GetDirectoryName(HotkeyConfigFile); + if (!Directory.Exists(configDir)) + { + Directory.CreateDirectory(configDir); + } + + // 创建配置对象 + var config = new HotkeyConfig + { + Version = "1.0", + LastModified = DateTime.Now, + Hotkeys = new List() + }; + + // 添加所有已注册的快捷键 + foreach (var hotkey in _registeredHotkeys.Values) + { + config.Hotkeys.Add(new HotkeyConfigItem + { + Name = hotkey.Name, + Key = hotkey.Key, + Modifiers = hotkey.Modifiers + }); + } + + // 序列化为JSON + var settings = new JsonSerializerSettings + { + Formatting = Formatting.Indented + }; + + string jsonContent = JsonConvert.SerializeObject(config, settings); + + // 先写入临时文件,然后替换原文件(原子操作) + string tempFile = HotkeyConfigFile + ".temp"; + File.WriteAllText(tempFile, jsonContent, System.Text.Encoding.UTF8); + + // 如果原文件存在,先备份 + if (File.Exists(HotkeyConfigFile)) + { + File.Copy(HotkeyConfigFile, HotkeyConfigBackupFile, true); + } + + // 替换原文件 + File.Move(tempFile, HotkeyConfigFile); + + LogHelper.WriteLogToFile($"快捷键配置已保存到: {HotkeyConfigFile}", LogHelper.LogType.Event); + return true; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"保存快捷键配置到配置文件时出错: {ex.Message}", LogHelper.LogType.Error); + return false; + } + } + + /// + /// 根据快捷键名称获取对应的动作 + /// + /// 快捷键名称 + /// 对应的动作,如果不存在则返回null + private Action GetActionByName(string hotkeyName) + { + try + { + switch (hotkeyName) + { + case "Undo": + return () => _mainWindow.SymbolIconUndo_MouseUp(null, null); + case "Redo": + return () => _mainWindow.SymbolIconRedo_MouseUp(null, null); + case "Clear": + return () => _mainWindow.SymbolIconDelete_MouseUp(null, null); + case "Paste": + return () => _mainWindow.HandleGlobalPaste(null, null); + case "SelectTool": + return () => _mainWindow.SymbolIconSelect_MouseUp(null, null); + case "DrawTool": + return () => _mainWindow.PenIcon_Click(null, null); + case "EraserTool": + return () => _mainWindow.EraserIcon_Click(null, null); + case "BlackboardTool": + return () => _mainWindow.ImageBlackboard_MouseUp(null, null); + case "QuitDrawTool": + return () => _mainWindow.CursorIcon_Click(null, null); + case "Pen1": + return () => SwitchToPenType(0); + case "Pen2": + return () => SwitchToPenType(1); + case "Pen3": + return () => SwitchToPenType(2); + case "Pen4": + return () => SwitchToPenType(3); + case "Pen5": + return () => SwitchToPenType(4); + case "DrawLine": + return () => _mainWindow.BtnDrawLine_Click(null, null); + case "Screenshot": + return () => _mainWindow.SaveScreenShotToDesktop(); + case "Hide": + return () => _mainWindow.SymbolIconEmoji_MouseUp(null, null); + case "Exit": + return () => _mainWindow.KeyExit(null, null); + default: + LogHelper.WriteLogToFile($"未知的快捷键名称: {hotkeyName}", LogHelper.LogType.Warning); + return null; + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"获取快捷键 {hotkeyName} 对应动作时出错: {ex.Message}", LogHelper.LogType.Error); + return null; + } + } #endregion #region IDisposable Implementation @@ -296,6 +580,26 @@ namespace Ink_Canvas.Helpers return $"{modifiersText}{Key}"; } } + + /// + /// 快捷键配置类 + /// + private class HotkeyConfig + { + public string Version { get; set; } + public DateTime LastModified { get; set; } + public List Hotkeys { get; set; } + } + + /// + /// 快捷键配置项类 + /// + private class HotkeyConfigItem + { + public string Name { get; set; } + public Key Key { get; set; } + public ModifierKeys Modifiers { get; set; } + } #endregion } } \ No newline at end of file diff --git a/Ink Canvas/HotkeyConfig.json b/Ink Canvas/HotkeyConfig.json new file mode 100644 index 00000000..4ce2d1ee --- /dev/null +++ b/Ink Canvas/HotkeyConfig.json @@ -0,0 +1,96 @@ +{ + "Version": "1.0", + "LastModified": "2025-01-28T15:30:00", + "Hotkeys": [ + { + "Name": "Undo", + "Key": "Z", + "Modifiers": "Control" + }, + { + "Name": "Redo", + "Key": "Y", + "Modifiers": "Control" + }, + { + "Name": "Clear", + "Key": "E", + "Modifiers": "Control" + }, + { + "Name": "Paste", + "Key": "V", + "Modifiers": "Control" + }, + { + "Name": "SelectTool", + "Key": "S", + "Modifiers": "Alt" + }, + { + "Name": "DrawTool", + "Key": "D", + "Modifiers": "Alt" + }, + { + "Name": "EraserTool", + "Key": "E", + "Modifiers": "Alt" + }, + { + "Name": "BlackboardTool", + "Key": "B", + "Modifiers": "Alt" + }, + { + "Name": "QuitDrawTool", + "Key": "Q", + "Modifiers": "Alt" + }, + { + "Name": "Pen1", + "Key": "D1", + "Modifiers": "Alt" + }, + { + "Name": "Pen2", + "Key": "D2", + "Modifiers": "Alt" + }, + { + "Name": "Pen3", + "Key": "D3", + "Modifiers": "Alt" + }, + { + "Name": "Pen4", + "Key": "D4", + "Modifiers": "Alt" + }, + { + "Name": "Pen5", + "Key": "D5", + "Modifiers": "Alt" + }, + { + "Name": "DrawLine", + "Key": "L", + "Modifiers": "Alt" + }, + { + "Name": "Screenshot", + "Key": "C", + "Modifiers": "Alt" + }, + { + "Name": "Hide", + "Key": "V", + "Modifiers": "Alt" + }, + { + "Name": "Exit", + "Key": "Escape", + "Modifiers": "None" + } + ] +} \ No newline at end of file diff --git a/Ink Canvas/Windows/HotkeyItem.xaml.cs b/Ink Canvas/Windows/HotkeyItem.xaml.cs index 3ff70c8c..4f498877 100644 --- a/Ink Canvas/Windows/HotkeyItem.xaml.cs +++ b/Ink Canvas/Windows/HotkeyItem.xaml.cs @@ -32,6 +32,11 @@ namespace Ink_Canvas.Windows public string DefaultKey { get; set; } public string DefaultModifiers { get; set; } + + /// + /// 快捷键名称(用于标识,如"Undo") + /// + public string HotkeyName { get; set; } private Key _currentKey = Key.None; private ModifierKeys _currentModifiers = ModifierKeys.None; @@ -144,7 +149,7 @@ namespace Ink_Canvas.Windows // 触发快捷键变更事件 HotkeyChanged?.Invoke(this, new HotkeyChangedEventArgs { - HotkeyName = Title, + HotkeyName = HotkeyName ?? Title, // 优先使用HotkeyName,如果没有则使用Title Key = _currentKey, Modifiers = _currentModifiers }); diff --git a/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs b/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs index 453122cb..1d3c30dc 100644 --- a/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs +++ b/Ink Canvas/Windows/HotkeySettingsWindow.xaml.cs @@ -39,25 +39,60 @@ namespace Ink_Canvas.Windows #region Private Methods private void InitializeHotkeyItems() { - // 初始化快捷键项 + // 初始化快捷键项并设置HotkeyName _hotkeyItems["Undo"] = UndoHotkey; + UndoHotkey.HotkeyName = "Undo"; + _hotkeyItems["Redo"] = RedoHotkey; + RedoHotkey.HotkeyName = "Redo"; + _hotkeyItems["Clear"] = ClearHotkey; + ClearHotkey.HotkeyName = "Clear"; + _hotkeyItems["Paste"] = PasteHotkey; + PasteHotkey.HotkeyName = "Paste"; + _hotkeyItems["SelectTool"] = SelectToolHotkey; + SelectToolHotkey.HotkeyName = "SelectTool"; + _hotkeyItems["DrawTool"] = DrawToolHotkey; + DrawToolHotkey.HotkeyName = "DrawTool"; + _hotkeyItems["EraserTool"] = EraserToolHotkey; + EraserToolHotkey.HotkeyName = "EraserTool"; + _hotkeyItems["BlackboardTool"] = BlackboardToolHotkey; + BlackboardToolHotkey.HotkeyName = "BlackboardTool"; + _hotkeyItems["QuitDrawTool"] = QuitDrawToolHotkey; + QuitDrawToolHotkey.HotkeyName = "QuitDrawTool"; + _hotkeyItems["Pen1"] = Pen1Hotkey; + Pen1Hotkey.HotkeyName = "Pen1"; + _hotkeyItems["Pen2"] = Pen2Hotkey; + Pen2Hotkey.HotkeyName = "Pen2"; + _hotkeyItems["Pen3"] = Pen3Hotkey; + Pen3Hotkey.HotkeyName = "Pen3"; + _hotkeyItems["Pen4"] = Pen4Hotkey; + Pen4Hotkey.HotkeyName = "Pen4"; + _hotkeyItems["Pen5"] = Pen5Hotkey; + Pen5Hotkey.HotkeyName = "Pen5"; + _hotkeyItems["DrawLine"] = DrawLineHotkey; + DrawLineHotkey.HotkeyName = "DrawLine"; + _hotkeyItems["Screenshot"] = ScreenshotHotkey; + ScreenshotHotkey.HotkeyName = "Screenshot"; + _hotkeyItems["Hide"] = HideHotkey; + HideHotkey.HotkeyName = "Hide"; + _hotkeyItems["Exit"] = ExitHotkey; + ExitHotkey.HotkeyName = "Exit"; } private void LoadCurrentHotkeys() @@ -132,7 +167,15 @@ namespace Ink_Canvas.Windows var action = GetActionForHotkey(hotkeyName); if (action != null) { - _hotkeyManager.RegisterHotkey(hotkeyName, key, modifiers, action); + // 使用快捷键管理器的UpdateHotkey方法,这会自动保存配置 + if (_hotkeyManager.UpdateHotkey(hotkeyName, key, modifiers)) + { + LogHelper.WriteLogToFile($"快捷键 {hotkeyName} 已更新为 {modifiers}+{key} 并自动保存", LogHelper.LogType.Event); + } + else + { + LogHelper.WriteLogToFile($"更新快捷键 {hotkeyName} 失败", LogHelper.LogType.Error); + } } } catch (Exception ex)