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 @@
-
+
-
+
@@ -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 @@
@@ -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">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs b/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs
index 1fb83a07..cd1668ac 100644
--- a/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs
+++ b/Ink Canvas/Windows/HistoryRollbackWindow.xaml.cs
@@ -32,6 +32,15 @@ namespace Ink_Canvas
InitializeComponent();
this.channel = channel;
LoadVersions();
+
+ // 添加窗口拖动功能
+ this.MouseDown += (sender, e) =>
+ {
+ if (e.ChangedButton == MouseButton.Left)
+ {
+ this.DragMove();
+ }
+ };
}
private async void LoadVersions()
@@ -135,6 +144,16 @@ namespace Ink_Canvas
}
}
+ private void MinimizeButton_Click(object sender, RoutedEventArgs e)
+ {
+ this.WindowState = WindowState.Minimized;
+ }
+
+ private void CloseButton_Click(object sender, RoutedEventArgs e)
+ {
+ this.Close();
+ }
+
protected override void OnClosing(CancelEventArgs e)
{
downloadCts?.Cancel();