Files
community/Ink Canvas/MainWindow_cs/MW_PPT.cs
T

1885 lines
72 KiB
C#
Raw Normal View History

2025-09-18 17:58:51 +08:00
using Ink_Canvas.Helpers;
2025-08-31 11:43:52 +08:00
using iNKORE.UI.WPF.Modern;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.PowerPoint;
using System;
2025-05-25 09:29:48 +08:00
using System.IO;
using System.Runtime.InteropServices;
2025-07-28 14:40:44 +08:00
using System.Security.Cryptography;
using System.Text;
2025-05-25 09:29:48 +08:00
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
2025-09-13 22:44:29 +08:00
using System.Windows.Controls;
2025-10-18 21:20:54 +08:00
using System.Windows.Ink;
2025-05-25 09:29:48 +08:00
using System.Windows.Media;
2025-08-23 19:43:09 +08:00
using System.Windows.Threading;
2025-05-25 09:29:48 +08:00
using Application = System.Windows.Application;
using File = System.IO.File;
2025-09-13 12:22:08 +08:00
using MessageBox = iNKORE.UI.WPF.Modern.Controls.MessageBox;
2025-07-29 01:15:32 +08:00
using MouseButtonEventArgs = System.Windows.Input.MouseButtonEventArgs;
2025-07-28 14:40:44 +08:00
using MouseEventArgs = System.Windows.Input.MouseEventArgs;
2025-05-25 09:29:48 +08:00
2025-08-03 16:46:33 +08:00
namespace Ink_Canvas
{
public partial class MainWindow : Window
{
2025-07-29 01:15:32 +08:00
#region Win32 API Declarations
2025-07-20 12:01:30 +08:00
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
2025-07-20 15:00:11 +08:00
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32.dll")]
2025-07-28 14:40:44 +08:00
private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);
2025-07-20 15:00:11 +08:00
2025-07-20 19:36:58 +08:00
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool IsWindowVisible(IntPtr hWnd);
2025-07-21 08:37:37 +08:00
[DllImport("user32.dll")]
private static extern bool IsIconic(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool IsZoomed(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
private static extern IntPtr GetWindow(IntPtr hWnd, uint uCmd);
[DllImport("user32.dll")]
private static extern bool IsWindow(IntPtr hWnd);
[DllImport("user32.dll")]
private static extern bool GetWindowRect(IntPtr hWnd, out ForegroundWindowInfo.RECT lpRect);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
2025-07-28 14:40:44 +08:00
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
2025-07-21 08:37:37 +08:00
private const int GWL_STYLE = -16;
private const int WS_VISIBLE = 0x10000000;
private const int WS_MINIMIZE = 0x20000000;
private const uint GW_HWNDNEXT = 2;
private const uint GW_HWNDPREV = 3;
2025-07-20 15:00:11 +08:00
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
2025-07-29 01:15:32 +08:00
#endregion
2025-07-20 15:00:11 +08:00
2025-07-29 01:15:32 +08:00
#region PPT Application Variables
2025-07-28 14:40:44 +08:00
public static Microsoft.Office.Interop.PowerPoint.Application pptApplication;
public static Presentation presentation;
public static Slides slides;
public static Slide slide;
public static int slidescount;
2025-07-29 01:15:32 +08:00
#endregion
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
#region PPT State Management
2025-07-28 14:40:44 +08:00
private bool wasFloatingBarFoldedWhenEnterSlideShow;
2025-10-18 17:24:47 +08:00
private bool isEnteredSlideShowEndEvent;
2025-07-29 01:15:32 +08:00
private bool isPresentationHaveBlackSpace;
2025-08-23 19:43:09 +08:00
// 长按翻页相关字段
private DispatcherTimer _longPressTimer;
private bool _isLongPressNext = true; // true为下一页,false为上一页
2025-09-06 10:20:28 +08:00
private const int LongPressDelay = 500; // 长按延迟时间(毫秒)
2025-09-06 14:36:07 +08:00
private const int LongPressInterval = 50; // 长按翻页间隔(毫秒)
2025-09-06 12:09:06 +08:00
// PowerPoint应用程序守护相关字段
private DispatcherTimer _powerPointProcessMonitorTimer;
2025-09-13 18:07:42 +08:00
private const int ProcessMonitorInterval = 1000; // 应用程序监控间隔(毫秒)
2025-10-03 17:08:46 +08:00
2025-09-13 11:29:48 +08:00
// 上次播放位置相关字段
2025-10-01 00:53:22 +08:00
private int _lastPlaybackPage = 0;
private bool _shouldNavigateToLastPage = false;
2025-10-03 17:08:46 +08:00
2025-09-13 18:20:56 +08:00
// 页面切换防抖机制
private DateTime _lastSlideSwitchTime = DateTime.MinValue;
private int _pendingSlideIndex = -1;
private System.Timers.Timer _slideSwitchDebounceTimer;
private const int SlideSwitchDebounceMs = 150; // 防抖延迟150毫秒
2025-07-29 01:15:32 +08:00
#endregion
2025-07-25 10:21:55 +08:00
2025-07-29 01:15:32 +08:00
#region PPT Managers
private PPTManager _pptManager;
2025-10-18 21:20:54 +08:00
private PPTInkManager _singlePPTInkManager;
2025-07-29 01:15:32 +08:00
private PPTUIManager _pptUIManager;
2025-08-23 19:10:53 +08:00
/// <summary>
2025-10-18 17:24:47 +08:00
/// 获取PPT管理器实例
2025-08-23 19:10:53 +08:00
/// </summary>
public PPTManager PPTManager => _pptManager;
2025-07-29 01:15:32 +08:00
#endregion
2025-07-19 23:42:43 +08:00
2025-07-29 01:15:32 +08:00
#region PPT Manager Initialization
private void InitializePPTManagers()
{
try
{
2025-08-23 19:43:09 +08:00
// 初始化长按定时器
InitializeLongPressTimer();
2025-07-29 01:15:32 +08:00
// 初始化PPT管理器
_pptManager = new PPTManager();
_pptManager.IsSupportWPS = Settings.PowerPointSettings.IsSupportWPS;
// 注册事件
_pptManager.PPTConnectionChanged += OnPPTConnectionChanged;
_pptManager.SlideShowBegin += OnPPTSlideShowBegin;
_pptManager.SlideShowNextSlide += OnPPTSlideShowNextSlide;
_pptManager.SlideShowEnd += OnPPTSlideShowEnd;
_pptManager.PresentationOpen += OnPPTPresentationOpen;
_pptManager.PresentationClose += OnPPTPresentationClose;
2025-08-23 19:10:53 +08:00
_pptManager.SlideShowStateChanged += OnPPTSlideShowStateChanged;
2025-07-29 01:15:32 +08:00
2025-11-15 18:04:22 +08:00
_singlePPTInkManager = new PPTInkManager();
_singlePPTInkManager.IsAutoSaveEnabled = Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint;
_singlePPTInkManager.AutoSaveLocation = Settings.Automation.AutoSavedStrokesLocation;
2025-07-29 01:15:32 +08:00
// 初始化UI管理器
_pptUIManager = new PPTUIManager(this);
_pptUIManager.ShowPPTButton = Settings.PowerPointSettings.ShowPPTButton;
_pptUIManager.PPTButtonsDisplayOption = Settings.PowerPointSettings.PPTButtonsDisplayOption;
_pptUIManager.PPTSButtonsOption = Settings.PowerPointSettings.PPTSButtonsOption;
_pptUIManager.PPTBButtonsOption = Settings.PowerPointSettings.PPTBButtonsOption;
_pptUIManager.PPTLSButtonPosition = Settings.PowerPointSettings.PPTLSButtonPosition;
_pptUIManager.PPTRSButtonPosition = Settings.PowerPointSettings.PPTRSButtonPosition;
2025-08-23 19:27:30 +08:00
_pptUIManager.PPTLBButtonPosition = Settings.PowerPointSettings.PPTLBButtonPosition;
_pptUIManager.PPTRBButtonPosition = Settings.PowerPointSettings.PPTRBButtonPosition;
2025-07-29 01:15:32 +08:00
_pptUIManager.EnablePPTButtonPageClickable = Settings.PowerPointSettings.EnablePPTButtonPageClickable;
2025-08-23 19:43:09 +08:00
_pptUIManager.EnablePPTButtonLongPressPageTurn = Settings.PowerPointSettings.EnablePPTButtonLongPressPageTurn;
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile("PPT管理器初始化完成", LogHelper.LogType.Event);
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
catch (Exception ex)
{
LogHelper.WriteLogToFile($"PPT管理器初始化失败: {ex}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
2025-07-29 01:15:32 +08:00
private void StartPPTMonitoring()
{
if (Settings.PowerPointSettings.PowerPointSupport)
{
_pptManager?.StartMonitoring();
LogHelper.WriteLogToFile("PPT监控已启动", LogHelper.LogType.Event);
}
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
private void StopPPTMonitoring()
{
_pptManager?.StopMonitoring();
LogHelper.WriteLogToFile("PPT监控已停止", LogHelper.LogType.Event);
}
2025-05-25 09:29:48 +08:00
2025-09-06 12:09:06 +08:00
#region PowerPoint Application Management
/// <summary>
/// 启动PowerPoint应用程序守护
/// </summary>
private void StartPowerPointProcessMonitoring()
{
try
{
if (!Settings.PowerPointSettings.EnablePowerPointEnhancement) return;
// 创建PowerPoint应用程序实例
CreatePowerPointApplication();
// 启动应用程序监控定时器
if (_powerPointProcessMonitorTimer == null)
{
_powerPointProcessMonitorTimer = new DispatcherTimer();
_powerPointProcessMonitorTimer.Interval = TimeSpan.FromMilliseconds(ProcessMonitorInterval);
_powerPointProcessMonitorTimer.Tick += OnPowerPointApplicationMonitorTick;
}
_powerPointProcessMonitorTimer.Start();
LogHelper.WriteLogToFile("PowerPoint应用程序守护已启动", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"启动PowerPoint应用程序守护失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 停止PowerPoint应用程序守护
/// </summary>
private void StopPowerPointProcessMonitoring()
{
try
{
// 停止应用程序监控定时器
_powerPointProcessMonitorTimer?.Stop();
// 关闭PowerPoint应用程序
ClosePowerPointApplication();
LogHelper.WriteLogToFile("PowerPoint应用程序守护已停止", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"停止PowerPoint应用程序守护失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 创建PowerPoint应用程序实例
/// </summary>
private void CreatePowerPointApplication()
{
try
{
// 如果应用程序已存在且有效,则不重复创建
if (pptApplication != null && IsPowerPointApplicationValid())
{
return;
}
// 创建新的PowerPoint应用程序实例
pptApplication = new Microsoft.Office.Interop.PowerPoint.Application();
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
// 设置为不可见,作为后台进程
2025-09-07 00:11:22 +08:00
pptApplication.Visible = MsoTriState.msoFalse;
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
// 设置应用程序属性
2025-09-07 00:11:22 +08:00
pptApplication.WindowState = PpWindowState.ppWindowMinimized;
2025-09-06 12:09:06 +08:00
// 直接设置PPTManager的PPTApplication属性,绕过COM注册问题
Task.Delay(1000).ContinueWith(_ =>
{
Dispatcher.Invoke(() =>
{
try
{
// 直接设置PPTManager的PowerPoint应用程序实例
if (_pptManager != null)
{
// 使用反射或直接访问来设置PPTManager的PPTApplication
SetPPTManagerApplication(pptApplication);
LogHelper.WriteLogToFile("已直接设置PPTManager的PowerPoint应用程序实例", LogHelper.LogType.Event);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"设置PPTManager的PowerPoint应用程序实例失败: {ex}", LogHelper.LogType.Error);
}
});
});
LogHelper.WriteLogToFile("PowerPoint应用程序实例已创建", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"创建PowerPoint应用程序实例失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 设置PPTManager的PowerPoint应用程序实例
/// </summary>
private void SetPPTManagerApplication(Microsoft.Office.Interop.PowerPoint.Application app)
{
try
{
if (_pptManager == null) return;
// 使用反射调用PPTManager的ConnectToPPT方法
var pptManagerType = _pptManager.GetType();
2025-09-07 13:30:46 +08:00
var connectMethod = pptManagerType.GetMethod("ConnectToPPT",
2025-09-06 12:09:06 +08:00
System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
if (connectMethod != null)
{
connectMethod.Invoke(_pptManager, new object[] { app });
LogHelper.WriteLogToFile("通过ConnectToPPT方法设置PowerPoint应用程序实例", LogHelper.LogType.Event);
}
else
{
// 如果无法通过反射调用,尝试直接设置属性
2025-09-07 13:30:46 +08:00
var pptApplicationProperty = pptManagerType.GetProperty("PPTApplication",
2025-09-06 12:09:06 +08:00
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
if (pptApplicationProperty != null && pptApplicationProperty.CanWrite)
{
pptApplicationProperty.SetValue(_pptManager, app);
LogHelper.WriteLogToFile("通过属性设置PPTManager的PowerPoint应用程序实例", LogHelper.LogType.Event);
}
else
{
LogHelper.WriteLogToFile("无法设置PPTManager的PowerPoint应用程序实例", LogHelper.LogType.Warning);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"设置PPTManager的PowerPoint应用程序实例失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// 检查PowerPoint应用程序是否有效
/// </summary>
private bool IsPowerPointApplicationValid()
{
try
{
if (pptApplication == null) return false;
if (!Marshal.IsComObject(pptApplication)) return false;
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
// 尝试访问一个简单的属性来验证连接是否有效
var _ = pptApplication.Name;
return true;
}
catch (COMException comEx)
{
var hr = (uint)comEx.HResult;
// 如果COM对象已失效,返回false
if (hr == 0x8001010E || hr == 0x80004005 || hr == 0x800706B5)
{
return false;
}
return false;
}
catch
{
return false;
}
}
/// <summary>
/// 关闭PowerPoint应用程序
/// </summary>
private void ClosePowerPointApplication()
{
try
{
if (pptApplication != null)
{
// 关闭所有打开的演示文稿
if (pptApplication.Presentations.Count > 0)
{
for (int i = pptApplication.Presentations.Count; i >= 1; i--)
{
try
{
pptApplication.Presentations[i].Close();
}
catch { }
}
}
// 退出PowerPoint应用程序
pptApplication.Quit();
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
// 释放COM对象
Marshal.ReleaseComObject(pptApplication);
pptApplication = null;
}
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
LogHelper.WriteLogToFile("PowerPoint应用程序已关闭", LogHelper.LogType.Event);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"关闭PowerPoint应用程序失败: {ex}", LogHelper.LogType.Error);
}
}
/// <summary>
/// PowerPoint应用程序监控定时器事件
/// </summary>
private void OnPowerPointApplicationMonitorTick(object sender, EventArgs e)
{
try
{
if (!Settings.PowerPointSettings.EnablePowerPointEnhancement)
{
StopPowerPointProcessMonitoring();
return;
}
// 检查应用程序是否还在运行
if (!IsPowerPointApplicationValid())
{
LogHelper.WriteLogToFile("检测到PowerPoint应用程序已失效,重新创建", LogHelper.LogType.Event);
CreatePowerPointApplication();
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"PowerPoint应用程序监控异常: {ex}", LogHelper.LogType.Error);
}
}
#endregion
2025-07-29 01:15:32 +08:00
private void DisposePPTManagers()
{
try
{
_pptManager?.Dispose();
2025-10-18 21:20:54 +08:00
_singlePPTInkManager?.Dispose();
2025-08-23 19:43:09 +08:00
_longPressTimer?.Stop();
_longPressTimer = null;
2025-07-29 01:15:32 +08:00
_pptManager = null;
2025-10-18 21:20:54 +08:00
_singlePPTInkManager = null;
2025-07-29 01:15:32 +08:00
_pptUIManager = null;
2025-09-06 12:09:06 +08:00
// 清理PowerPoint进程守护
StopPowerPointProcessMonitoring();
_powerPointProcessMonitorTimer = null;
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile("PPT管理器已释放", LogHelper.LogType.Event);
2025-05-25 09:29:48 +08:00
}
2025-07-20 19:36:58 +08:00
catch (Exception ex)
{
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile($"释放PPT管理器失败: {ex}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
2025-08-23 19:43:09 +08:00
/// <summary>
/// 初始化长按定时器
/// </summary>
private void InitializeLongPressTimer()
{
_longPressTimer = new DispatcherTimer();
_longPressTimer.Interval = TimeSpan.FromMilliseconds(LongPressDelay);
_longPressTimer.Tick += OnLongPressTimerTick;
}
/// <summary>
/// 启动长按检测
/// </summary>
/// <param name="sender">触发事件的控件</param>
/// <param name="isNext">是否为下一页按钮</param>
private void StartLongPressDetection(object sender, bool isNext)
{
if (!Settings.PowerPointSettings.EnablePPTButtonLongPressPageTurn) return;
_isLongPressNext = isNext;
2025-09-07 00:14:59 +08:00
// 重置定时器间隔为初始延迟时间,确保每次长按检测都从正确的延迟开始
_longPressTimer.Interval = TimeSpan.FromMilliseconds(LongPressDelay);
2025-08-23 19:43:09 +08:00
_longPressTimer?.Start();
}
/// <summary>
/// 停止长按检测
/// </summary>
private void StopLongPressDetection()
{
_longPressTimer?.Stop();
}
/// <summary>
/// 长按定时器事件处理
/// </summary>
private void OnLongPressTimerTick(object sender, EventArgs e)
{
if (!Settings.PowerPointSettings.EnablePPTButtonLongPressPageTurn) return;
_longPressTimer.Interval = TimeSpan.FromMilliseconds(LongPressInterval);
// 执行翻页
if (_isLongPressNext)
{
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
}
else
{
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
}
}
2025-07-29 01:15:32 +08:00
#endregion
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
#region New PPT Event Handlers
private void OnPPTConnectionChanged(bool isConnected)
{
try
2025-07-21 17:19:27 +08:00
{
2025-07-29 01:15:32 +08:00
Application.Current.Dispatcher.InvokeAsync(() =>
{
_pptUIManager?.UpdateConnectionStatus(isConnected);
if (isConnected)
2025-07-21 17:19:27 +08:00
{
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile("PPT连接已建立", LogHelper.LogType.Event);
2025-07-21 17:19:27 +08:00
}
2025-07-29 01:15:32 +08:00
else
2025-07-21 17:19:27 +08:00
{
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile("PPT连接已断开", LogHelper.LogType.Event);
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.ClearAllStrokes();
2025-07-21 17:19:27 +08:00
}
2025-07-29 01:15:32 +08:00
});
2025-07-21 17:19:27 +08:00
}
2025-07-29 01:15:32 +08:00
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理PPT连接状态变化失败: {ex}", LogHelper.LogType.Error);
}
}
2025-07-20 16:14:26 +08:00
2025-07-29 01:15:32 +08:00
private void OnPPTPresentationOpen(Presentation pres)
{
try
{
Application.Current.Dispatcher.InvokeAsync(() =>
{
2025-08-23 19:16:19 +08:00
// 在初始化墨迹管理器之前,先清理画布上的所有墨迹
ClearStrokes(true);
2025-08-31 11:43:52 +08:00
2025-08-23 19:16:19 +08:00
// 清理备份历史记录,防止旧演示文稿的墨迹影响新演示文稿
if (TimeMachineHistories != null && TimeMachineHistories.Length > 0)
{
TimeMachineHistories[0] = null;
}
2025-08-31 11:43:52 +08:00
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.InitializePresentation(pres);
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
// 处理跳转到首页或上次播放页的逻辑
HandlePresentationOpenNavigation(pres);
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
// 检查隐藏幻灯片
if (Settings.PowerPointSettings.IsNotifyHiddenPage)
2025-07-20 16:14:26 +08:00
{
2025-07-29 01:15:32 +08:00
CheckAndNotifyHiddenSlides(pres);
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
// 检查自动播放设置
if (Settings.PowerPointSettings.IsNotifyAutoPlayPresentation)
2025-07-20 16:14:26 +08:00
{
2025-07-29 01:15:32 +08:00
CheckAndNotifyAutoPlaySettings(pres);
2025-07-20 16:14:26 +08:00
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
_pptUIManager?.UpdateConnectionStatus(true);
2025-08-31 11:43:52 +08:00
2025-08-23 19:16:19 +08:00
LogHelper.WriteLogToFile($"已打开新演示文稿: {pres.Name},墨迹状态已清理", LogHelper.LogType.Event);
2025-05-25 09:29:48 +08:00
});
}
2025-07-29 01:15:32 +08:00
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理演示文稿打开事件失败: {ex}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
2025-07-29 01:15:32 +08:00
private void OnPPTPresentationClose(Presentation pres)
{
try
{
Application.Current.Dispatcher.InvokeAsync(() =>
2025-05-25 09:29:48 +08:00
{
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.SaveAllStrokesToFile(pres);
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
_pptUIManager?.UpdateConnectionStatus(false);
});
2025-05-25 09:29:48 +08:00
}
2025-09-13 19:29:17 +08:00
catch (COMException comEx)
{
// COM对象已失效,这是正常情况,完全静默处理
var hr = (uint)comEx.HResult;
if (hr == 0x8001010E || hr == 0x80004005 || hr == 0x800706BA || hr == 0x800706BE || hr == 0x80048010)
{
}
}
catch (Exception)
2025-07-29 01:15:32 +08:00
{
2025-05-25 09:29:48 +08:00
}
}
2025-08-23 19:10:53 +08:00
private void OnPPTSlideShowStateChanged(bool isInSlideShow)
{
try
{
Application.Current.Dispatcher.InvokeAsync(() =>
{
// 通知UI管理器放映状态变化
_pptUIManager?.OnSlideShowStateChanged(isInSlideShow);
if (!isInSlideShow)
{
}
2025-09-06 21:26:46 +08:00
// 检查主窗口可见性(用于仅PPT模式)
CheckMainWindowVisibility();
2025-08-23 19:10:53 +08:00
});
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理PPT放映状态变化失败: {ex}", LogHelper.LogType.Error);
}
}
2025-10-20 17:45:14 +08:00
private async void OnPPTSlideShowBegin(SlideShowWindow wn)
2025-07-29 01:15:32 +08:00
{
try
{
2025-09-22 11:48:05 +08:00
// 始终记录进入放映时浮动栏收纳状态,用于退出时恢复
wasFloatingBarFoldedWhenEnterSlideShow = isFloatingBarFolded;
2025-07-29 01:15:32 +08:00
2025-09-18 17:58:51 +08:00
if (Settings.Automation.IsAutoFoldInPPTSlideShow)
{
if (!isFloatingBarFolded)
FoldFloatingBar_MouseUp(new object(), null);
}
2025-09-22 11:36:55 +08:00
else
{
2025-09-22 11:48:05 +08:00
if (isFloatingBarFolded)
{
2025-10-20 17:45:14 +08:00
await UnFoldFloatingBar(new object());
2025-09-22 11:48:05 +08:00
}
2025-09-22 11:36:55 +08:00
}
2025-05-25 09:29:48 +08:00
isStopInkReplay = true;
2025-10-20 17:45:14 +08:00
await Application.Current.Dispatcher.InvokeAsync(() =>
2025-07-29 01:15:32 +08:00
{
2025-11-08 19:02:37 +08:00
Presentation activePresentation = null;
int currentSlide = 0;
int totalSlides = 0;
if (wn?.View != null && wn.Presentation != null)
{
activePresentation = wn.Presentation;
currentSlide = wn.View.CurrentShowPosition;
totalSlides = activePresentation.Slides.Count;
}
else
{
activePresentation = _pptManager?.GetCurrentActivePresentation();
currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
totalSlides = _pptManager?.SlidesCount ?? 0;
}
2025-09-13 18:07:42 +08:00
if (activePresentation != null)
{
2025-11-15 18:04:22 +08:00
if (_singlePPTInkManager != null)
2025-10-18 21:20:54 +08:00
{
2025-11-15 18:04:22 +08:00
try
{
_singlePPTInkManager.InitializePresentation(activePresentation);
}
catch (Exception)
{
}
2025-10-18 21:20:54 +08:00
}
2025-09-13 18:07:42 +08:00
}
2025-09-13 11:29:48 +08:00
// 处理跳转到首页或上次播放位置
2025-07-21 17:19:27 +08:00
if (Settings.PowerPointSettings.IsAlwaysGoToFirstPageOnReenter)
{
2025-07-29 01:15:32 +08:00
_pptManager?.TryNavigateToSlide(1);
2025-07-21 17:19:27 +08:00
}
2025-09-13 11:29:48 +08:00
else if (_shouldNavigateToLastPage && _lastPlaybackPage > 0)
{
_pptManager?.TryNavigateToSlide(_lastPlaybackPage);
_shouldNavigateToLastPage = false; // 重置标志位
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
// 更新UI状态
_pptUIManager?.UpdateSlideShowStatus(true, currentSlide, totalSlides);
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
// 设置浮动栏透明度和边距
_pptUIManager?.SetFloatingBarOpacity(Settings.Appearance.ViewboxFloatingBarOpacityInPPTValue);
_pptUIManager?.SetMainPanelMargin(new Thickness(10, 10, 10, 10));
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
// 显示侧边栏退出按钮
_pptUIManager?.UpdateSidebarExitButtons(true);
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
// 处理画板显示
2025-05-25 09:29:48 +08:00
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow &&
!Settings.Automation.IsAutoFoldInPPTSlideShow &&
2025-07-29 01:15:32 +08:00
GridTransparencyFakeBackground.Background == Brushes.Transparent && !isFloatingBarFolded)
{
2025-05-25 09:29:48 +08:00
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
}
if (currentMode != 0)
{
2025-07-29 01:15:32 +08:00
ImageBlackboard_MouseUp(null, null);
2025-05-25 09:29:48 +08:00
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
}
BorderFloatingBarMainControls.Visibility = Visibility.Visible;
2025-09-06 19:27:17 +08:00
// 在PPT模式下根据设置决定是否隐藏手势面板和手势按钮
AnimationsHelper.HideWithSlideAndFade(TwoFingerGestureBorder);
AnimationsHelper.HideWithSlideAndFade(BoardTwoFingerGestureBorder);
2025-09-07 13:30:46 +08:00
2025-09-06 19:27:17 +08:00
// 根据设置决定是否在PPT放映模式下显示手势按钮
if (Settings.PowerPointSettings.ShowGestureButtonInSlideShow)
{
// 如果启用了PPT放映模式显示手势按钮,则显示手势按钮
if (Settings.Gesture.IsEnableTwoFingerGesture)
{
CheckEnableTwoFingerGestureBtnVisibility(true);
}
}
else
{
// 如果禁用了PPT放映模式显示手势按钮,则隐藏手势按钮
EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed;
}
2025-05-25 09:29:48 +08:00
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow &&
!Settings.Automation.IsAutoFoldInPPTSlideShow)
{
2025-11-15 18:04:22 +08:00
await Task.Delay(300);
2025-09-20 11:22:09 +08:00
// 先进入批注模式,这会显示调色盘
PenIcon_Click(null, null);
// 然后设置颜色
2025-05-25 09:29:48 +08:00
BtnColorRed_Click(null, null);
2025-11-08 19:36:05 +08:00
try
{
2025-11-08 19:36:05 +08:00
if (inkCanvas.EditingMode == InkCanvasEditingMode.Ink)
{
2025-11-08 19:36:05 +08:00
UpdateCurrentToolMode("pen");
SetFloatingBarHighlightPosition("pen");
if (Settings.Appearance.IsShowQuickColorPalette && QuickColorPalettePanel != null && QuickColorPaletteSingleRowPanel != null)
{
2025-11-08 19:36:05 +08:00
// 根据显示模式选择显示哪个面板
if (Settings.Appearance.QuickColorPaletteDisplayMode == 0)
2025-10-20 12:10:47 +08:00
{
2025-11-08 19:36:05 +08:00
// 单行显示模式
QuickColorPalettePanel.Visibility = Visibility.Collapsed;
QuickColorPaletteSingleRowPanel.Visibility = Visibility.Visible;
}
else
{
// 双行显示模式
QuickColorPalettePanel.Visibility = Visibility.Visible;
QuickColorPaletteSingleRowPanel.Visibility = Visibility.Collapsed;
2025-10-20 12:10:47 +08:00
}
}
}
2025-11-08 19:36:05 +08:00
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"PPT进入批注模式后同步浮动栏高光状态失败: {ex.Message}", LogHelper.LogType.Error);
}
}
2025-05-25 09:29:48 +08:00
isEnteredSlideShowEndEvent = false;
2025-07-29 01:15:32 +08:00
// 加载当前页墨迹
LoadCurrentSlideInk(currentSlide);
});
if (!isFloatingBarFolded)
{
2025-10-20 17:45:14 +08:00
new Thread(() =>
{
Thread.Sleep(100);
Application.Current.Dispatcher.Invoke(() =>
{
ViewboxFloatingBarMarginAnimation(60);
});
}).Start();
2025-07-29 01:15:32 +08:00
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理幻灯片放映开始事件失败: {ex}", LogHelper.LogType.Error);
}
}
2025-07-21 14:35:30 +08:00
2025-07-29 01:15:32 +08:00
private void OnPPTSlideShowNextSlide(SlideShowWindow wn)
{
try
{
Application.Current.Dispatcher.InvokeAsync(() =>
{
2025-11-08 19:02:37 +08:00
if (wn?.View == null || wn.Presentation == null)
2025-09-13 18:07:42 +08:00
{
2025-11-08 19:02:37 +08:00
return;
2025-09-13 18:07:42 +08:00
}
2025-11-08 19:02:37 +08:00
var currentSlide = wn.View.CurrentShowPosition;
var activePresentation = wn.Presentation;
var totalSlides = activePresentation.Slides.Count;
2025-09-13 18:20:56 +08:00
// 使用防抖机制处理页面切换
HandleSlideSwitchWithDebounce(currentSlide, totalSlides);
2025-07-29 01:15:32 +08:00
2025-07-21 16:43:29 +08:00
});
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理幻灯片切换事件失败: {ex}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
2025-07-29 01:15:32 +08:00
private async void OnPPTSlideShowEnd(Presentation pres)
{
try
{
2025-09-22 11:48:05 +08:00
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
2025-07-29 01:15:32 +08:00
{
2025-09-22 11:36:55 +08:00
if (wasFloatingBarFoldedWhenEnterSlideShow)
{
if (!isFloatingBarFolded) FoldFloatingBar_MouseUp(new object(), null);
}
else
{
if (isFloatingBarFolded) await UnFoldFloatingBar(new object());
}
2025-07-29 01:15:32 +08:00
}
else
{
2025-09-22 11:48:05 +08:00
if (Settings.Automation.IsAutoFoldInPPTSlideShow)
2025-09-22 11:36:55 +08:00
{
2025-10-03 17:08:46 +08:00
if (isFloatingBarFolded)
2025-09-22 11:48:05 +08:00
{
2025-09-22 11:58:54 +08:00
await UnFoldFloatingBar(new object());
2025-09-22 11:48:05 +08:00
}
}
else
{
2025-10-03 17:08:46 +08:00
if (isFloatingBarFolded)
2025-09-22 11:48:05 +08:00
{
await UnFoldFloatingBar(new object());
}
2025-09-22 11:36:55 +08:00
}
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
if (isEnteredSlideShowEndEvent) return;
isEnteredSlideShowEndEvent = true;
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.SaveAllStrokesToFile(pres);
2025-07-29 01:15:32 +08:00
await Application.Current.Dispatcher.InvokeAsync(() =>
2025-07-20 12:01:30 +08:00
{
2025-07-21 08:37:37 +08:00
try
{
2025-07-29 01:15:32 +08:00
isPresentationHaveBlackSpace = false;
// 恢复主题
if (BtnSwitchTheme.Content.ToString() == "深色")
2025-07-21 08:37:37 +08:00
{
2025-07-29 01:15:32 +08:00
BtnExit.Foreground = Brushes.Black;
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
2025-07-21 08:37:37 +08:00
}
2025-07-29 01:15:32 +08:00
// 更新UI状态
_pptUIManager?.UpdateSlideShowStatus(false);
_pptUIManager?.UpdateSidebarExitButtons(false);
_pptUIManager?.SetMainPanelMargin(new Thickness(10, 10, 10, 55));
_pptUIManager?.SetFloatingBarOpacity(Settings.Appearance.ViewboxFloatingBarOpacityValue);
if (currentMode != 0)
2025-07-21 08:37:37 +08:00
{
2025-07-29 01:15:32 +08:00
CloseWhiteboardImmediately();
currentMode = 0;
2025-07-21 08:37:37 +08:00
}
2025-07-29 01:15:32 +08:00
ClearStrokes(true);
2025-07-29 01:31:21 +08:00
// 清空备份历史记录,防止退出白板时恢复已结束PPT的墨迹
// 注意:这里只清空索引0的备份,不影响白板页面的墨迹(索引1及以上)
2025-07-29 01:15:32 +08:00
TimeMachineHistories[0] = null;
2025-09-13 18:52:23 +08:00
// 重置墨迹管理器的锁定状态,防止下次放映时墨迹显示错误
ResetInkManagerLockState();
// 退出PPT模式时恢复手势面板和手势按钮的显示状态
if (Settings.Gesture.IsEnableTwoFingerGesture && ToggleSwitchEnableMultiTouchMode.IsOn)
{
// 根据手势设置决定是否显示手势面板和手势按钮
CheckEnableTwoFingerGestureBtnVisibility(true);
}
else
{
// 如果手势功能未启用,确保手势按钮保持隐藏
EnableTwoFingerGestureBorder.Visibility = Visibility.Collapsed;
}
// 退出PPT模式时隐藏快捷调色盘
if (QuickColorPalettePanel != null)
{
QuickColorPalettePanel.Visibility = Visibility.Collapsed;
}
if (QuickColorPaletteSingleRowPanel != null)
{
QuickColorPaletteSingleRowPanel.Visibility = Visibility.Collapsed;
}
2025-07-29 01:15:32 +08:00
if (GridTransparencyFakeBackground.Background != Brushes.Transparent)
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
2025-09-13 22:44:29 +08:00
SetCurrentToolMode(InkCanvasEditingMode.None);
2025-10-20 17:45:14 +08:00
UpdateCurrentToolMode("cursor");
SetFloatingBarHighlightPosition("cursor");
2025-07-21 08:37:37 +08:00
}
catch (Exception ex)
{
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile($"处理幻灯片放映结束UI更新失败: {ex}", LogHelper.LogType.Error);
2025-07-21 08:37:37 +08:00
}
2025-07-29 01:15:32 +08:00
});
2025-05-25 09:29:48 +08:00
2025-09-13 11:56:26 +08:00
await Task.Delay(100);
2025-07-29 01:15:32 +08:00
await Application.Current.Dispatcher.InvokeAsync(() =>
{
PureViewboxFloatingBarMarginAnimationInDesktopMode();
2025-07-29 01:15:32 +08:00
ViewboxFloatingBarMarginAnimation(100, true);
});
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理幻灯片放映结束事件失败: {ex}", LogHelper.LogType.Error);
}
}
#endregion
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
#region Helper Methods
private void HandlePresentationOpenNavigation(Presentation pres)
{
try
{
if (Settings.PowerPointSettings.IsAlwaysGoToFirstPageOnReenter)
{
_pptManager?.TryNavigateToSlide(1);
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
else if (Settings.PowerPointSettings.IsNotifyPreviousPage)
{
ShowPreviousPageNotification(pres);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理演示文稿导航失败: {ex}", LogHelper.LogType.Error);
}
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
private void ShowPreviousPageNotification(Presentation pres)
{
try
{
if (pres == null) return;
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
var presentationPath = pres.FullName;
var fileHash = GetFileHash(presentationPath);
var folderName = pres.Name + "_" + pres.Slides.Count + "_" + fileHash;
var folderPath = Path.Combine(Settings.Automation.AutoSavedStrokesLocation, "Auto Saved - Presentations", folderName);
var positionFile = Path.Combine(folderPath, "Position");
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
if (!File.Exists(positionFile)) return;
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
if (int.TryParse(File.ReadAllText(positionFile), out var page) && page > 0)
{
2025-09-13 11:29:48 +08:00
_lastPlaybackPage = page;
2025-07-29 01:15:32 +08:00
new YesOrNoNotificationWindow($"上次播放到了第 {page} 页, 是否立即跳转", () =>
{
2025-10-18 16:41:55 +08:00
try
{
if (_pptManager?.PPTApplication != null)
{
if (_pptManager.PPTApplication.SlideShowWindows.Count >= 1)
{
pres.SlideShowWindow.View.GotoSlide(page);
}
else
{
pres.Windows[1].View.GotoSlide(page);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"跳转到第{page}页失败: {ex}", LogHelper.LogType.Error);
}
2025-07-29 01:15:32 +08:00
}).ShowDialog();
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"显示上次播放页通知失败: {ex}", LogHelper.LogType.Error);
}
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
private void CheckAndNotifyHiddenSlides(Presentation pres)
{
try
{
bool hasHiddenSlides = false;
if (pres?.Slides != null)
{
foreach (Slide slide in pres.Slides)
{
if (slide.SlideShowTransition.Hidden == MsoTriState.msoTrue)
{
hasHiddenSlides = true;
break;
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
}
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
if (hasHiddenSlides && !IsShowingRestoreHiddenSlidesWindow)
{
IsShowingRestoreHiddenSlidesWindow = true;
new YesOrNoNotificationWindow("检测到此演示文档中包含隐藏的幻灯片,是否取消隐藏?",
() =>
{
try
{
if (pres?.Slides != null)
{
foreach (Slide slide in pres.Slides)
{
if (slide.SlideShowTransition.Hidden == MsoTriState.msoTrue)
slide.SlideShowTransition.Hidden = MsoTriState.msoFalse;
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"取消隐藏幻灯片失败: {ex}", LogHelper.LogType.Error);
}
finally
{
IsShowingRestoreHiddenSlidesWindow = false;
}
},
() => { IsShowingRestoreHiddenSlidesWindow = false; },
() => { IsShowingRestoreHiddenSlidesWindow = false; }).ShowDialog();
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"检查隐藏幻灯片失败: {ex}", LogHelper.LogType.Error);
}
}
2025-07-28 18:23:07 +08:00
2025-07-29 01:15:32 +08:00
private void CheckAndNotifyAutoPlaySettings(Presentation pres)
{
try
{
if (BtnPPTSlideShowEnd.Visibility == Visibility.Visible) return;
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
bool hasSlideTimings = false;
if (pres?.Slides != null)
{
foreach (Slide slide in pres.Slides)
{
if (slide.SlideShowTransition.AdvanceOnTime == MsoTriState.msoTrue &&
slide.SlideShowTransition.AdvanceTime > 0)
{
hasSlideTimings = true;
break;
}
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
if (hasSlideTimings && !IsShowingAutoplaySlidesWindow)
{
IsShowingAutoplaySlidesWindow = true;
new YesOrNoNotificationWindow("检测到此演示文档中自动播放或排练计时已经启用,可能导致幻灯片自动翻页,是否取消?",
() =>
{
try
{
if (pres != null)
{
pres.SlideShowSettings.AdvanceMode = PpSlideShowAdvanceMode.ppSlideShowManualAdvance;
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"设置手动播放模式失败: {ex}", LogHelper.LogType.Error);
}
finally
{
IsShowingAutoplaySlidesWindow = false;
}
},
() => { IsShowingAutoplaySlidesWindow = false; },
() => { IsShowingAutoplaySlidesWindow = false; }).ShowDialog();
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"检查自动播放设置失败: {ex}", LogHelper.LogType.Error);
}
}
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
private void LoadCurrentSlideInk(int slideIndex)
{
try
{
2025-11-08 19:55:10 +08:00
ClearStrokes(true);
timeMachine.ClearStrokeHistory();
2025-11-15 18:04:22 +08:00
StrokeCollection strokes = _singlePPTInkManager?.LoadSlideStrokes(slideIndex);
2025-10-18 21:20:54 +08:00
2025-11-08 19:55:10 +08:00
if (strokes != null && strokes.Count > 0)
2025-07-29 01:15:32 +08:00
{
inkCanvas.Strokes.Add(strokes);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"加载当前页墨迹失败: {ex}", LogHelper.LogType.Error);
}
}
2025-07-20 12:36:21 +08:00
2025-09-13 18:52:23 +08:00
/// <summary>
/// 重置墨迹管理器的锁定状态,防止墨迹显示错误
/// </summary>
private void ResetInkManagerLockState()
{
try
{
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.ResetLockState();
2025-09-13 18:52:23 +08:00
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"重置墨迹管理器锁定状态失败: {ex}", LogHelper.LogType.Error);
}
}
2025-09-22 11:36:55 +08:00
/// <summary>
/// 重置PPT相关的状态变量,当PPT自动收纳设置变更时调用
/// </summary>
public void ResetPPTStateVariables()
{
try
{
// 重置进入PPT时的浮动栏收纳状态记录
wasFloatingBarFoldedWhenEnterSlideShow = false;
2025-10-03 17:08:46 +08:00
2025-09-22 11:36:55 +08:00
// 重置PPT放映结束事件标志
isEnteredSlideShowEndEvent = false;
2025-10-03 17:08:46 +08:00
2025-09-22 11:36:55 +08:00
// 重置演示文稿黑边状态
isPresentationHaveBlackSpace = false;
2025-10-03 17:08:46 +08:00
2025-09-22 11:36:55 +08:00
// 重置上次播放位置相关字段
_lastPlaybackPage = 0;
_shouldNavigateToLastPage = false;
2025-10-03 17:08:46 +08:00
2025-09-22 11:36:55 +08:00
// 重置页面切换防抖机制
_lastSlideSwitchTime = DateTime.MinValue;
_pendingSlideIndex = -1;
2025-10-03 17:08:46 +08:00
2025-09-22 11:36:55 +08:00
LogHelper.WriteLogToFile("PPT状态变量已重置", LogHelper.LogType.Trace);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"重置PPT状态变量失败: {ex.Message}", LogHelper.LogType.Error);
}
}
2025-09-13 18:20:56 +08:00
/// <summary>
/// 使用防抖机制处理页面切换
/// </summary>
private void HandleSlideSwitchWithDebounce(int currentSlide, int totalSlides)
{
try
{
var now = DateTime.Now;
2025-10-03 17:08:46 +08:00
2025-09-13 18:20:56 +08:00
// 如果距离上次切换时间太短,使用防抖机制
if (now - _lastSlideSwitchTime < TimeSpan.FromMilliseconds(SlideSwitchDebounceMs))
{
_pendingSlideIndex = currentSlide;
2025-10-03 17:08:46 +08:00
2025-09-13 18:20:56 +08:00
// 停止之前的定时器
_slideSwitchDebounceTimer?.Stop();
2025-10-03 17:08:46 +08:00
2025-09-13 18:20:56 +08:00
// 创建新的定时器
_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);
}
2025-10-03 17:08:46 +08:00
2025-09-13 18:20:56 +08:00
_lastSlideSwitchTime = now;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理页面切换防抖失败: {ex}", LogHelper.LogType.Error);
}
}
2025-07-29 01:15:32 +08:00
private void SwitchSlideInk(int newSlideIndex)
{
try
{
2025-09-21 08:26:55 +08:00
// 检查PPT连接状态
if (_pptManager?.IsConnected != true || _pptManager?.IsInSlideShow != true)
{
return;
}
2025-09-13 19:10:40 +08:00
// 获取当前页面索引
var currentSlideIndex = _pptManager?.GetCurrentSlideNumber() ?? 0;
2025-10-03 17:08:46 +08:00
2025-09-21 08:26:55 +08:00
// 验证页面索引的有效性
if (newSlideIndex <= 0)
{
LogHelper.WriteLogToFile($"无效的新页面索引: {newSlideIndex},跳过页面切换", LogHelper.LogType.Warning);
return;
}
2025-10-03 17:08:46 +08:00
2025-09-13 19:10:40 +08:00
// 如果有当前墨迹且不是第一次切换,先保存到当前页面
if (inkCanvas.Strokes.Count > 0 && currentSlideIndex > 0 && currentSlideIndex != newSlideIndex)
{
2025-11-15 18:04:22 +08:00
bool canWrite = _singlePPTInkManager?.CanWriteInk(currentSlideIndex) == true;
2025-10-18 21:20:54 +08:00
if (canWrite)
{
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlideIndex, inkCanvas.Strokes);
2025-09-21 08:26:55 +08:00
}
}
2025-10-03 17:08:46 +08:00
2025-11-08 19:55:10 +08:00
ClearStrokes(true);
timeMachine.ClearStrokeHistory();
2025-11-15 18:04:22 +08:00
StrokeCollection newStrokes = _singlePPTInkManager?.SwitchToSlide(newSlideIndex, null);
2025-11-08 19:55:10 +08:00
if (newStrokes != null && newStrokes.Count > 0)
2025-07-20 12:36:21 +08:00
{
2025-07-29 01:15:32 +08:00
inkCanvas.Strokes.Add(newStrokes);
2025-07-20 12:36:21 +08:00
}
2025-07-29 01:15:32 +08:00
2025-09-21 08:26:55 +08:00
// 注意:LockInkForSlide已经在SwitchToSlide中调用,这里不需要重复调用
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
catch (Exception ex)
{
LogHelper.WriteLogToFile($"切换页面墨迹失败: {ex}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
2025-07-29 01:15:32 +08:00
private string GetFileHash(string filePath)
{
try
{
if (string.IsNullOrEmpty(filePath)) return "unknown";
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
using (var md5 = MD5.Create())
{
byte[] hashBytes = md5.ComputeHash(Encoding.UTF8.GetBytes(filePath));
return BitConverter.ToString(hashBytes).Replace("-", "").Substring(0, 8);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"计算文件哈希值失败: {ex}", LogHelper.LogType.Error);
return "error";
}
}
#endregion
2025-07-21 21:02:23 +08:00
2025-08-03 16:46:33 +08:00
private void BtnCheckPPT_Click(object sender, RoutedEventArgs e)
{
try
{
2025-07-29 01:15:32 +08:00
// 使用新的PPT管理器进行连接检查
if (_pptManager == null)
2025-07-20 16:14:26 +08:00
{
2025-07-29 01:15:32 +08:00
InitializePPTManagers();
2025-07-20 16:14:26 +08:00
}
2025-07-29 01:15:32 +08:00
// 手动触发一次连接检查
_pptManager?.StartMonitoring();
// 等待一小段时间让连接建立
Task.Delay(500).ContinueWith(_ =>
{
Application.Current.Dispatcher.Invoke(() =>
{
if (_pptManager?.IsConnected == true)
{
LogHelper.WriteLogToFile("手动PPT连接检查成功", LogHelper.LogType.Event);
}
else
{
MessageBox.Show("未找到幻灯片");
LogHelper.WriteLogToFile("手动PPT连接检查失败", LogHelper.LogType.Warning);
}
});
2025-05-25 09:29:48 +08:00
});
}
2025-08-03 16:46:33 +08:00
catch (Exception ex)
{
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile($"手动检查PPT应用程序失败: {ex}", LogHelper.LogType.Error);
_pptUIManager?.UpdateConnectionStatus(false);
MessageBox.Show("未找到幻灯片");
2025-05-25 09:29:48 +08:00
}
}
2025-09-06 12:09:06 +08:00
private void ToggleSwitchPowerPointEnhancement_Toggled(object sender, RoutedEventArgs e)
{
if (!isLoaded) return;
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
Settings.PowerPointSettings.EnablePowerPointEnhancement = ToggleSwitchPowerPointEnhancement.IsOn;
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
if (Settings.PowerPointSettings.EnablePowerPointEnhancement)
{
Settings.PowerPointSettings.IsSupportWPS = false;
ToggleSwitchSupportWPS.IsOn = false;
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
// 更新PPT管理器的WPS支持设置
if (_pptManager != null)
{
_pptManager.IsSupportWPS = false;
}
}
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
SaveSettingsToFile();
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
// 启动或停止PowerPoint进程守护
if (Settings.PowerPointSettings.EnablePowerPointEnhancement)
{
StartPowerPointProcessMonitoring();
}
else
{
StopPowerPointProcessMonitoring();
}
}
2025-08-03 16:46:33 +08:00
private void ToggleSwitchSupportWPS_Toggled(object sender, RoutedEventArgs e)
{
2025-07-29 01:15:32 +08:00
if (!isLoaded) return;
Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn;
2025-09-07 13:30:46 +08:00
2025-09-06 12:09:06 +08:00
if (Settings.PowerPointSettings.IsSupportWPS)
{
Settings.PowerPointSettings.EnablePowerPointEnhancement = false;
ToggleSwitchPowerPointEnhancement.IsOn = false;
StopPowerPointProcessMonitoring();
}
2025-07-29 01:15:32 +08:00
// 更新PPT管理器的WPS支持设置
if (_pptManager != null)
{
_pptManager.IsSupportWPS = Settings.PowerPointSettings.IsSupportWPS;
}
SaveSettingsToFile();
}
private static bool isWPSSupportOn => Settings.PowerPointSettings.IsSupportWPS;
public static bool IsShowingRestoreHiddenSlidesWindow;
private static bool IsShowingAutoplaySlidesWindow;
2025-08-03 16:46:33 +08:00
private void BtnPPTSlidesUp_Click(object sender, RoutedEventArgs e)
{
Application.Current.Dispatcher.Invoke(() =>
{
2025-07-21 20:30:07 +08:00
try
2025-07-20 16:14:26 +08:00
{
2025-07-29 01:15:32 +08:00
// 保存当前页墨迹
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
if (currentSlide > 0)
2025-07-20 16:14:26 +08:00
{
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
2025-05-25 09:29:48 +08:00
}
2025-07-29 01:15:32 +08:00
// 保存截图(如果启用)
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
2025-07-21 20:30:07 +08:00
{
2025-07-29 01:15:32 +08:00
var presentationName = _pptManager?.GetPresentationName() ?? "";
SaveScreenShot(true, $"{presentationName}/{currentSlide}");
}
// 执行翻页
if (_pptManager?.TryNavigatePrevious() == true)
{
// 翻页成功,等待事件处理墨迹切换
}
else
{
LogHelper.WriteLogToFile("切换到上一页失败", LogHelper.LogType.Warning);
_pptUIManager?.UpdateConnectionStatus(false);
2025-06-12 18:55:50 +08:00
}
2025-07-21 20:30:07 +08:00
}
2025-08-03 16:46:33 +08:00
catch (Exception ex)
{
2025-07-28 14:40:44 +08:00
LogHelper.WriteLogToFile($"PPT上一页操作异常: {ex}", LogHelper.LogType.Error);
2025-07-29 01:15:32 +08:00
_pptUIManager?.UpdateConnectionStatus(false);
2025-07-21 20:30:07 +08:00
}
});
2025-05-25 09:29:48 +08:00
}
2025-08-03 16:46:33 +08:00
private void BtnPPTSlidesDown_Click(object sender, RoutedEventArgs e)
{
Application.Current.Dispatcher.Invoke(() =>
{
2025-07-21 20:30:07 +08:00
try
2025-07-20 16:14:26 +08:00
{
2025-07-29 01:15:32 +08:00
// 保存当前页墨迹
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
if (currentSlide > 0)
2025-07-20 16:14:26 +08:00
{
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
2025-06-12 18:55:50 +08:00
}
2025-07-29 01:15:32 +08:00
// 保存截图(如果启用)
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
2025-07-21 20:30:07 +08:00
{
2025-07-29 01:15:32 +08:00
var presentationName = _pptManager?.GetPresentationName() ?? "";
SaveScreenShot(true, $"{presentationName}/{currentSlide}");
}
// 执行翻页
if (_pptManager?.TryNavigateNext() == true)
{
// 翻页成功,等待事件处理墨迹切换
}
else
{
LogHelper.WriteLogToFile("切换到下一页失败", LogHelper.LogType.Warning);
_pptUIManager?.UpdateConnectionStatus(false);
2025-05-25 09:29:48 +08:00
}
2025-07-21 20:30:07 +08:00
}
2025-08-03 16:46:33 +08:00
catch (Exception ex)
{
2025-07-28 14:40:44 +08:00
LogHelper.WriteLogToFile($"PPT下一页操作异常: {ex}", LogHelper.LogType.Error);
2025-07-29 01:15:32 +08:00
_pptUIManager?.UpdateConnectionStatus(false);
2025-07-21 20:30:07 +08:00
}
});
2025-05-25 09:29:48 +08:00
}
2025-10-22 12:16:42 +08:00
private void PPTNavigationBtn_MouseDown(object sender, MouseButtonEventArgs e)
2025-05-25 09:29:48 +08:00
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = sender;
if (!Settings.PowerPointSettings.EnablePPTButtonPageClickable) return;
if (sender == PPTLSPageButton)
2025-05-25 09:29:48 +08:00
{
2025-06-12 18:55:50 +08:00
PPTLSPageButtonFeedbackBorder.Opacity = 0.15;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRSPageButton)
2025-05-25 09:29:48 +08:00
{
2025-06-12 18:55:50 +08:00
PPTRSPageButtonFeedbackBorder.Opacity = 0.15;
}
else if (sender == PPTLBPageButton)
{
PPTLBPageButtonFeedbackBorder.Opacity = 0.15;
}
else if (sender == PPTRBPageButton)
{
PPTRBPageButtonFeedbackBorder.Opacity = 0.15;
2025-05-25 09:29:48 +08:00
}
}
2025-10-18 17:24:47 +08:00
private void PPTNavigationBtn_MouseLeave(object sender, MouseEventArgs e)
2025-05-25 09:29:48 +08:00
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = null;
if (sender == PPTLSPageButton)
2025-05-25 09:29:48 +08:00
{
2025-06-12 18:55:50 +08:00
PPTLSPageButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRSPageButton)
2025-05-25 09:29:48 +08:00
{
2025-06-12 18:55:50 +08:00
PPTRSPageButtonFeedbackBorder.Opacity = 0;
}
else if (sender == PPTLBPageButton)
{
PPTLBPageButtonFeedbackBorder.Opacity = 0;
}
else if (sender == PPTRBPageButton)
{
PPTRBPageButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
}
private async void PPTNavigationBtn_MouseUp(object sender, MouseButtonEventArgs e)
2025-08-03 16:46:33 +08:00
{
2025-06-12 18:55:50 +08:00
if (lastBorderMouseDownObject != sender) return;
2025-05-25 09:29:48 +08:00
2025-06-12 18:55:50 +08:00
if (sender == PPTLSPageButton)
{
PPTLSPageButtonFeedbackBorder.Opacity = 0;
}
else if (sender == PPTRSPageButton)
{
PPTRSPageButtonFeedbackBorder.Opacity = 0;
}
else if (sender == PPTLBPageButton)
{
PPTLBPageButtonFeedbackBorder.Opacity = 0;
}
else if (sender == PPTRBPageButton)
{
PPTRBPageButtonFeedbackBorder.Opacity = 0;
}
2025-05-25 09:29:48 +08:00
2025-06-12 18:55:50 +08:00
if (!Settings.PowerPointSettings.EnablePPTButtonPageClickable) return;
2025-05-25 09:29:48 +08:00
2025-07-29 01:15:32 +08:00
// 使用新的PPT管理器检查连接状态
if (_pptManager?.IsConnected != true || _pptManager?.IsInSlideShow != true)
2025-07-20 16:14:26 +08:00
{
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile("PPT未连接或未在放映状态,无法执行页码点击操作", LogHelper.LogType.Warning);
2025-07-20 16:14:26 +08:00
return;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
2025-07-20 16:14:26 +08:00
try
{
GridTransparencyFakeBackground.Opacity = 1;
GridTransparencyFakeBackground.Background = new SolidColorBrush(StringToColor("#01FFFFFF"));
CursorIcon_Click(null, null);
2025-07-29 01:15:32 +08:00
// 使用新的PPT管理器显示导航
if (_pptManager.TryShowSlideNavigation())
{
LogHelper.WriteLogToFile("成功显示PPT幻灯片导航", LogHelper.LogType.Trace);
2025-07-20 16:14:26 +08:00
}
2025-07-29 01:15:32 +08:00
else
{
LogHelper.WriteLogToFile("显示PPT幻灯片导航失败", LogHelper.LogType.Warning);
2025-07-20 16:14:26 +08:00
}
// 控制居中
2025-08-03 16:46:33 +08:00
if (!isFloatingBarFolded)
{
2025-10-22 12:12:43 +08:00
await Task.Delay(100);
2025-07-20 16:14:26 +08:00
ViewboxFloatingBarMarginAnimation(60);
}
}
catch (Exception ex)
{
2025-07-28 14:40:44 +08:00
LogHelper.WriteLogToFile($"PPT翻页控件操作失败: {ex}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
2025-08-03 16:46:33 +08:00
private void BtnPPTSlideShow_Click(object sender, RoutedEventArgs e)
{
new Thread(() =>
{
try
{
2025-07-29 01:15:32 +08:00
if (_pptManager?.TryStartSlideShow() != true)
{
LogHelper.WriteLogToFile("启动幻灯片放映失败", LogHelper.LogType.Warning);
}
}
2025-08-03 16:46:33 +08:00
catch (Exception ex)
{
2025-07-29 01:15:32 +08:00
LogHelper.WriteLogToFile($"启动幻灯片放映异常: {ex}", LogHelper.LogType.Error);
2025-06-12 18:55:50 +08:00
}
2025-07-28 14:40:44 +08:00
}).Start();
2025-05-25 09:29:48 +08:00
}
2025-08-03 16:46:33 +08:00
private async void BtnPPTSlideShowEnd_Click(object sender, RoutedEventArgs e)
{
2025-07-20 16:14:26 +08:00
try
{
2025-07-29 01:15:32 +08:00
// 保存当前页墨迹
var currentSlide = _pptManager?.GetCurrentSlideNumber() ?? 0;
if (currentSlide > 0)
2025-07-20 16:14:26 +08:00
{
2025-08-03 16:46:33 +08:00
Application.Current.Dispatcher.Invoke(() =>
{
2025-11-15 18:04:22 +08:00
_singlePPTInkManager?.SaveCurrentSlideStrokes(currentSlide, inkCanvas.Strokes);
2025-07-29 01:15:32 +08:00
timeMachine.ClearStrokeHistory();
});
2025-06-12 18:55:50 +08:00
}
2025-06-08 23:47:27 +08:00
2025-07-29 01:15:32 +08:00
// 结束放映
if (_pptManager?.TryEndSlideShow() == true)
{
2025-09-22 11:58:54 +08:00
// 如果成功结束放映,等待OnPPTSlideShowEnd事件处理收纳状态恢复
2025-07-29 01:15:32 +08:00
}
else
{
LogHelper.WriteLogToFile("结束幻灯片放映失败", LogHelper.LogType.Warning);
// 手动更新UI状态,防止事件未触发
2025-08-03 16:46:33 +08:00
await Application.Current.Dispatcher.InvokeAsync(() =>
{
2025-07-29 01:15:32 +08:00
_pptUIManager?.UpdateSlideShowStatus(false);
_pptUIManager?.UpdateSidebarExitButtons(false);
LogHelper.WriteLogToFile("手动更新放映结束UI状态", LogHelper.LogType.Trace);
});
2025-09-22 11:58:54 +08:00
// 手动处理收纳状态恢复,因为OnPPTSlideShowEnd事件可能未触发
await HandleManualSlideShowEnd();
2025-07-29 01:15:32 +08:00
}
2025-07-20 16:14:26 +08:00
HideSubPanels("cursor");
2025-09-13 22:44:29 +08:00
SetCurrentToolMode(InkCanvasEditingMode.None);
2025-10-03 17:08:46 +08:00
2025-07-20 16:14:26 +08:00
await Task.Delay(150);
2025-09-22 12:11:03 +08:00
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
{
if (wasFloatingBarFoldedWhenEnterSlideShow)
{
ViewboxFloatingBarMarginAnimation(-60);
}
else
{
ViewboxFloatingBarMarginAnimation(100, true);
}
}
else
{
if (isFloatingBarFolded)
{
ViewboxFloatingBarMarginAnimation(-60);
}
else
{
ViewboxFloatingBarMarginAnimation(100, true);
}
}
2025-07-20 16:14:26 +08:00
}
catch (Exception ex)
{
2025-07-28 14:40:44 +08:00
LogHelper.WriteLogToFile($"结束PPT放映操作异常: {ex}", LogHelper.LogType.Error);
2025-07-29 01:15:32 +08:00
// 确保UI状态正确
2025-08-03 16:46:33 +08:00
await Application.Current.Dispatcher.InvokeAsync(() =>
{
2025-07-29 01:15:32 +08:00
_pptUIManager?.UpdateSlideShowStatus(false);
_pptUIManager?.UpdateSidebarExitButtons(false);
});
2025-09-22 11:58:54 +08:00
// 异常情况下也手动处理收纳状态恢复
await HandleManualSlideShowEnd();
2025-10-03 17:08:46 +08:00
2025-09-22 12:11:03 +08:00
// 异常情况下也要根据设置决定浮动栏边距
await Task.Delay(150);
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
{
if (wasFloatingBarFoldedWhenEnterSlideShow)
{
ViewboxFloatingBarMarginAnimation(-60);
}
else
{
ViewboxFloatingBarMarginAnimation(100, true);
}
}
else
{
if (isFloatingBarFolded)
{
ViewboxFloatingBarMarginAnimation(-60);
}
else
{
ViewboxFloatingBarMarginAnimation(100, true);
}
}
2025-09-22 11:58:54 +08:00
}
}
/// <summary>
/// 手动处理PPT放映结束时的收纳状态恢复
/// </summary>
private async Task HandleManualSlideShowEnd()
{
try
{
if (Settings.Automation.IsAutoFoldAfterPPTSlideShow)
{
if (wasFloatingBarFoldedWhenEnterSlideShow)
{
if (!isFloatingBarFolded) FoldFloatingBar_MouseUp(new object(), null);
}
else
{
if (isFloatingBarFolded) await UnFoldFloatingBar(new object());
}
}
else
{
if (Settings.Automation.IsAutoFoldInPPTSlideShow)
{
2025-10-03 17:08:46 +08:00
if (isFloatingBarFolded)
2025-09-22 11:58:54 +08:00
{
await UnFoldFloatingBar(new object());
}
}
else
{
// 如果两个功能都关闭,确保浮动栏展开
2025-10-03 17:08:46 +08:00
if (isFloatingBarFolded)
2025-09-22 11:58:54 +08:00
{
await UnFoldFloatingBar(new object());
}
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"手动处理PPT放映结束收纳状态恢复失败: {ex}", LogHelper.LogType.Error);
2025-07-20 16:14:26 +08:00
}
2025-05-25 09:29:48 +08:00
}
private void GridPPTControlPrevious_MouseDown(object sender, MouseButtonEventArgs e)
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = sender;
2025-08-03 16:46:33 +08:00
if (sender == PPTLSPreviousButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTLSPreviousButtonFeedbackBorder.Opacity = 0.15;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTRSPreviousButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTRSPreviousButtonFeedbackBorder.Opacity = 0.15;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTLBPreviousButtonBorder)
2025-06-12 18:55:50 +08:00
{
PPTLBPreviousButtonFeedbackBorder.Opacity = 0.15;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRBPreviousButtonBorder)
{
PPTRBPreviousButtonFeedbackBorder.Opacity = 0.15;
2025-05-25 09:29:48 +08:00
}
2025-08-23 19:43:09 +08:00
// 启动长按检测
if (Settings.PowerPointSettings.EnablePPTButtonLongPressPageTurn)
{
StartLongPressDetection(sender, false);
}
2025-05-25 09:29:48 +08:00
}
private void GridPPTControlPrevious_MouseLeave(object sender, MouseEventArgs e)
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = null;
2025-08-03 16:46:33 +08:00
if (sender == PPTLSPreviousButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTLSPreviousButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTRSPreviousButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTRSPreviousButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTLBPreviousButtonBorder)
2025-06-12 18:55:50 +08:00
{
PPTLBPreviousButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRBPreviousButtonBorder)
{
PPTRBPreviousButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-08-23 19:43:09 +08:00
// 停止长按检测
StopLongPressDetection();
2025-05-25 09:29:48 +08:00
}
2025-08-03 16:46:33 +08:00
private void GridPPTControlPrevious_MouseUp(object sender, MouseButtonEventArgs e)
{
2025-06-12 18:55:50 +08:00
if (lastBorderMouseDownObject != sender) return;
2025-08-03 16:46:33 +08:00
if (sender == PPTLSPreviousButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTLSPreviousButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTRSPreviousButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTRSPreviousButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTLBPreviousButtonBorder)
2025-06-12 18:55:50 +08:00
{
PPTLBPreviousButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRBPreviousButtonBorder)
{
PPTRBPreviousButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-08-23 19:43:09 +08:00
// 停止长按检测
StopLongPressDetection();
2025-06-12 18:55:50 +08:00
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
2025-05-25 09:29:48 +08:00
}
2025-08-03 16:46:33 +08:00
private void GridPPTControlNext_MouseDown(object sender, MouseButtonEventArgs e)
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = sender;
2025-08-03 16:46:33 +08:00
if (sender == PPTLSNextButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTLSNextButtonFeedbackBorder.Opacity = 0.15;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTRSNextButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTRSNextButtonFeedbackBorder.Opacity = 0.15;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTLBNextButtonBorder)
2025-06-12 18:55:50 +08:00
{
PPTLBNextButtonFeedbackBorder.Opacity = 0.15;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRBNextButtonBorder)
{
PPTRBNextButtonFeedbackBorder.Opacity = 0.15;
2025-05-25 09:29:48 +08:00
}
2025-08-23 19:43:09 +08:00
// 启动长按检测
if (Settings.PowerPointSettings.EnablePPTButtonLongPressPageTurn)
{
StartLongPressDetection(sender, true);
}
2025-05-25 09:29:48 +08:00
}
private void GridPPTControlNext_MouseLeave(object sender, MouseEventArgs e)
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = null;
2025-08-03 16:46:33 +08:00
if (sender == PPTLSNextButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTLSNextButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTRSNextButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTRSNextButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTLBNextButtonBorder)
2025-06-12 18:55:50 +08:00
{
PPTLBNextButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRBNextButtonBorder)
{
PPTRBNextButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-08-23 19:43:09 +08:00
// 停止长按检测
StopLongPressDetection();
2025-05-25 09:29:48 +08:00
}
2025-08-03 16:46:33 +08:00
private void GridPPTControlNext_MouseUp(object sender, MouseButtonEventArgs e)
{
2025-06-12 18:55:50 +08:00
if (lastBorderMouseDownObject != sender) return;
2025-08-03 16:46:33 +08:00
if (sender == PPTLSNextButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTLSNextButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTRSNextButtonBorder)
{
2025-06-12 18:55:50 +08:00
PPTRSNextButtonFeedbackBorder.Opacity = 0;
2025-08-03 16:46:33 +08:00
}
else if (sender == PPTLBNextButtonBorder)
2025-06-12 18:55:50 +08:00
{
PPTLBNextButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
else if (sender == PPTRBNextButtonBorder)
{
PPTRBNextButtonFeedbackBorder.Opacity = 0;
2025-05-25 09:29:48 +08:00
}
2025-08-23 19:43:09 +08:00
// 停止长按检测
StopLongPressDetection();
2025-06-12 18:55:50 +08:00
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
2025-05-25 09:29:48 +08:00
}
2025-08-03 16:46:33 +08:00
private void ImagePPTControlEnd_MouseUp(object sender, MouseButtonEventArgs e)
{
2025-06-12 18:55:50 +08:00
BtnPPTSlideShowEnd_Click(BtnPPTSlideShowEnd, null);
2025-06-10 11:09:51 +08:00
}
2025-05-25 09:29:48 +08:00
}
2025-07-12 09:09:20 +08:00
}