Compare commits

...

1 Commits

Author SHA1 Message Date
doudou0720 ab7905696d refactor(PPT)!: 重构PPT链接管理器,引入基类并优化代码结构
将ROTPPTManager重命名为ROTPPTLinkManager
新增BasePPTLinkManager抽象基类,提取公共逻辑
重构ComPPTLinkManager继承自基类,减少重复代码

Signed-off-by: doudou0720 <98651603+doudou0720@users.noreply.github.com>
2026-04-12 13:40:54 +08:00
4 changed files with 191 additions and 106 deletions
+117
View File
@@ -0,0 +1,117 @@
using System;
namespace Ink_Canvas.Helpers
{
public abstract class BasePPTLinkManager : IPPTLinkManager
{
#region IPPTLinkManager
public event Action<object> SlideShowBegin;
public event Action<object> SlideShowNextSlide;
public event Action<object> SlideShowEnd;
public event Action<object> PresentationOpen;
public event Action<object> PresentationClose;
public event Action<bool> PPTConnectionChanged;
public event Action<bool> SlideShowStateChanged;
#endregion
#region IPPTLinkManager
public virtual bool IsConnected => PPTApplication != null;
public virtual bool IsInSlideShow { get; protected set; }
public virtual bool IsSupportWPS { get; set; }
public virtual bool SkipAnimationsWhenNavigating { get; set; }
public virtual int SlidesCount { get; protected set; }
public abstract object PPTApplication { get; protected set; }
#endregion
#region
protected BasePPTLinkManager()
{
}
#endregion
#region
public abstract void StartMonitoring();
public abstract void StopMonitoring();
public virtual void ReloadConnection()
{
LogHelper.WriteLogToFile($"{GetType().Name} 执行热重载:强制断开并重新连接", LogHelper.LogType.Event);
StopMonitoring();
}
#endregion
#region
public abstract bool TryStartSlideShow();
public abstract bool TryEndSlideShow();
#endregion
#region
public abstract bool TryNavigateToSlide(int slideNumber);
public abstract bool TryNavigateNext();
public abstract bool TryNavigatePrevious();
#endregion
#region
public abstract int GetCurrentSlideNumber();
public abstract string GetPresentationName();
public abstract bool TryShowSlideNavigation();
public abstract object GetCurrentActivePresentation();
#endregion
#region
protected virtual void OnSlideShowBegin(object slideShowWindow)
{
SlideShowBegin?.Invoke(slideShowWindow);
}
protected virtual void OnSlideShowNextSlide(object slideShowWindow)
{
SlideShowNextSlide?.Invoke(slideShowWindow);
}
protected virtual void OnSlideShowEnd(object presentation)
{
SlideShowEnd?.Invoke(presentation);
}
protected virtual void OnPresentationOpen(object presentation)
{
PresentationOpen?.Invoke(presentation);
}
protected virtual void OnPresentationClose(object presentation)
{
PresentationClose?.Invoke(presentation);
}
protected virtual void OnPPTConnectionChanged(bool isConnected)
{
PPTConnectionChanged?.Invoke(isConnected);
}
protected virtual void OnSlideShowStateChanged(bool isInSlideShow)
{
SlideShowStateChanged?.Invoke(isInSlideShow);
}
#endregion
#region IDisposable
public virtual void Dispose()
{
StopMonitoring();
}
#endregion
}
}
+32 -50
View File
@@ -2,7 +2,7 @@ using System;
namespace Ink_Canvas.Helpers
{
public class ComPPTLinkManager : IPPTLinkManager
public class ComPPTLinkManager : BasePPTLinkManager
{
private readonly PPTManager _inner;
@@ -10,65 +10,47 @@ namespace Ink_Canvas.Helpers
{
_inner = new PPTManager();
_inner.SlideShowBegin += wn => SlideShowBegin?.Invoke(wn);
_inner.SlideShowNextSlide += wn => SlideShowNextSlide?.Invoke(wn);
_inner.SlideShowEnd += pres => SlideShowEnd?.Invoke(pres);
_inner.PresentationOpen += pres => PresentationOpen?.Invoke(pres);
_inner.PresentationClose += pres => PresentationClose?.Invoke(pres);
_inner.PPTConnectionChanged += connected => PPTConnectionChanged?.Invoke(connected);
_inner.SlideShowStateChanged += inSlideShow => SlideShowStateChanged?.Invoke(inSlideShow);
_inner.SlideShowBegin += wn => OnSlideShowBegin(wn);
_inner.SlideShowNextSlide += wn => OnSlideShowNextSlide(wn);
_inner.SlideShowEnd += pres => OnSlideShowEnd(pres);
_inner.PresentationOpen += pres => OnPresentationOpen(pres);
_inner.PresentationClose += pres => OnPresentationClose(pres);
_inner.PPTConnectionChanged += connected => OnPPTConnectionChanged(connected);
_inner.SlideShowStateChanged += inSlideShow => OnSlideShowStateChanged(inSlideShow);
}
#region IPPTLinkManager
public event Action<object> SlideShowBegin;
public event Action<object> SlideShowNextSlide;
public event Action<object> SlideShowEnd;
public event Action<object> PresentationOpen;
public event Action<object> PresentationClose;
public event Action<bool> PPTConnectionChanged;
public event Action<bool> SlideShowStateChanged;
#endregion
#region BasePPTLinkManager
public override bool IsConnected => _inner.IsConnected;
#region IPPTLinkManager
public bool IsConnected => _inner.IsConnected;
public override bool IsInSlideShow => _inner.IsInSlideShow;
public bool IsInSlideShow => _inner.IsInSlideShow;
public bool IsSupportWPS
public override bool IsSupportWPS
{
get => _inner.IsSupportWPS;
set => _inner.IsSupportWPS = value;
}
public bool SkipAnimationsWhenNavigating
public override bool SkipAnimationsWhenNavigating
{
get => _inner.SkipAnimationsWhenNavigating;
set => _inner.SkipAnimationsWhenNavigating = value;
}
public int SlidesCount => _inner.SlidesCount;
public override int SlidesCount => _inner.SlidesCount;
public object PPTApplication => _inner.PPTApplication;
public override object PPTApplication
{
get => _inner.PPTApplication;
protected set { }
}
#endregion
#region
/// <summary>
/// 开始监控本地 PowerPoint 的连接与运行状态,并在状态变化时触发相应事件。
/// </summary>
public void StartMonitoring() => _inner.StartMonitoring();
public override void StartMonitoring() => _inner.StartMonitoring();
/// <summary>
/// 停止对 PowerPoint 的监控,断开当前连接并停止触发相关事件。
/// </summary>
public void StopMonitoring() => _inner.StopMonitoring();
public override void StopMonitoring() => _inner.StopMonitoring();
/// <summary>
/// 强制断开当前 COM PPT 连接并停止对其监控,同时写入事件日志。
/// </summary>
/// <remarks>
/// 会向日志记录一条事件信息并调用内部管理器停止监控;该方法不会重新启动监控或重新初始化内部管理器实例。
/// </remarks>
public void ReloadConnection()
public override void ReloadConnection()
{
LogHelper.WriteLogToFile("COM PPT 执行热重载:强制断开并重新连接", LogHelper.LogType.Event);
_inner.StopMonitoring();
@@ -76,31 +58,31 @@ namespace Ink_Canvas.Helpers
#endregion
#region
public bool TryStartSlideShow() => _inner.TryStartSlideShow();
public override bool TryStartSlideShow() => _inner.TryStartSlideShow();
public bool TryEndSlideShow() => _inner.TryEndSlideShow();
public override bool TryEndSlideShow() => _inner.TryEndSlideShow();
#endregion
#region
public bool TryNavigateToSlide(int slideNumber) => _inner.TryNavigateToSlide(slideNumber);
public override bool TryNavigateToSlide(int slideNumber) => _inner.TryNavigateToSlide(slideNumber);
public bool TryNavigateNext() => _inner.TryNavigateNext();
public override bool TryNavigateNext() => _inner.TryNavigateNext();
public bool TryNavigatePrevious() => _inner.TryNavigatePrevious();
public override bool TryNavigatePrevious() => _inner.TryNavigatePrevious();
#endregion
#region
public int GetCurrentSlideNumber() => _inner.GetCurrentSlideNumber();
public override int GetCurrentSlideNumber() => _inner.GetCurrentSlideNumber();
public string GetPresentationName() => _inner.GetPresentationName();
public override string GetPresentationName() => _inner.GetPresentationName();
public bool TryShowSlideNavigation() => _inner.TryShowSlideNavigation();
public override bool TryShowSlideNavigation() => _inner.TryShowSlideNavigation();
public object GetCurrentActivePresentation() => _inner.GetCurrentActivePresentation();
public override object GetCurrentActivePresentation() => _inner.GetCurrentActivePresentation();
#endregion
#region IDisposable
public void Dispose()
public override void Dispose()
{
_inner?.Dispose();
}
@@ -11,25 +11,14 @@ using Timer = System.Timers.Timer;
namespace Ink_Canvas.Helpers
{
public class ROTPPTManager : IPPTLinkManager
public class ROTPPTLinkManager : BasePPTLinkManager
{
#region Events
public event Action<object> SlideShowBegin;
public event Action<object> SlideShowNextSlide;
public event Action<object> SlideShowEnd;
public event Action<object> PresentationOpen;
public event Action<object> PresentationClose;
public event Action<bool> PPTConnectionChanged;
public event Action<bool> SlideShowStateChanged;
#endregion
#region Properties
public dynamic PPTApplication { get; private set; }
public override dynamic PPTApplication { get; protected set; }
public dynamic CurrentPresentation { get; private set; }
public dynamic CurrentSlides { get; private set; }
public dynamic CurrentSlide { get; private set; }
public int SlidesCount { get; private set; }
public bool IsConnected
public override int SlidesCount { get; protected set; }
public override bool IsConnected
{
get
{
@@ -38,14 +27,12 @@ namespace Ink_Canvas.Helpers
if (PPTApplication == null) return false;
if (!Marshal.IsComObject(PPTApplication)) return false;
// 尝试访问一个简单的属性来验证连接是否有效
var _ = PPTApplication.Name;
return true;
}
catch (COMException comEx)
{
var hr = (uint)comEx.HResult;
// 如果COM对象已失效,返回false
if (hr == 0x8001010E || hr == 0x80004005 || hr == 0x800706B5)
{
return false;
@@ -58,7 +45,7 @@ namespace Ink_Canvas.Helpers
}
}
}
public bool IsInSlideShow
public override bool IsInSlideShow
{
get
{
@@ -119,9 +106,8 @@ namespace Ink_Canvas.Helpers
}
}
}
public bool IsSupportWPS { get; set; } = false;
public bool SkipAnimationsWhenNavigating { get; set; } = false;
#endregion
public override bool IsSupportWPS { get; set; } = false;
public override bool SkipAnimationsWhenNavigating { get; set; } = false;
#region Private Fields
private Thread _monitoringThread;
@@ -149,11 +135,11 @@ namespace Ink_Canvas.Helpers
#endregion
#region Constructor & Initialization
public ROTPPTManager()
public ROTPPTLinkManager()
{
}
public void StartMonitoring()
public override void StartMonitoring()
{
if (_disposed) return;
@@ -175,7 +161,7 @@ namespace Ink_Canvas.Helpers
}
}
public void StopMonitoring()
public override void StopMonitoring()
{
lock (_monitoringLock)
{
@@ -195,7 +181,7 @@ namespace Ink_Canvas.Helpers
}
}
public void ReloadConnection()
public override void ReloadConnection()
{
if (_disposed) return;
@@ -555,7 +541,7 @@ namespace Ink_Canvas.Helpers
{
try
{
SlideShowNextSlide?.Invoke(_pptSlideShowWindow);
OnSlideShowNextSlide(_pptSlideShowWindow);
}
catch (Exception ex)
{
@@ -586,7 +572,7 @@ namespace Ink_Canvas.Helpers
{
try
{
SlideShowNextSlide?.Invoke(_pptSlideShowWindow);
OnSlideShowNextSlide(_pptSlideShowWindow);
}
catch (Exception ex)
{
@@ -617,7 +603,7 @@ namespace Ink_Canvas.Helpers
SlidesCount = 0;
_lastSlideShowState = false;
SlideShowStateChanged?.Invoke(false);
OnSlideShowStateChanged(false);
if (_pptActivePresentation != null)
{
@@ -964,7 +950,7 @@ namespace Ink_Canvas.Helpers
try
{
LogHelper.WriteLogToFile($"轮询模式检测到页码变化: {_lastPolledSlideNumber} -> {currentPage},触发事件", LogHelper.LogType.Trace);
SlideShowNextSlide?.Invoke(_pptSlideShowWindow);
OnSlideShowNextSlide(_pptSlideShowWindow);
}
catch (Exception ex)
{
@@ -1008,7 +994,7 @@ namespace Ink_Canvas.Helpers
try
{
LogHelper.WriteLogToFile($"轮询模式检测到页码变化: {_lastPolledSlideNumber} -> {currentPage},触发事件", LogHelper.LogType.Trace);
SlideShowNextSlide?.Invoke(_pptSlideShowWindow);
OnSlideShowNextSlide(_pptSlideShowWindow);
}
catch (Exception ex)
{
@@ -1038,7 +1024,7 @@ namespace Ink_Canvas.Helpers
SlidesCount = 0;
_lastSlideShowState = false;
SlideShowStateChanged?.Invoke(false);
OnSlideShowStateChanged(false);
if (_pptActivePresentation != null)
{
@@ -1074,7 +1060,7 @@ namespace Ink_Canvas.Helpers
if (currentSlideShowState != _lastSlideShowState)
{
_lastSlideShowState = currentSlideShowState;
SlideShowStateChanged?.Invoke(currentSlideShowState);
OnSlideShowStateChanged(currentSlideShowState);
if (!currentSlideShowState)
{
@@ -1252,7 +1238,7 @@ namespace Ink_Canvas.Helpers
UpdateCurrentPresentationInfo();
}
PPTConnectionChanged?.Invoke(true);
OnPPTConnectionChanged(true);
try
{
@@ -1301,7 +1287,7 @@ namespace Ink_Canvas.Helpers
if (slideShowWindow == null)
return;
SlideShowBegin?.Invoke(slideShowWindow);
OnSlideShowBegin(slideShowWindow);
LogHelper.WriteLogToFile("检测到放映已在进行中,热重载", LogHelper.LogType.Trace);
}
catch (COMException comEx)
@@ -1374,7 +1360,7 @@ namespace Ink_Canvas.Helpers
{
try
{
PresentationClose?.Invoke(_pptActivePresentation);
OnPresentationClose(_pptActivePresentation);
}
catch (Exception ex)
{
@@ -1457,7 +1443,7 @@ namespace Ink_Canvas.Helpers
_forcePolling = true;
_bindingEvents = false;
PPTConnectionChanged?.Invoke(false);
OnPPTConnectionChanged(false);
LogHelper.WriteLogToFile("已断开PPT连接,并显式释放所有COM对象", LogHelper.LogType.Event);
@@ -1776,7 +1762,7 @@ namespace Ink_Canvas.Helpers
}
UpdateCurrentPresentationInfo();
PresentationOpen?.Invoke(pres);
OnPresentationOpen(pres);
LogHelper.WriteLogToFile($"演示文稿已打开: {pres?.Name}", LogHelper.LogType.Event);
}
catch (Exception ex)
@@ -1821,7 +1807,7 @@ namespace Ink_Canvas.Helpers
}
}
private void OnSlideShowBegin(object wn)
protected override void OnSlideShowBegin(object wn)
{
try
{
@@ -1854,10 +1840,10 @@ namespace Ink_Canvas.Helpers
if (!_lastSlideShowState)
{
_lastSlideShowState = true;
SlideShowStateChanged?.Invoke(true);
OnSlideShowStateChanged(true);
}
SlideShowBegin?.Invoke(wn);
base.OnSlideShowBegin(wn);
}
catch (Exception ex)
{
@@ -1890,7 +1876,7 @@ namespace Ink_Canvas.Helpers
}
UpdateCurrentPresentationInfo();
SlideShowNextSlide?.Invoke(wn);
base.OnSlideShowNextSlide(wn);
}
catch (Exception ex)
{
@@ -1898,7 +1884,7 @@ namespace Ink_Canvas.Helpers
}
}
private void OnSlideShowEnd(object pres)
protected override void OnSlideShowEnd(object pres)
{
try
{
@@ -1920,10 +1906,10 @@ namespace Ink_Canvas.Helpers
if (_lastSlideShowState)
{
_lastSlideShowState = false;
SlideShowStateChanged?.Invoke(false);
OnSlideShowStateChanged(false);
}
SlideShowEnd?.Invoke(pres);
base.OnSlideShowEnd(pres);
}
catch (Exception ex)
{
@@ -1938,7 +1924,7 @@ namespace Ink_Canvas.Helpers
#endregion
#region Public Methods
public bool TryNavigateToSlide(int slideNumber)
public override bool TryNavigateToSlide(int slideNumber)
{
object slideShowWindows = null;
object slideShowWindow = null;
@@ -2025,7 +2011,7 @@ namespace Ink_Canvas.Helpers
}
}
public bool TryNavigateNext()
public override bool TryNavigateNext()
{
try
{
@@ -2088,7 +2074,7 @@ namespace Ink_Canvas.Helpers
}
}
public bool TryNavigatePrevious()
public override bool TryNavigatePrevious()
{
try
{
@@ -2151,7 +2137,7 @@ namespace Ink_Canvas.Helpers
}
}
public bool TryEndSlideShow()
public override bool TryEndSlideShow()
{
object slideShowWindows = null;
object slideShowWindow = null;
@@ -2203,7 +2189,7 @@ namespace Ink_Canvas.Helpers
}
}
public bool TryStartSlideShow()
public override bool TryStartSlideShow()
{
try
{
@@ -2234,7 +2220,7 @@ namespace Ink_Canvas.Helpers
/// <summary>
/// 获取当前活跃的演示文稿
/// </summary>
public object GetCurrentActivePresentation()
public override object GetCurrentActivePresentation()
{
object slideShowWindows = null;
object slideShowWindow = null;
@@ -2412,7 +2398,7 @@ namespace Ink_Canvas.Helpers
}
}
public int GetCurrentSlideNumber()
public override int GetCurrentSlideNumber()
{
object activeWindow = null;
object selection = null;
@@ -2483,7 +2469,7 @@ namespace Ink_Canvas.Helpers
}
}
public string GetPresentationName()
public override string GetPresentationName()
{
try
{
@@ -2535,7 +2521,7 @@ namespace Ink_Canvas.Helpers
}
}
public bool TryShowSlideNavigation()
public override bool TryShowSlideNavigation()
{
object slideShowWindows = null;
object slideShowWindow = null;
@@ -3020,7 +3006,7 @@ namespace Ink_Canvas.Helpers
SlidesCount = 0;
StopWpsProcessCheckTimer();
PPTConnectionChanged?.Invoke(false);
OnPPTConnectionChanged(false);
LogHelper.WriteLogToFile("WPS进程结束后已清理所有COM对象并重启连接检查", LogHelper.LogType.Event);
}
@@ -3542,7 +3528,7 @@ namespace Ink_Canvas.Helpers
#endregion
#region Dispose
public void Dispose()
public override void Dispose()
{
if (!_disposed)
{
+1 -1
View File
@@ -248,7 +248,7 @@ namespace Ink_Canvas
// 根据设置选择 COM / ROT 架构
if (Settings.PowerPointSettings.UseRotPptLink)
{
_pptManager = new ROTPPTManager();
_pptManager = new ROTPPTLinkManager();
}
else
{