From 483e0757b70bafba1b31b22b36d9ba20cc560823 Mon Sep 17 00:00:00 2001
From: CJKmkp <2564608840@qq.com>
Date: Sat, 10 Jan 2026 17:31:10 +0800
Subject: [PATCH] =?UTF-8?q?=E6=92=A4=E9=94=80commit3cd2632?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
Ink Canvas/MainWindow_cs/MW_PPT.cs | 344 +++++++++--------------------
1 file changed, 104 insertions(+), 240 deletions(-)
diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs
index a4cf2105..6b8786a7 100644
--- a/Ink Canvas/MainWindow_cs/MW_PPT.cs
+++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs
@@ -77,7 +77,7 @@ namespace Ink_Canvas
#endregion
#region PPT State Management
- private bool isEnteredSlideShowEndEvent;
+ private bool isEnteredSlideShowEndEvent;
private bool isPresentationHaveBlackSpace;
// 长按翻页相关字段
@@ -93,14 +93,15 @@ namespace Ink_Canvas
// 上次播放位置相关字段
private int _lastPlaybackPage = 0;
private bool _shouldNavigateToLastPage = false;
-
+
// 当前播放页码跟踪
private int _currentSlideShowPosition = 0;
// 页面切换防抖机制
private DateTime _lastSlideSwitchTime = DateTime.MinValue;
- private const int SlideSwitchDebounceMs = 150;
- private bool _isInkClearedByButton = false;
+ private int _pendingSlideIndex = -1;
+ private System.Timers.Timer _slideSwitchDebounceTimer;
+ private const int SlideSwitchDebounceMs = 150; // 防抖延迟150毫秒
#endregion
#region PPT Managers
@@ -151,10 +152,6 @@ namespace Ink_Canvas
_pptUIManager.PPTRBButtonPosition = Settings.PowerPointSettings.PPTRBButtonPosition;
_pptUIManager.EnablePPTButtonPageClickable = Settings.PowerPointSettings.EnablePPTButtonPageClickable;
_pptUIManager.EnablePPTButtonLongPressPageTurn = Settings.PowerPointSettings.EnablePPTButtonLongPressPageTurn;
- _pptUIManager.PPTLSButtonOpacity = Settings.PowerPointSettings.PPTLSButtonOpacity;
- _pptUIManager.PPTRSButtonOpacity = Settings.PowerPointSettings.PPTRSButtonOpacity;
- _pptUIManager.PPTLBButtonOpacity = Settings.PowerPointSettings.PPTLBButtonOpacity;
- _pptUIManager.PPTRBButtonOpacity = Settings.PowerPointSettings.PPTRBButtonOpacity;
LogHelper.WriteLogToFile("PPT管理器初始化完成", LogHelper.LogType.Event);
}
@@ -527,8 +524,6 @@ namespace Ink_Canvas
{
try
{
- bool isInSlideShowWhenOpened = _pptManager?.IsInSlideShow == true;
-
Application.Current.Dispatcher.InvokeAsync(() =>
{
// 在初始化墨迹管理器之前,先清理画布上的所有墨迹
@@ -551,7 +546,8 @@ namespace Ink_Canvas
CheckAndNotifyHiddenSlides(pres);
}
- if (Settings.PowerPointSettings.IsNotifyAutoPlayPresentation && !isInSlideShowWhenOpened)
+ // 检查自动播放设置
+ if (Settings.PowerPointSettings.IsNotifyAutoPlayPresentation)
{
CheckAndNotifyAutoPlaySettings(pres);
}
@@ -729,7 +725,7 @@ namespace Ink_Canvas
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow &&
!Settings.Automation.IsAutoFoldInPPTSlideShow)
{
- await Task.Delay(600);
+ await Task.Delay(300);
// 先进入批注模式,这会显示调色盘
PenIcon_Click(null, null);
// 然后设置颜色
@@ -770,7 +766,6 @@ namespace Ink_Canvas
LoadCurrentSlideInk(currentSlide);
});
-
if (!isFloatingBarFolded)
{
new Thread(() =>
@@ -783,8 +778,9 @@ namespace Ink_Canvas
}).Start();
}
}
- catch (Exception)
+ catch (Exception ex)
{
+ LogHelper.WriteLogToFile($"处理幻灯片放映开始事件失败: {ex}", LogHelper.LogType.Error);
}
}
@@ -792,7 +788,7 @@ namespace Ink_Canvas
{
try
{
- Application.Current.Dispatcher.Invoke(() =>
+ Application.Current.Dispatcher.InvokeAsync(() =>
{
if (wn?.View == null || wn.Presentation == null)
{
@@ -803,54 +799,11 @@ namespace Ink_Canvas
var activePresentation = wn.Presentation;
var totalSlides = activePresentation.Slides.Count;
- // 获取之前的页码(用于保存墨迹)
- var previousSlide = _currentSlideShowPosition > 0 ? _currentSlideShowPosition :
- (_pptManager?.GetCurrentSlideNumber() ?? 0);
-
- // 先保存当前页墨迹的副本
- StrokeCollection strokesToSave = null;
- if (previousSlide > 0 && previousSlide != currentSlide && inkCanvas.Strokes.Count > 0)
- {
- strokesToSave = inkCanvas.Strokes.Clone();
- }
-
- if (_isInkClearedByButton)
- {
- _isInkClearedByButton = false;
- }
- else if (inkCanvas.Strokes.Count > 0)
- {
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
- }
-
// 更新当前播放页码
_currentSlideShowPosition = currentSlide;
- // 异步保存之前页面的墨迹(不阻塞翻页操作)
- if (strokesToSave != null && previousSlide > 0 && previousSlide != currentSlide)
- {
- Task.Run(() =>
- {
- try
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- bool canWrite = _singlePPTInkManager?.CanWriteInk(previousSlide) == true;
- if (canWrite)
- {
- _singlePPTInkManager?.SaveCurrentSlideStrokes(previousSlide, strokesToSave);
- }
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"异步保存PPT页面墨迹失败: {ex}", LogHelper.LogType.Error);
- }
- });
- }
- LoadCurrentSlideInk(currentSlide, skipClear: true); // 跳过清除,因为已在上面清除
- _pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides);
+ // 使用防抖机制处理页面切换
+ HandleSlideSwitchWithDebounce(currentSlide, totalSlides);
});
}
@@ -864,7 +817,6 @@ namespace Ink_Canvas
{
try
{
- // PPT退出时自动收纳浮动栏
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow && !isFloatingBarFolded)
{
FoldFloatingBar_MouseUp(new object(), null);
@@ -956,7 +908,7 @@ namespace Ink_Canvas
if (GridTransparencyFakeBackground.Background != Brushes.Transparent)
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
SetCurrentToolMode(InkCanvasEditingMode.None);
-
+
UpdateCurrentToolMode("cursor");
SetFloatingBarHighlightPosition("cursor");
}
@@ -969,15 +921,8 @@ namespace Ink_Canvas
await Task.Delay(100);
await Application.Current.Dispatcher.InvokeAsync(() =>
{
- if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
- {
- PureViewboxFloatingBarMarginAnimationInDesktopMode();
- ViewboxFloatingBarMarginAnimation(-60);
- }
- else
- {
- PureViewboxFloatingBarMarginAnimationInDesktopMode();
- }
+ PureViewboxFloatingBarMarginAnimationInDesktopMode();
+ ViewboxFloatingBarMarginAnimation(-60);
});
}
catch (Exception ex)
@@ -998,10 +943,7 @@ namespace Ink_Canvas
}
else if (Settings.PowerPointSettings.IsNotifyPreviousPage)
{
- if (_pptManager?.IsInSlideShow != true)
- {
- ShowPreviousPageNotification(pres);
- }
+ ShowPreviousPageNotification(pres);
}
}
catch (Exception ex)
@@ -1113,7 +1055,7 @@ namespace Ink_Canvas
{
try
{
- if (_pptManager?.IsInSlideShow == true) return;
+ if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) return;
bool hasSlideTimings = false;
if (pres?.Slides != null)
@@ -1161,16 +1103,13 @@ namespace Ink_Canvas
}
}
- private void LoadCurrentSlideInk(int slideIndex, bool skipClear = false)
+ private void LoadCurrentSlideInk(int slideIndex)
{
try
{
- // 如果未跳过清除,则清除当前墨迹
- if (!skipClear)
- {
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
- }
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
+
StrokeCollection strokes = _singlePPTInkManager?.LoadSlideStrokes(slideIndex);
if (strokes != null && strokes.Count > 0)
@@ -1215,12 +1154,13 @@ namespace Ink_Canvas
// 重置上次播放位置相关字段
_lastPlaybackPage = 0;
_shouldNavigateToLastPage = false;
-
+
// 重置当前播放页码跟踪
_currentSlideShowPosition = 0;
// 重置页面切换防抖机制
_lastSlideSwitchTime = DateTime.MinValue;
+ _pendingSlideIndex = -1;
LogHelper.WriteLogToFile("PPT状态变量已重置", LogHelper.LogType.Trace);
}
@@ -1235,14 +1175,51 @@ namespace Ink_Canvas
///
private void HandleSlideSwitchWithDebounce(int currentSlide, int totalSlides)
{
+ try
+ {
+ var now = DateTime.Now;
+
+ // 如果距离上次切换时间太短,使用防抖机制
+ if (now - _lastSlideSwitchTime < TimeSpan.FromMilliseconds(SlideSwitchDebounceMs))
+ {
+ _pendingSlideIndex = currentSlide;
+
+ // 停止之前的定时器
+ _slideSwitchDebounceTimer?.Stop();
+
+ // 创建新的定时器
+ _slideSwitchDebounceTimer = new System.Timers.Timer(SlideSwitchDebounceMs);
+ _slideSwitchDebounceTimer.Elapsed += (sender, e) =>
+ {
+ Application.Current.Dispatcher.Invoke(() =>
+ {
+ if (_pendingSlideIndex > 0)
+ {
+ SwitchSlideInk(_pendingSlideIndex);
+ _pptUIManager?.UpdateCurrentSlideNumber(_pendingSlideIndex, totalSlides);
+ _pendingSlideIndex = -1;
+ }
+ });
+ _slideSwitchDebounceTimer?.Stop();
+ };
+ _slideSwitchDebounceTimer.Start();
+ }
+ else
+ {
+ // 直接处理页面切换
+ SwitchSlideInk(currentSlide);
+ _pptUIManager?.UpdateCurrentSlideNumber(currentSlide, totalSlides);
+ }
+
+ _lastSlideSwitchTime = now;
+ }
+ catch (Exception ex)
+ {
+ LogHelper.WriteLogToFile($"处理页面切换防抖失败: {ex}", LogHelper.LogType.Error);
+ }
}
- ///
- /// 切换页面墨迹
- ///
- /// 新页面索引
- /// 是否跳过清除操作(如果已在翻页时立即清除,则设为true)
- private void SwitchSlideInk(int newSlideIndex, bool skipClear = false)
+ private void SwitchSlideInk(int newSlideIndex)
{
try
{
@@ -1263,25 +1240,20 @@ namespace Ink_Canvas
}
// 如果有当前墨迹且不是第一次切换,先保存到当前页面
- if (currentSlideIndex > 0 && currentSlideIndex != newSlideIndex)
+ if (inkCanvas.Strokes.Count > 0 && currentSlideIndex > 0 && currentSlideIndex != newSlideIndex)
{
bool canWrite = _singlePPTInkManager?.CanWriteInk(currentSlideIndex) == true;
- if (canWrite && inkCanvas.Strokes.Count > 0)
+ if (canWrite)
{
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes);
}
}
- if (!skipClear)
- {
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
- }
-
- // 加载新页面的墨迹
+ ClearStrokes(true);
+ timeMachine.ClearStrokeHistory();
StrokeCollection newStrokes = _singlePPTInkManager?.SwitchToSlide(newSlideIndex, null);
-
+
if (newStrokes != null && newStrokes.Count > 0)
{
inkCanvas.Strokes.Add(newStrokes);
@@ -1416,72 +1388,25 @@ namespace Ink_Canvas
{
try
{
- var previousSlideBeforeNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
-
- StrokeCollection strokesToSave = null;
- if (previousSlideBeforeNavigate > 0 && inkCanvas.Strokes.Count > 0)
+ // 保存当前页墨迹
+ var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
+ if (currentSlide > 0)
{
- strokesToSave = inkCanvas.Strokes.Clone();
+ _singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
}
+ // 保存截图(如果启用)
+ if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
+ Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
+ {
+ var presentationName = _pptManager?.GetPresentationName() ?? "";
+ SaveScreenShot(true, $"{presentationName}/{currentSlide}");
+ }
+
+ // 执行翻页
if (_pptManager?.TryNavigatePrevious() == true)
{
- var currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
-
- if (previousSlideBeforeNavigate == currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
- {
- Thread.Sleep(50);
- currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
- }
-
- if (previousSlideBeforeNavigate != currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
- {
- if (inkCanvas.Strokes.Count > 0)
- {
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
- _isInkClearedByButton = true;
- }
-
- if (strokesToSave != null && previousSlideBeforeNavigate > 0)
- {
- Task.Run(() =>
- {
- try
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- _singlePPTInkManager?.SaveCurrentSlideStrokes(previousSlideBeforeNavigate, strokesToSave);
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"异步保存PPT上一页墨迹失败: {ex}", LogHelper.LogType.Error);
- }
- });
-
- // 异步保存截图(如果启用)
- if (strokesToSave.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
- Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
- {
- Task.Run(() =>
- {
- try
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- var presentationName = _pptManager?.GetPresentationName() ?? "";
- SaveScreenShot(true, $"{presentationName}/{previousSlideBeforeNavigate}");
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"异步保存PPT上一页截图失败: {ex}", LogHelper.LogType.Error);
- }
- });
- }
- }
- }
+ // 翻页成功,等待事件处理墨迹切换
}
else
{
@@ -1503,72 +1428,25 @@ namespace Ink_Canvas
{
try
{
- var previousSlideBeforeNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
-
- StrokeCollection strokesToSave = null;
- if (previousSlideBeforeNavigate > 0 && inkCanvas.Strokes.Count > 0)
+ // 保存当前页墨迹
+ var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
+ if (currentSlide > 0)
{
- strokesToSave = inkCanvas.Strokes.Clone();
+ _singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
}
+ // 保存截图(如果启用)
+ if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
+ Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
+ {
+ var presentationName = _pptManager?.GetPresentationName() ?? "";
+ SaveScreenShot(true, $"{presentationName}/{currentSlide}");
+ }
+
+ // 执行翻页
if (_pptManager?.TryNavigateNext() == true)
{
- var currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
-
- if (previousSlideBeforeNavigate == currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
- {
- Thread.Sleep(50);
- currentSlideAfterNavigate = _pptManager?.GetCurrentSlideNumber() ?? 0;
- }
-
- if (previousSlideBeforeNavigate != currentSlideAfterNavigate && previousSlideBeforeNavigate > 0)
- {
- if (inkCanvas.Strokes.Count > 0)
- {
- ClearStrokes(true);
- timeMachine.ClearStrokeHistory();
- _isInkClearedByButton = true;
- }
-
- if (strokesToSave != null && previousSlideBeforeNavigate > 0)
- {
- Task.Run(() =>
- {
- try
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- _singlePPTInkManager?.SaveCurrentSlideStrokes(previousSlideBeforeNavigate, strokesToSave);
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"异步保存PPT下一页墨迹失败: {ex}", LogHelper.LogType.Error);
- }
- });
-
- // 异步保存截图(如果启用)
- if (strokesToSave.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
- Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
- {
- Task.Run(() =>
- {
- try
- {
- Application.Current.Dispatcher.Invoke(() =>
- {
- var presentationName = _pptManager?.GetPresentationName() ?? "";
- SaveScreenShot(true, $"{presentationName}/{previousSlideBeforeNavigate}");
- });
- }
- catch (Exception ex)
- {
- LogHelper.WriteLogToFile($"异步保存PPT下一页截图失败: {ex}", LogHelper.LogType.Error);
- }
- });
- }
- }
- }
+ // 翻页成功,等待事件处理墨迹切换
}
else
{
@@ -1744,15 +1622,8 @@ namespace Ink_Canvas
SetCurrentToolMode(InkCanvasEditingMode.None);
await Task.Delay(150);
-
- if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
- {
- ViewboxFloatingBarMarginAnimation(-60);
- }
- else
- {
- ViewboxFloatingBarMarginAnimation(100, true);
- }
+ // PPT退出时自动收纳,使用收纳状态的边距动画
+ ViewboxFloatingBarMarginAnimation(-60);
}
catch (Exception ex)
{
@@ -1768,15 +1639,9 @@ namespace Ink_Canvas
// 异常情况下也手动处理自动收纳
await HandleManualSlideShowEnd();
+ // 异常情况下也要自动收纳,使用收纳状态的边距动画
await Task.Delay(150);
- if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
- {
- ViewboxFloatingBarMarginAnimation(-60);
- }
- else
- {
- ViewboxFloatingBarMarginAnimation(100, true);
- }
+ ViewboxFloatingBarMarginAnimation(-60);
}
}
@@ -1787,7 +1652,6 @@ namespace Ink_Canvas
{
try
{
- // PPT退出时自动收纳浮动栏
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow && !isFloatingBarFolded)
{
FoldFloatingBar_MouseUp(new object(), null);