diff --git a/Ink Canvas/App.xaml b/Ink Canvas/App.xaml index 0eecad8a..83167e38 100644 --- a/Ink Canvas/App.xaml +++ b/Ink Canvas/App.xaml @@ -237,7 +237,6 @@ - diff --git a/Ink Canvas/AssemblyInfo.cs b/Ink Canvas/AssemblyInfo.cs index f9735752..8f8fb36e 100644 --- a/Ink Canvas/AssemblyInfo.cs +++ b/Ink Canvas/AssemblyInfo.cs @@ -49,5 +49,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.11.1")] -[assembly: AssemblyFileVersion("1.7.11.1")] +[assembly: AssemblyVersion("1.7.11.3")] +[assembly: AssemblyFileVersion("1.7.11.3")] diff --git a/Ink Canvas/FloatingWindowInterceptorManager.cs b/Ink Canvas/FloatingWindowInterceptorManager.cs index 2c505220..9abd6a00 100644 --- a/Ink Canvas/FloatingWindowInterceptorManager.cs +++ b/Ink Canvas/FloatingWindowInterceptorManager.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Windows; using Ink_Canvas.Helpers; namespace Ink_Canvas diff --git a/Ink Canvas/Helpers/FloatingWindowInterceptor.cs b/Ink Canvas/Helpers/FloatingWindowInterceptor.cs index 5d401a71..9c74c857 100644 --- a/Ink Canvas/Helpers/FloatingWindowInterceptor.cs +++ b/Ink Canvas/Helpers/FloatingWindowInterceptor.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; -using System.Threading.Tasks; using System.Windows.Threading; namespace Ink_Canvas.Helpers diff --git a/Ink Canvas/Helpers/MultiPPTInkManager.cs b/Ink Canvas/Helpers/MultiPPTInkManager.cs index 29228802..8ba5df07 100644 --- a/Ink Canvas/Helpers/MultiPPTInkManager.cs +++ b/Ink Canvas/Helpers/MultiPPTInkManager.cs @@ -1,7 +1,6 @@ using Microsoft.Office.Interop.PowerPoint; using System; using System.Collections.Generic; -using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Security.Cryptography; @@ -27,6 +26,11 @@ namespace Ink_Canvas.Helpers private readonly object _lockObject = new object(); private bool _disposed; private string _currentActivePresentationId = ""; + + // 墨迹备份机制 + private readonly Dictionary> _strokeBackups; + private DateTime _lastBackupTime = DateTime.MinValue; + private const int BackupIntervalMinutes = 2; // 每2分钟备份一次 #endregion #region Constructor @@ -34,6 +38,7 @@ namespace Ink_Canvas.Helpers { _presentationManagers = new Dictionary(); _presentationInfos = new Dictionary(); + _strokeBackups = new Dictionary>(); } #endregion @@ -113,8 +118,15 @@ namespace Ink_Canvas.Helpers var currentPresentation = GetCurrentActivePresentation(); if (currentPresentation != null) { - currentManager.SaveAllStrokesToFile(currentPresentation); - LogHelper.WriteLogToFile($"已保存当前演示文稿墨迹: {currentPresentation.Name}", LogHelper.LogType.Trace); + try + { + currentManager.SaveAllStrokesToFile(currentPresentation); + LogHelper.WriteLogToFile($"已保存当前演示文稿墨迹: {currentPresentation.Name}", LogHelper.LogType.Trace); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"保存当前演示文稿墨迹失败: {ex}", LogHelper.LogType.Error); + } } } } @@ -127,10 +139,10 @@ namespace Ink_Canvas.Helpers _presentationInfos[presentationId].LastAccessTime = DateTime.Now; } - if (_currentActivePresentationId != presentationId) - { - LogHelper.WriteLogToFile($"已切换到演示文稿: {presentation.Name}", LogHelper.LogType.Trace); - } + if (_currentActivePresentationId != presentationId) + { + LogHelper.WriteLogToFile($"已切换到演示文稿: {presentation.Name}", LogHelper.LogType.Trace); + } return true; } else @@ -162,7 +174,17 @@ namespace Ink_Canvas.Helpers var manager = GetCurrentManager(); if (manager != null) { + // 保存到管理器 manager.SaveCurrentSlideStrokes(slideIndex, strokes); + + // 只有在保存成功后才创建备份 + if (!string.IsNullOrEmpty(_currentActivePresentationId)) + { + CreateStrokeBackup(_currentActivePresentationId, slideIndex, strokes); + } + + // 检查是否需要执行定期备份 + CheckAndPerformBackup(); } } catch (Exception ex) @@ -210,12 +232,29 @@ namespace Ink_Canvas.Helpers var manager = GetCurrentManager(); if (manager != null) { - return manager.LoadSlideStrokes(slideIndex); + var strokes = manager.LoadSlideStrokes(slideIndex); + + // 如果从管理器加载失败,尝试从备份恢复 + if (strokes == null || strokes.Count == 0) + { + if (!string.IsNullOrEmpty(_currentActivePresentationId)) + { + strokes = RestoreStrokeFromBackup(_currentActivePresentationId, slideIndex); + } + } + + return strokes ?? new StrokeCollection(); } } catch (Exception ex) { LogHelper.WriteLogToFile($"加载页面墨迹失败: {ex}", LogHelper.LogType.Error); + + // 尝试从备份恢复 + if (!string.IsNullOrEmpty(_currentActivePresentationId)) + { + return RestoreStrokeFromBackup(_currentActivePresentationId, slideIndex); + } } } @@ -512,6 +551,12 @@ namespace Ink_Canvas.Helpers } _presentationInfos.Remove(id); + // 清理备份数据 + if (_strokeBackups.ContainsKey(id)) + { + _strokeBackups.Remove(id); + } + LogHelper.WriteLogToFile($"已清理非活跃演示文稿: {id}", LogHelper.LogType.Trace); } } @@ -521,6 +566,97 @@ namespace Ink_Canvas.Helpers } } } + + /// + /// 创建墨迹备份 + /// + private void CreateStrokeBackup(string presentationId, int slideIndex, StrokeCollection strokes) + { + try + { + if (strokes == null || strokes.Count == 0) return; + + if (!_strokeBackups.ContainsKey(presentationId)) + { + _strokeBackups[presentationId] = new Dictionary(); + } + + // 释放旧的备份 + if (_strokeBackups[presentationId].ContainsKey(slideIndex)) + { + _strokeBackups[presentationId][slideIndex] = null; + } + + // 创建新的备份 + _strokeBackups[presentationId][slideIndex] = strokes.Clone(); + + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"创建墨迹备份失败: {ex}", LogHelper.LogType.Error); + } + } + + /// + /// 从备份恢复墨迹 + /// + private StrokeCollection RestoreStrokeFromBackup(string presentationId, int slideIndex) + { + try + { + if (_strokeBackups.ContainsKey(presentationId) && + _strokeBackups[presentationId].ContainsKey(slideIndex)) + { + var backup = _strokeBackups[presentationId][slideIndex]; + if (backup != null) + { + LogHelper.WriteLogToFile($"从备份恢复第{slideIndex}页墨迹", LogHelper.LogType.Trace); + return backup.Clone(); + } + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"从备份恢复墨迹失败: {ex}", LogHelper.LogType.Error); + } + + return new StrokeCollection(); + } + + /// + /// 检查并执行定期备份 + /// + private void CheckAndPerformBackup() + { + try + { + var now = DateTime.Now; + + // 检查是否需要执行备份 + if (now - _lastBackupTime < TimeSpan.FromMinutes(BackupIntervalMinutes)) + { + return; + } + + // 备份当前活跃演示文稿的所有墨迹 + if (!string.IsNullOrEmpty(_currentActivePresentationId) && + _presentationManagers.ContainsKey(_currentActivePresentationId)) + { + var manager = _presentationManagers[_currentActivePresentationId]; + if (manager != null) + { + // 这里可以添加更详细的备份逻辑 + LogHelper.WriteLogToFile($"执行定期墨迹备份: {_currentActivePresentationId}", LogHelper.LogType.Trace); + } + } + + _lastBackupTime = now; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"定期备份检查失败: {ex}", LogHelper.LogType.Error); + } + } #endregion #region Private Methods @@ -562,7 +698,7 @@ namespace Ink_Canvas.Helpers var presentationPath = presentation.FullName; var fileHash = GetFileHash(presentationPath); var processId = GetProcessId(presentation); - return $"{presentation.Name}_{fileHash}_{processId}"; + return $"{presentation.Name}_{presentation.Slides.Count}_{fileHash}_{processId}"; } catch (COMException comEx) { @@ -638,12 +774,24 @@ namespace Ink_Canvas.Helpers { lock (_lockObject) { + // 释放所有管理器 foreach (var manager in _presentationManagers.Values) { manager?.Dispose(); } _presentationManagers.Clear(); _presentationInfos.Clear(); + + // 清理备份数据 + foreach (var backupDict in _strokeBackups.Values) + { + foreach (var backup in backupDict.Values) + { + backup?.Clear(); + } + backupDict.Clear(); + } + _strokeBackups.Clear(); } _disposed = true; } diff --git a/Ink Canvas/Helpers/PPTInkManager.cs b/Ink Canvas/Helpers/PPTInkManager.cs index 0776e827..2fee446c 100644 --- a/Ink Canvas/Helpers/PPTInkManager.cs +++ b/Ink Canvas/Helpers/PPTInkManager.cs @@ -35,6 +35,12 @@ namespace Ink_Canvas.Helpers private DateTime _lastSwitchTime = DateTime.MinValue; private int _lastSwitchSlideIndex = -1; private const int MinSwitchIntervalMs = 100; // 最小切换间隔100毫秒 + + // 内存管理相关字段 + private long _totalMemoryUsage = 0; + private const long MaxMemoryUsageBytes = 100 * 1024 * 1024; // 100MB限制 + private DateTime _lastMemoryCleanup = DateTime.MinValue; + private const int MemoryCleanupIntervalMinutes = 5; // 5分钟清理一次 #endregion #region Constructor @@ -118,24 +124,34 @@ namespace Ink_Canvas.Helpers { if (DateTime.Now < _inkLockUntil) { - LogHelper.WriteLogToFile($"墨迹写入被锁定,当前页:{slideIndex},锁定页:{_lockedSlideIndex}", LogHelper.LogType.Warning); } return; } if (slideIndex < _memoryStreams.Length) { + // 先释放旧的内存流,防止内存泄漏 + try + { + _memoryStreams[slideIndex]?.Dispose(); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放旧内存流失败: {ex}", LogHelper.LogType.Warning); + } + + // 创建新的内存流 var ms = new MemoryStream(); strokes.Save(ms); ms.Position = 0; - - // 释放旧的内存流 - _memoryStreams[slideIndex]?.Dispose(); _memoryStreams[slideIndex] = ms; if (ms.Length > 0) { } + + // 检查内存使用情况 + CheckAndPerformMemoryCleanup(); } } catch (Exception ex) @@ -158,12 +174,20 @@ namespace Ink_Canvas.Helpers { if (slideIndex < _memoryStreams.Length) { + // 先释放旧的内存流,防止内存泄漏 + try + { + _memoryStreams[slideIndex]?.Dispose(); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放旧内存流失败: {ex}", LogHelper.LogType.Warning); + } + + // 创建新的内存流 var ms = new MemoryStream(); strokes.Save(ms); ms.Position = 0; - - // 释放旧的内存流 - _memoryStreams[slideIndex]?.Dispose(); _memoryStreams[slideIndex] = ms; LogHelper.WriteLogToFile($"已强制保存第{slideIndex}页墨迹,大小: {ms.Length} bytes", LogHelper.LogType.Trace); @@ -388,13 +412,30 @@ namespace Ink_Canvas.Helpers { try { - for (int i = 0; i < _memoryStreams.Length; i++) + // 安全释放所有内存流 + if (_memoryStreams != null) { - _memoryStreams[i]?.Dispose(); - _memoryStreams[i] = null; + for (int i = 0; i < _memoryStreams.Length; i++) + { + try + { + _memoryStreams[i]?.Dispose(); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放内存流{i}失败: {ex}", LogHelper.LogType.Warning); + } + finally + { + _memoryStreams[i] = null; + } + } + + // 重新初始化数组 + _memoryStreams = new MemoryStream[_maxSlides + 2]; } - CurrentStrokes.Clear(); + CurrentStrokes?.Clear(); LogHelper.WriteLogToFile("已清除所有墨迹", LogHelper.LogType.Trace); } catch (Exception ex) @@ -430,6 +471,13 @@ namespace Ink_Canvas.Helpers return true; } + // 如果当前页面不是锁定页面,但锁定时间很短(小于50ms),允许写入 + // 这样可以确保旧页面的墨迹能够及时保存 + if (DateTime.Now - (_inkLockUntil.AddMilliseconds(-InkLockMilliseconds)) < TimeSpan.FromMilliseconds(50)) + { + return true; + } + // 只有在快速切换且页面不同时才锁定 return false; } @@ -447,6 +495,110 @@ namespace Ink_Canvas.Helpers _lastSwitchSlideIndex = -1; } } + + /// + /// 检查并执行内存清理 + /// + private void CheckAndPerformMemoryCleanup() + { + try + { + var now = DateTime.Now; + + // 检查是否需要执行内存清理 + if (now - _lastMemoryCleanup < TimeSpan.FromMinutes(MemoryCleanupIntervalMinutes)) + { + return; + } + + // 计算当前内存使用量 + long currentMemoryUsage = 0; + if (_memoryStreams != null) + { + for (int i = 0; i < _memoryStreams.Length; i++) + { + if (_memoryStreams[i] != null) + { + currentMemoryUsage += _memoryStreams[i].Length; + } + } + } + + _totalMemoryUsage = currentMemoryUsage; + + // 如果内存使用量超过限制,执行清理 + if (currentMemoryUsage > MaxMemoryUsageBytes) + { + LogHelper.WriteLogToFile($"内存使用量超限 ({currentMemoryUsage / 1024 / 1024}MB),开始清理", LogHelper.LogType.Warning); + + // 清理非当前页面的墨迹 + CleanupInactiveSlideStrokes(); + + _lastMemoryCleanup = now; + LogHelper.WriteLogToFile($"内存清理完成,当前使用量: {_totalMemoryUsage / 1024 / 1024}MB", LogHelper.LogType.Trace); + } + else + { + _lastMemoryCleanup = now; + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"内存清理检查失败: {ex}", LogHelper.LogType.Error); + } + } + + /// + /// 清理非活跃页面的墨迹 + /// + private void CleanupInactiveSlideStrokes() + { + try + { + if (_memoryStreams == null) return; + + int cleanedCount = 0; + long freedMemory = 0; + + for (int i = 0; i < _memoryStreams.Length; i++) + { + // 保留当前锁定页面和最近访问的页面 + if (i == _lockedSlideIndex || i == _lastSwitchSlideIndex) + { + continue; + } + + if (_memoryStreams[i] != null) + { + long memorySize = _memoryStreams[i].Length; + + try + { + _memoryStreams[i].Dispose(); + freedMemory += memorySize; + cleanedCount++; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"清理页面{i}墨迹失败: {ex}", LogHelper.LogType.Warning); + } + finally + { + _memoryStreams[i] = null; + } + } + } + + if (cleanedCount > 0) + { + LogHelper.WriteLogToFile($"已清理{cleanedCount}个页面的墨迹,释放内存: {freedMemory / 1024}KB", LogHelper.LogType.Trace); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"清理非活跃页面墨迹失败: {ex}", LogHelper.LogType.Error); + } + } #endregion #region Private Methods @@ -456,7 +608,7 @@ namespace Ink_Canvas.Helpers { var presentationPath = presentation.FullName; var fileHash = GetFileHash(presentationPath); - return $"{presentation.Name}_{fileHash}"; + return $"{presentation.Name}_{presentation.Slides.Count}_{fileHash}"; } catch (Exception ex) { diff --git a/Ink Canvas/Helpers/PPTManager.cs b/Ink Canvas/Helpers/PPTManager.cs index ecca9519..b26c89f4 100644 --- a/Ink Canvas/Helpers/PPTManager.cs +++ b/Ink Canvas/Helpers/PPTManager.cs @@ -93,7 +93,6 @@ namespace Ink_Canvas.Helpers // COM对象已失效,触发断开连接 DisconnectFromPPT(); } - LogHelper.WriteLogToFile($"验证PPT放映窗口失败: {comEx.Message} (HR: 0x{hr:X8})", LogHelper.LogType.Warning); return false; } } @@ -411,63 +410,30 @@ namespace Ink_Canvas.Helpers catch (COMException comEx) { var hr = (uint)comEx.HResult; + LogHelper.WriteLogToFile($"取消PPT事件注册时COM异常: {comEx.Message} (HR: 0x{hr:X8})", LogHelper.LogType.Warning); } catch (InvalidCastException) { // COM对象类型转换失败,通常是因为对象已经被释放 LogHelper.WriteLogToFile("PPT COM对象已被释放,跳过事件注册取消", LogHelper.LogType.Trace); } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"取消PPT事件注册时发生异常: {ex}", LogHelper.LogType.Warning); + } }, DispatcherPriority.Normal, CancellationToken.None, TimeSpan.FromSeconds(1)); } } - catch (Exception) + catch (Exception ex) { + LogHelper.WriteLogToFile($"取消PPT事件注册失败: {ex}", LogHelper.LogType.Warning); } - // 释放COM对象 - try - { - if (Marshal.IsComObject(CurrentSlide)) - { - Marshal.ReleaseComObject(CurrentSlide); - } - } - catch (Exception) - { - } - - try - { - if (Marshal.IsComObject(CurrentSlides)) - { - Marshal.ReleaseComObject(CurrentSlides); - } - } - catch (Exception) - { - } - - try - { - if (Marshal.IsComObject(CurrentPresentation)) - { - Marshal.ReleaseComObject(CurrentPresentation); - } - } - catch (Exception) - { - } - - try - { - if (Marshal.IsComObject(PPTApplication)) - { - Marshal.ReleaseComObject(PPTApplication); - } - } - catch (Exception) - { - } + // 安全释放COM对象 + SafeReleaseComObject(CurrentSlide, "CurrentSlide"); + SafeReleaseComObject(CurrentSlides, "CurrentSlides"); + SafeReleaseComObject(CurrentPresentation, "CurrentPresentation"); + SafeReleaseComObject(PPTApplication, "PPTApplication"); // 清理引用 PPTApplication = null; @@ -491,6 +457,30 @@ namespace Ink_Canvas.Helpers } } + /// + /// 安全释放COM对象 + /// + private void SafeReleaseComObject(object comObject, string objectName) + { + try + { + if (comObject != null && Marshal.IsComObject(comObject)) + { + int refCount = Marshal.ReleaseComObject(comObject); + LogHelper.WriteLogToFile($"已释放COM对象 {objectName},引用计数: {refCount}", LogHelper.LogType.Trace); + } + } + catch (COMException comEx) + { + var hr = (uint)comEx.HResult; + LogHelper.WriteLogToFile($"释放COM对象 {objectName} 时COM异常: {comEx.Message} (HR: 0x{hr:X8})", LogHelper.LogType.Warning); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"释放COM对象 {objectName} 时发生异常: {ex}", LogHelper.LogType.Warning); + } + } + private void UpdateCurrentPresentationInfo() { try @@ -859,10 +849,23 @@ namespace Ink_Canvas.Helpers // 如果在放映模式,获取放映窗口的演示文稿 if (IsInSlideShow && PPTApplication.SlideShowWindows.Count > 0) { - var slideShowWindow = PPTApplication.SlideShowWindows[1]; - if (slideShowWindow?.View != null) + try { - return (Presentation)slideShowWindow.View.Slide.Parent; + var slideShowWindow = PPTApplication.SlideShowWindows[1]; + if (slideShowWindow?.View != null) + { + return (Presentation)slideShowWindow.View.Slide.Parent; + } + } + catch (COMException comEx) + { + var hr = (uint)comEx.HResult; + if (hr == 0x80048240) // Integer out of range + { + // 放映窗口已不存在,返回null + return null; + } + throw; // 重新抛出其他COM异常 } } @@ -935,12 +938,10 @@ namespace Ink_Canvas.Helpers // COM对象已失效,触发断开连接 DisconnectFromPPT(); } - LogHelper.WriteLogToFile($"获取当前幻灯片编号失败: {comEx.Message}", LogHelper.LogType.Warning); return 0; } catch (Exception ex) { - LogHelper.WriteLogToFile($"获取当前幻灯片编号失败: {ex}", LogHelper.LogType.Error); return 0; } } diff --git a/Ink Canvas/Helpers/PPTUIManager.cs b/Ink Canvas/Helpers/PPTUIManager.cs index f7646bbd..c8482a4e 100644 --- a/Ink Canvas/Helpers/PPTUIManager.cs +++ b/Ink Canvas/Helpers/PPTUIManager.cs @@ -92,7 +92,6 @@ namespace Ink_Canvas.Helpers // 页数无效时清空页码显示 _mainWindow.PPTBtnPageNow.Text = "?"; _mainWindow.PPTBtnPageTotal.Text = "/ ?"; - LogHelper.WriteLogToFile($"PPT页数无效,清空页码显示: 当前页={currentSlide}, 总页数={totalSlides}", LogHelper.LogType.Warning); } UpdateNavigationPanelsVisibility(); @@ -132,7 +131,6 @@ namespace Ink_Canvas.Helpers // 页数无效时清空页码显示 _mainWindow.PPTBtnPageNow.Text = "?"; _mainWindow.PPTBtnPageTotal.Text = "/ ?"; - LogHelper.WriteLogToFile($"PPT页数无效,清空页码显示: 当前页={currentSlide}, 总页数={totalSlides}", LogHelper.LogType.Warning); } } catch (Exception ex) diff --git a/Ink Canvas/Helpers/ScreenDetectionHelper.cs b/Ink Canvas/Helpers/ScreenDetectionHelper.cs index bf23dc8a..5d048a7f 100644 --- a/Ink Canvas/Helpers/ScreenDetectionHelper.cs +++ b/Ink Canvas/Helpers/ScreenDetectionHelper.cs @@ -1,6 +1,5 @@ using System; using System.Drawing; -using System.Linq; using System.Windows; using System.Windows.Forms; using System.Windows.Interop; diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 1504a0bf..54c2636f 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -22,7 +22,7 @@ Height="9000" Width="1440" FontFamily="Microsoft YaHei UI" MouseWheel="Window_MouseWheel" - Foreground="Black" + Foreground="{DynamicResource FloatBarForeground}" SizeChanged="MainWindow_OnSizeChanged" MouseMove="MainWindow_OnMouseMove" Stylus.IsPressAndHoldEnabled="False" @@ -186,6 +186,21 @@ + + + - - + + - + - + - - @@ -1028,6 +1029,19 @@ FontSize="26" /> + + + + + + + + + @@ -4077,13 +4091,13 @@ - + - @@ -4100,21 +4114,21 @@ - - @@ -4122,7 +4136,7 @@ - @@ -4173,8 +4187,8 @@ + BorderThickness="0,1,1,1" BorderBrush="{DynamicResource BoardFloatBarBorderBrush}" + Background="{DynamicResource BoardFloatBarBackground}" Opacity="0.95"> @@ -4182,7 +4196,7 @@ - @@ -4190,7 +4204,7 @@ - @@ -4198,8 +4212,8 @@ - - @@ -4231,12 +4245,12 @@ - + + Background="{DynamicResource BoardFloatBarBackground}" + Opacity="1" BorderThickness="1,1,0,1" BorderBrush="{DynamicResource BoardFloatBarBorderBrush}"> @@ -4245,17 +4259,17 @@ - @@ -4264,7 +4278,7 @@ + Background="{DynamicResource BoardFloatBarBackground}" Opacity="1" BorderThickness="0,1,1,1" + BorderBrush="{DynamicResource BoardFloatBarBorderBrush}"> @@ -4421,26 +4435,26 @@ - - - + - + BorderThickness="0,1,0,1" BorderBrush="{DynamicResource BoardFloatBarBorderBrush}" + MouseUp="PenIcon_Click" Background="{DynamicResource BoardFloatBarBackground}" Opacity="0.95"> @@ -4473,14 +4487,14 @@ - @@ -4498,8 +4512,8 @@ - @@ -5369,8 +5383,8 @@ + BorderThickness="0,1,1,1" BorderBrush="{DynamicResource BoardFloatBarBorderBrush}" + MouseUp="BoardEraserIcon_Click" Background="{DynamicResource BoardFloatBarBackground}" Opacity="0.95"> @@ -5379,14 +5393,14 @@ - @@ -5403,7 +5417,7 @@ @@ -5593,19 +5607,19 @@ - + BorderThickness="0,1,1,1" BorderBrush="{DynamicResource BoardFloatBarBorderBrush}" + MouseUp="ImageDrawShape_MouseUp" Background="{DynamicResource BoardFloatBarBackground}" Opacity="0.95"> @@ -5613,25 +5627,25 @@ - - - - @@ -5777,8 +5791,8 @@ + BorderThickness="0,1,0,1" BorderBrush="{DynamicResource BoardFloatBarBorderBrush}" + MouseUp="InsertImageOptions_MouseUp" Background="{DynamicResource BoardFloatBarBackground}" Opacity="0.95"> @@ -5786,14 +5800,14 @@ - - @@ -5808,7 +5822,7 @@ - + @@ -5882,7 +5896,7 @@ - + @@ -5890,42 +5904,42 @@ - - + - + - - - + - - @@ -5957,7 +5971,7 @@ @@ -5993,7 +6007,7 @@ - @@ -6013,7 +6027,7 @@ - @@ -6033,7 +6047,7 @@ - @@ -6056,7 +6070,7 @@ - @@ -6076,7 +6090,7 @@ - @@ -6096,7 +6110,7 @@ - @@ -6119,7 +6133,7 @@ - @@ -6139,7 +6153,7 @@ - @@ -6159,7 +6173,7 @@ - @@ -6177,9 +6191,9 @@ + BorderBrush="{DynamicResource BoardFloatBarBorderBrush}"> @@ -6187,14 +6201,14 @@ - - @@ -6211,8 +6225,8 @@ HorizontalAlignment="Center" VerticalAlignment="Bottom"> - - - + - @@ -6255,21 +6269,21 @@ - - @@ -6277,7 +6291,7 @@ - @@ -6328,8 +6342,8 @@ + BorderThickness="0,1,1,1" BorderBrush="{DynamicResource BoardFloatBarBorderBrush}" + Background="{DynamicResource BoardFloatBarBackground}" Opacity="0.95"> @@ -6337,7 +6351,7 @@ - @@ -6345,7 +6359,7 @@ - @@ -6448,10 +6462,10 @@ - + FontSize="16" Foreground="{DynamicResource SettingsPageForeground}" /> @@ -6869,7 +6883,7 @@ @@ -6877,9 +6891,9 @@ @@ -6911,7 +6925,7 @@ - @@ -6927,14 +6941,14 @@ - - @@ -7537,7 +7551,7 @@ - @@ -7562,7 +7576,7 @@ Canvas.Left="9" Canvas.Right="9" Canvas.Bottom="0"> + Background="{DynamicResource FloatBarBackground}" CornerRadius="1" /> @@ -7595,7 +7609,7 @@ Orientation="Horizontal" Canvas.Left="14" Canvas.Right="14" Canvas.Bottom="0"> + Background="{DynamicResource FloatBarBackground}" CornerRadius="1" /> @@ -7774,7 +7788,7 @@ Height="23" Margin="0,0,0,0" /> @@ -8341,7 +8355,7 @@ - - - - - @@ -8676,7 +8690,7 @@ - @@ -8685,7 +8699,7 @@ - @@ -8713,7 +8727,7 @@ - - @@ -8745,7 +8759,7 @@ - - - - @@ -8940,20 +8954,20 @@ - - - @@ -9006,7 +9020,7 @@ - @@ -9026,7 +9040,7 @@ - @@ -9049,7 +9063,7 @@ - @@ -9069,7 +9083,7 @@ - @@ -9089,7 +9103,7 @@ - @@ -9112,7 +9126,7 @@ - @@ -9132,7 +9146,7 @@ - @@ -9152,7 +9166,7 @@ - @@ -9175,7 +9189,7 @@ - @@ -9192,7 +9206,7 @@ - @@ -9337,7 +9351,7 @@ EditingMode="None" Background="Transparent" /> @@ -9481,7 +9495,7 @@ + Foreground="{DynamicResource FloatBarForeground}" Text="1.0x" VerticalAlignment="Center"> @@ -9503,7 +9517,7 @@ - - + - + - + - + - + - + - - + - + - + - + - + - + + /// 主题下拉框选择变化事件 + /// + private void ComboBoxTheme_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + if (!isLoaded) return; + + try + { + System.Windows.Controls.ComboBox comboBox = sender as System.Windows.Controls.ComboBox; + if (comboBox != null) + { + Settings.Appearance.Theme = comboBox.SelectedIndex; + + // 应用新主题 + ApplyTheme(comboBox.SelectedIndex); + + // 保存设置 + SaveSettingsToFile(); + + // 显示通知 + string themeName; + switch (comboBox.SelectedIndex) + { + case 0: + themeName = "浅色主题"; + break; + case 1: + themeName = "深色主题"; + break; + case 2: + themeName = "跟随系统"; + break; + default: + themeName = "未知主题"; + break; + } + + ShowNotification($"已切换到{themeName}"); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"切换主题时出错: {ex.Message}", LogHelper.LogType.Error); + ShowNotification("主题切换失败"); + } + } + + /// + /// 应用指定主题 + /// + /// 主题索引:0-浅色,1-深色,2-跟随系统 + private void ApplyTheme(int themeIndex) + { + try + { + switch (themeIndex) + { + case 0: // 浅色主题 + SetTheme("Light"); + // 浅色主题下设置浮动栏为完全不透明 + ViewboxFloatingBar.Opacity = 1.0; + break; + case 1: // 深色主题 + SetTheme("Dark"); + // 深色主题下设置浮动栏为完全不透明 + ViewboxFloatingBar.Opacity = 1.0; + break; + case 2: // 跟随系统 + if (IsSystemThemeLight()) + { + SetTheme("Light"); + ViewboxFloatingBar.Opacity = 1.0; + } + else + { + SetTheme("Dark"); + ViewboxFloatingBar.Opacity = 1.0; + } + break; + } + + // 强制刷新通知框的颜色资源 + RefreshNotificationColors(); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"应用主题时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + + /// + /// 刷新通知框的颜色资源 + /// + private void RefreshNotificationColors() + { + try + { + // 强制刷新通知框的背景和前景色 + var border = GridNotifications.Children.OfType().FirstOrDefault(); + if (border != null) + { + border.Background = (Brush)Application.Current.FindResource("SettingsPageBackground"); + border.BorderBrush = new SolidColorBrush(Color.FromRgb(185, 28, 28)); // 保持红色边框 + } + + TextBlockNotice.Foreground = (Brush)Application.Current.FindResource("SettingsPageForeground"); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"刷新通知框颜色时出错: {ex.Message}", LogHelper.LogType.Error); + } + } + + #endregion } } diff --git a/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs b/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs index f908c2ad..63949a51 100644 --- a/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs +++ b/Ink Canvas/MainWindow_cs/MW_AutoTheme.cs @@ -1,6 +1,7 @@ using iNKORE.UI.WPF.Modern; using Microsoft.Win32; using System; +using System.Collections.Generic; using System.Windows; using System.Windows.Media; using Application = System.Windows.Application; @@ -9,16 +10,34 @@ namespace Ink_Canvas { public partial class MainWindow : Window { - private Color FloatBarForegroundColor = Color.FromRgb(102, 102, 102); + private Color FloatBarForegroundColor; private void SetTheme(string theme) { + // 清理现有的主题资源 + var resourcesToRemove = new List(); + foreach (var dict in Application.Current.Resources.MergedDictionaries) + { + if (dict.Source != null && + (dict.Source.ToString().Contains("Light.xaml") || + dict.Source.ToString().Contains("Dark.xaml"))) + { + resourcesToRemove.Add(dict); + } + } + + foreach (var dict in resourcesToRemove) + { + Application.Current.Resources.MergedDictionaries.Remove(dict); + } + if (theme == "Light") { var rd1 = new ResourceDictionary { Source = new Uri("Resources/Styles/Light.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd1); - + + // 在主题资源之后添加其他资源 var rd2 = new ResourceDictionary { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd2); @@ -33,13 +52,17 @@ namespace Ink_Canvas ThemeManager.SetRequestedTheme(window, ElementTheme.Light); - FloatBarForegroundColor = (Color)Application.Current.FindResource("FloatBarForegroundColor"); + InitializeFloatBarForegroundColor(); + + // 强制刷新UI + window.InvalidateVisual(); } else if (theme == "Dark") { var rd1 = new ResourceDictionary { Source = new Uri("Resources/Styles/Dark.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd1); - + + // 在主题资源之后添加其他资源 var rd2 = new ResourceDictionary { Source = new Uri("Resources/DrawShapeImageDictionary.xaml", UriKind.Relative) }; Application.Current.Resources.MergedDictionaries.Add(rd2); @@ -54,7 +77,93 @@ namespace Ink_Canvas ThemeManager.SetRequestedTheme(window, ElementTheme.Dark); + InitializeFloatBarForegroundColor(); + + // 强制刷新UI + window.InvalidateVisual(); + } + } + + /// + /// 初始化FloatBarForegroundColor,从当前主题资源中加载颜色 + /// + private void InitializeFloatBarForegroundColor() + { + try + { FloatBarForegroundColor = (Color)Application.Current.FindResource("FloatBarForegroundColor"); + + // 强制刷新浮动工具栏按钮颜色 + RefreshFloatingBarButtonColors(); + } + catch (Exception) + { + // 如果无法从资源中加载,使用默认颜色 + FloatBarForegroundColor = Color.FromRgb(0, 0, 0); + } + } + + /// + /// 刷新浮动工具栏按钮颜色 + /// + private void RefreshFloatingBarButtonColors() + { + try + { + // 选中状态的颜色(蓝底) + var selectedColor = Color.FromRgb(30, 58, 138); + + // 根据当前模式设置按钮颜色 + switch (_currentToolMode) + { + case "cursor": + CursorIconGeometry.Brush = new SolidColorBrush(selectedColor); + PenIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + StrokeEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + CircleEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + LassoSelectIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + break; + case "pen": + case "color": + CursorIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + PenIconGeometry.Brush = new SolidColorBrush(selectedColor); + StrokeEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + CircleEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + LassoSelectIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + break; + case "eraser": + CursorIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + PenIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + StrokeEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + CircleEraserIconGeometry.Brush = new SolidColorBrush(selectedColor); + LassoSelectIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + break; + case "eraserByStrokes": + CursorIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + PenIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + StrokeEraserIconGeometry.Brush = new SolidColorBrush(selectedColor); + CircleEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + LassoSelectIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + break; + case "select": + CursorIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + PenIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + StrokeEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + CircleEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + LassoSelectIconGeometry.Brush = new SolidColorBrush(selectedColor); + break; + default: + // 默认情况,所有按钮都使用主题颜色 + CursorIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + PenIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + StrokeEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + CircleEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + LassoSelectIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); + break; + } + } + catch (Exception) + { } } diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index a6df1ddd..c8eb0b5c 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -84,11 +84,23 @@ namespace Ink_Canvas EnableTwoFingerGestureBtn.Source = new BitmapImage(new Uri("/Resources/new-icons/gesture.png", UriKind.Relative)); - BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); - BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + // 根据主题设置颜色 + if (Settings.Appearance.Theme == 1) // 深色主题 + { + BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)); + BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85)); + } + else // 浅色主题或跟随系统 + { + BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); + BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + } BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DisabledGestureIcon); BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z"); @@ -122,11 +134,23 @@ namespace Ink_Canvas EnableTwoFingerGestureBtn.Source = new BitmapImage(new Uri("/Resources/new-icons/gesture.png", UriKind.Relative)); - BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); - BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + // 根据主题设置颜色 + if (Settings.Appearance.Theme == 1) // 深色主题 + { + BoardGesture.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)); + BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85)); + } + else // 浅色主题或跟随系统 + { + BoardGesture.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); + BoardGestureGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardGestureGeometry2.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardGestureLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardGesture.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + } BoardGestureGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.DisabledGestureIcon); BoardGestureGeometry2.Geometry = Geometry.Parse("F0 M24,24z M0,0z"); } @@ -404,31 +428,50 @@ namespace Ink_Canvas { if (mode != "clear") { - CursorIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(27, 27, 27)); + CursorIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); CursorIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.LinedCursorIcon); - PenIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(27, 27, 27)); + PenIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); PenIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.LinedPenIcon); - StrokeEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(27, 27, 27)); + StrokeEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); StrokeEraserIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.LinedEraserStrokeIcon); - CircleEraserIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(27, 27, 27)); + CircleEraserIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); CircleEraserIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.LinedEraserCircleIcon); - LassoSelectIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(27, 27, 27)); + LassoSelectIconGeometry.Brush = new SolidColorBrush(FloatBarForegroundColor); LassoSelectIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.LinedLassoSelectIcon); - BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); - BoardSelect.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); - BoardEraser.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); - BoardSelectGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardEraserGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardSelectLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardEraserLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); - BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); - BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + // 根据主题设置颜色 + if (Settings.Appearance.Theme == 1) // 深色主题 + { + BoardPen.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)); + BoardSelect.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)); + BoardEraser.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)); + BoardSelectGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardEraserGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardSelectLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardEraserLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85)); + BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85)); + BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85)); + } + else // 浅色主题或跟随系统 + { + BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); + BoardSelect.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); + BoardEraser.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); + BoardSelectGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardEraserGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardSelectLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardEraserLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardSelect.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + BoardEraser.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + } HideFloatingBarHighlight(); } @@ -492,10 +535,21 @@ namespace Ink_Canvas CursorIconGeometry.Brush = new SolidColorBrush(Color.FromRgb(30, 58, 138)); CursorIconGeometry.Geometry = Geometry.Parse(XamlGraphicsIconGeometries.LinedCursorIcon); - BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); - BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); - BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); - BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + // 根据主题设置颜色 + if (Settings.Appearance.Theme == 1) // 深色主题 + { + BoardPen.Background = new SolidColorBrush(Color.FromRgb(42, 42, 42)); + BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(85, 85, 85)); + BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(255, 255, 255)); + } + else // 浅色主题或跟随系统 + { + BoardPen.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245)); + BoardPen.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170)); + BoardPenGeometry.Brush = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + BoardPenLabel.Foreground = new SolidColorBrush(Color.FromRgb(24, 24, 27)); + } SetFloatingBarHighlightPosition("cursor"); break; diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingWindowInterceptor.cs b/Ink Canvas/MainWindow_cs/MW_FloatingWindowInterceptor.cs index c0e0fd4f..1df2cdf7 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingWindowInterceptor.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingWindowInterceptor.cs @@ -3,7 +3,6 @@ using iNKORE.UI.WPF.Modern.Controls; using System; using System.Linq; using System.Windows; -using System.Windows.Controls; namespace Ink_Canvas { diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 94370fc5..8d66fd6d 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -1121,14 +1121,42 @@ namespace Ink_Canvas { try { + // 检查PPT连接状态 + if (_pptManager?.IsConnected != true || _pptManager?.IsInSlideShow != true) + { + return; + } + // 获取当前页面索引 var currentSlideIndex = _pptManager?.GetCurrentSlideNumber() ?? 0; + + // 验证页面索引的有效性 + if (newSlideIndex <= 0) + { + LogHelper.WriteLogToFile($"无效的新页面索引: {newSlideIndex},跳过页面切换", LogHelper.LogType.Warning); + return; + } + // 如果有当前墨迹且不是第一次切换,先保存到当前页面 if (inkCanvas.Strokes.Count > 0 && currentSlideIndex > 0 && currentSlideIndex != newSlideIndex) { - _multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes); - LogHelper.WriteLogToFile($"切换前保存第{currentSlideIndex}页墨迹,墨迹数量: {inkCanvas.Strokes.Count}", LogHelper.LogType.Trace); + // 检查是否可以写入墨迹 + bool canWrite = _multiPPTInkManager?.CanWriteInk(currentSlideIndex) == true; + + if (canWrite) + { + // 正常保存 + _multiPPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes); + } + else + { + // 墨迹被锁定,跳过保存以避免墨迹错页 + } + } + else if (inkCanvas.Strokes.Count > 0 && currentSlideIndex <= 0) + { + // 无法获取当前页面索引时,不保存墨迹,直接清空 } // 切换到新页面并加载墨迹 @@ -1139,8 +1167,7 @@ namespace Ink_Canvas inkCanvas.Strokes.Add(newStrokes); } - // 设置墨迹锁定 - _multiPPTInkManager?.LockInkForSlide(newSlideIndex); + // 注意:LockInkForSlide已经在SwitchToSlide中调用,这里不需要重复调用 } catch (Exception ex) { diff --git a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs index b2e29494..41b6a0fe 100644 --- a/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs +++ b/Ink Canvas/MainWindow_cs/MW_SettingsToLoad.cs @@ -245,6 +245,9 @@ namespace Ink_Canvas break; } + // 设置主题下拉框 + ComboBoxTheme.SelectedIndex = Settings.Appearance.Theme; + ComboBoxChickenSoupSource.SelectedIndex = Settings.Appearance.ChickenSoupSource; ToggleSwitchEnableQuickPanel.IsOn = Settings.Appearance.IsShowQuickPanel; diff --git a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs index 2d9971c4..117a598a 100644 --- a/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs +++ b/Ink Canvas/MainWindow_cs/MW_TouchEvents.cs @@ -9,7 +9,6 @@ using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; -using System.Windows.Threading; using Point = System.Windows.Point; namespace Ink_Canvas diff --git a/Ink Canvas/Properties/AssemblyInfo.cs b/Ink Canvas/Properties/AssemblyInfo.cs index f9735752..8f8fb36e 100644 --- a/Ink Canvas/Properties/AssemblyInfo.cs +++ b/Ink Canvas/Properties/AssemblyInfo.cs @@ -49,5 +49,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.7.11.1")] -[assembly: AssemblyFileVersion("1.7.11.1")] +[assembly: AssemblyVersion("1.7.11.3")] +[assembly: AssemblyFileVersion("1.7.11.3")] diff --git a/Ink Canvas/Resources/Styles/Dark.xaml b/Ink Canvas/Resources/Styles/Dark.xaml index 2dd756fc..e04f7855 100644 --- a/Ink Canvas/Resources/Styles/Dark.xaml +++ b/Ink Canvas/Resources/Styles/Dark.xaml @@ -1,7 +1,32 @@ - - - - + + + + + + #FFcccccc + + + + + + + + + + + + + Transparent + #2200CDCD + #4400CDCD + + + + + + + + + \ No newline at end of file diff --git a/Ink Canvas/Resources/Styles/Light.xaml b/Ink Canvas/Resources/Styles/Light.xaml index 900ceccf..bcf1db1f 100644 --- a/Ink Canvas/Resources/Styles/Light.xaml +++ b/Ink Canvas/Resources/Styles/Light.xaml @@ -1,7 +1,32 @@ - - - - - #18181b + + + + + + + #FF000000 + + + + + + + + + + + + + Transparent + #66FFFFFF + #99FFFFFF + + + + + + + + + \ No newline at end of file diff --git a/Ink Canvas/Windows/HasNewUpdateWindow.xaml b/Ink Canvas/Windows/HasNewUpdateWindow.xaml index 7aebd58a..793d028c 100644 --- a/Ink Canvas/Windows/HasNewUpdateWindow.xaml +++ b/Ink Canvas/Windows/HasNewUpdateWindow.xaml @@ -11,13 +11,13 @@ ui:WindowHelper.SystemBackdropType="Mica" Title="InkCanvasForClass CE有新版本可用" Height="650" Width="900" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" WindowStyle="None" AllowsTransparency="True" - Background="#f8fafc"> + Background="Transparent"> - + BorderBrush="Transparent" + BorderThickness="0"> @@ -140,7 +140,7 @@ - + - - - - - - + ui:WindowHelper.UseModernWindowStyle="False" + ui:WindowHelper.SystemBackdropType="Mica" + Title="历史版本回滚" Height="650" Width="900" ResizeMode="CanResize" + WindowStartupLocation="CenterScreen" WindowStyle="None" AllowsTransparency="True" + Background="Transparent" MinHeight="550" MinWidth="800"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +