improve:PPT联动
This commit is contained in:
+461
-212
@@ -141,6 +141,15 @@ namespace Ink_Canvas.Helpers
|
|||||||
private bool _lastSlideShowState;
|
private bool _lastSlideShowState;
|
||||||
private readonly object _lockObject = new object();
|
private readonly object _lockObject = new object();
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
|
private Presentation _pptActivePresentation;
|
||||||
|
private SlideShowWindow _pptSlideShowWindow;
|
||||||
|
private int _polling = 0;
|
||||||
|
private bool _forcePolling = false;
|
||||||
|
private bool _bindingEvents = false;
|
||||||
|
private DateTime _updateTime;
|
||||||
|
private Thread _monitoringThread;
|
||||||
|
private bool _shouldStopMonitoring = false;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructor & Initialization
|
#region Constructor & Initialization
|
||||||
@@ -220,28 +229,53 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
if (_isModuleUnloading) return;
|
if (_isModuleUnloading) return;
|
||||||
|
|
||||||
// 尝试连接到PowerPoint
|
object bestApp = PPTROTConnectionHelper.GetAnyActivePowerPoint(PPTApplication, out int bestPriority, out int targetPriority);
|
||||||
var pptApp = TryConnectToPowerPoint();
|
bool needRebind = false;
|
||||||
if (pptApp == null && IsSupportWPS)
|
|
||||||
|
if (PPTApplication == null && bestApp != null)
|
||||||
{
|
{
|
||||||
// 如果PowerPoint连接失败且支持WPS,尝试连接WPS
|
needRebind = true;
|
||||||
pptApp = TryConnectToWPS();
|
}
|
||||||
|
else if (PPTApplication != null && bestApp != null && bestPriority > targetPriority)
|
||||||
|
{
|
||||||
|
if (!PPTROTConnectionHelper.AreComObjectsEqual(PPTApplication, bestApp))
|
||||||
|
{
|
||||||
|
needRebind = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pptApp != null && !IsConnected)
|
if (needRebind)
|
||||||
{
|
{
|
||||||
// 有可用的PPT/WPS应用程序且当前未连接,建立连接
|
bool wait = (PPTApplication != null);
|
||||||
ConnectToPPT(pptApp);
|
|
||||||
}
|
|
||||||
else if (pptApp == null && IsConnected)
|
|
||||||
{
|
|
||||||
// 没有可用的PPT/WPS应用程序但当前显示已连接,断开连接
|
|
||||||
DisconnectFromPPT();
|
DisconnectFromPPT();
|
||||||
|
|
||||||
|
if (bestApp != null)
|
||||||
|
{
|
||||||
|
if (wait) Thread.Sleep(1000);
|
||||||
|
|
||||||
|
Microsoft.Office.Interop.PowerPoint.Application pptApp = bestApp as Microsoft.Office.Interop.PowerPoint.Application;
|
||||||
|
if (pptApp != null)
|
||||||
|
{
|
||||||
|
ConnectToPPT(pptApp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PPTROTConnectionHelper.SafeReleaseComObject(bestApp);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (pptApp == null && PPTApplication != null)
|
else
|
||||||
{
|
{
|
||||||
// PPT/WPS应用程序不可用但PPTApplication对象仍存在,清理无效连接
|
if (bestApp != null && (PPTApplication == null || !PPTROTConnectionHelper.AreComObjectsEqual(PPTApplication, bestApp)))
|
||||||
DisconnectFromPPT();
|
{
|
||||||
|
PPTROTConnectionHelper.SafeReleaseComObject(bestApp);
|
||||||
|
bestApp = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PPTApplication != null && _pptActivePresentation != null)
|
||||||
|
{
|
||||||
|
CheckPresentationAndSlideShowState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -255,6 +289,150 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CheckPresentationAndSlideShowState()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Presentation activePresentation = null;
|
||||||
|
SlideShowWindow slideShowWindow = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
activePresentation = PPTApplication.ActivePresentation;
|
||||||
|
|
||||||
|
if (activePresentation != null && !PPTROTConnectionHelper.AreComObjectsEqual(_pptActivePresentation, activePresentation))
|
||||||
|
{
|
||||||
|
DisconnectFromPPT();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (COMException ex) when ((uint)ex.HResult == 0x8001010A)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("PowerPoint 忙,稍后重试", LogHelper.LogType.Trace);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"检查演示文稿状态失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
DisconnectFromPPT();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SafeReleaseComObject(activePresentation);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSlideShowActive = false;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
activePresentation = PPTApplication.ActivePresentation;
|
||||||
|
|
||||||
|
if (activePresentation != null && PPTROTConnectionHelper.GetSlideShowWindowsCount(PPTApplication) > 0)
|
||||||
|
{
|
||||||
|
isSlideShowActive = true;
|
||||||
|
|
||||||
|
slideShowWindow = activePresentation.SlideShowWindow;
|
||||||
|
if (_pptSlideShowWindow == null || !PPTROTConnectionHelper.IsValidSlideShowWindow(_pptSlideShowWindow))
|
||||||
|
{
|
||||||
|
if (!PPTROTConnectionHelper.AreComObjectsEqual(_pptSlideShowWindow, slideShowWindow))
|
||||||
|
{
|
||||||
|
SafeReleaseComObject(_pptSlideShowWindow);
|
||||||
|
_pptSlideShowWindow = slideShowWindow;
|
||||||
|
LogHelper.WriteLogToFile("发现窗口,成功设置 slideshowwindow", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (COMException ex) when ((uint)ex.HResult == 0x8001010A)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("PowerPoint 忙,稍后重试", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"发现窗口失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SafeReleaseComObject(activePresentation);
|
||||||
|
if (!PPTROTConnectionHelper.AreComObjectsEqual(_pptSlideShowWindow, slideShowWindow))
|
||||||
|
{
|
||||||
|
SafeReleaseComObject(slideShowWindow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSlideShowActive)
|
||||||
|
{
|
||||||
|
if ((DateTime.Now - _updateTime).TotalMilliseconds > 3000 || _forcePolling)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
slideShowWindow = _pptActivePresentation.SlideShowWindow;
|
||||||
|
|
||||||
|
int tempTotalPage = -1;
|
||||||
|
if (slideShowWindow != null)
|
||||||
|
{
|
||||||
|
tempTotalPage = GetTotalSlideIndex(_pptActivePresentation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tempTotalPage == -1)
|
||||||
|
{
|
||||||
|
SlidesCount = 0;
|
||||||
|
_polling = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int currentPage = GetCurrentSlideIndex(_pptSlideShowWindow);
|
||||||
|
SlidesCount = tempTotalPage;
|
||||||
|
if (currentPage >= tempTotalPage) _polling = 1;
|
||||||
|
else _polling = 0;
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
SlidesCount = 0;
|
||||||
|
_polling = 1;
|
||||||
|
LogHelper.WriteLogToFile($"获取当前页数失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
SlidesCount = 0;
|
||||||
|
LogHelper.WriteLogToFile($"获取总页数失败: {ex.Message}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SafeReleaseComObject(slideShowWindow);
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_polling != 0)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int currentPage = GetCurrentSlideIndex(_pptSlideShowWindow);
|
||||||
|
UpdateCurrentPresentationInfo();
|
||||||
|
_polling = 2;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SlidesCount = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"检查演示文稿和放映状态失败: {ex}", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void CheckSlideShowState()
|
private void CheckSlideShowState()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -279,38 +457,6 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Microsoft.Office.Interop.PowerPoint.Application TryConnectToPowerPoint()
|
private Microsoft.Office.Interop.PowerPoint.Application TryConnectToPowerPoint()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var pptApp = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("PowerPoint.Application");
|
|
||||||
|
|
||||||
if (pptApp != null && Marshal.IsComObject(pptApp))
|
|
||||||
{
|
|
||||||
var _ = pptApp.Name;
|
|
||||||
return pptApp;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (COMException ex)
|
|
||||||
{
|
|
||||||
var hr = (uint)ex.HResult;
|
|
||||||
if (hr == 0x800401E3 || hr == 0x800401F3 || hr == 0x800401E4)
|
|
||||||
{
|
|
||||||
return TryConnectToPowerPointViaROT();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (InvalidCastException)
|
|
||||||
{
|
|
||||||
return TryConnectToPowerPointViaROT();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Microsoft.Office.Interop.PowerPoint.Application TryConnectToPowerPointViaROT()
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -319,50 +465,12 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"ROT 备用方法连接异常: {ex}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"ROT连接PowerPoint异常: {ex}", LogHelper.LogType.Error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Microsoft.Office.Interop.PowerPoint.Application TryConnectToWPS()
|
private Microsoft.Office.Interop.PowerPoint.Application TryConnectToWPS()
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var wpsApp = (Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("kwpp.Application");
|
|
||||||
|
|
||||||
if (wpsApp != null && Marshal.IsComObject(wpsApp))
|
|
||||||
{
|
|
||||||
var _ = wpsApp.Name;
|
|
||||||
return wpsApp;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (COMException ex)
|
|
||||||
{
|
|
||||||
var hr = (uint)ex.HResult;
|
|
||||||
if (hr == 0x800401E3 || hr == 0x800401F3 || hr == 0x800401E4)
|
|
||||||
{
|
|
||||||
// WPS COM注册损坏,尝试使用ROT备用方法
|
|
||||||
return TryConnectToWPSViaROT();
|
|
||||||
}
|
|
||||||
if (hr != 0x80004005 && hr != 0x800706B5 && hr != 0x8001010E)
|
|
||||||
{
|
|
||||||
LogHelper.WriteLogToFile($"连接WPS失败: {ex}", LogHelper.LogType.Warning);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
catch (InvalidCastException)
|
|
||||||
{
|
|
||||||
// WPS COM对象类型转换失败,尝试使用ROT备用方法
|
|
||||||
return TryConnectToWPSViaROT();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Microsoft.Office.Interop.PowerPoint.Application TryConnectToWPSViaROT()
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -371,7 +479,7 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"ROT 备用方法连接 WPS 异常: {ex}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"ROT连接WPS异常: {ex}", LogHelper.LogType.Error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,44 +490,101 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
PPTApplication = pptApp;
|
PPTApplication = pptApp;
|
||||||
|
|
||||||
// 在主线程中注册事件,确保COM对象在正确的线程中
|
try
|
||||||
Application.Current?.Dispatcher?.Invoke(() =>
|
|
||||||
{
|
{
|
||||||
|
_pptActivePresentation = PPTApplication.ActivePresentation;
|
||||||
|
_updateTime = DateTime.Now;
|
||||||
|
|
||||||
|
int tempTotalPage = -1;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PPTApplication.PresentationOpen += OnPresentationOpen;
|
_pptSlideShowWindow = _pptActivePresentation.SlideShowWindow;
|
||||||
PPTApplication.PresentationClose += OnPresentationClose;
|
tempTotalPage = GetTotalSlideIndex(_pptActivePresentation);
|
||||||
PPTApplication.SlideShowBegin += OnSlideShowBegin;
|
}
|
||||||
PPTApplication.SlideShowNextSlide += OnSlideShowNextSlide;
|
catch
|
||||||
PPTApplication.SlideShowEnd += OnSlideShowEnd;
|
{
|
||||||
|
tempTotalPage = -1;
|
||||||
|
}
|
||||||
|
|
||||||
LogHelper.WriteLogToFile("PPT事件注册成功", LogHelper.LogType.Trace);
|
if (tempTotalPage == -1)
|
||||||
|
{
|
||||||
|
SlidesCount = 0;
|
||||||
|
_polling = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_pptSlideShowWindow != null)
|
||||||
|
{
|
||||||
|
int currentPage = GetCurrentSlideIndex(_pptSlideShowWindow);
|
||||||
|
SlidesCount = tempTotalPage;
|
||||||
|
if (currentPage >= tempTotalPage) _polling = 1;
|
||||||
|
else _polling = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SlidesCount = tempTotalPage;
|
||||||
|
_polling = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
SlidesCount = 0;
|
||||||
|
_polling = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Microsoft.Office.Interop.PowerPoint.Application app = PPTApplication as Microsoft.Office.Interop.PowerPoint.Application;
|
||||||
|
|
||||||
|
if (app != null)
|
||||||
|
{
|
||||||
|
app.SlideShowNextSlide += new EApplication_SlideShowNextSlideEventHandler(OnSlideShowNextSlide);
|
||||||
|
app.SlideShowBegin += new EApplication_SlideShowBeginEventHandler(OnSlideShowBegin);
|
||||||
|
app.SlideShowEnd += new EApplication_SlideShowEndEventHandler(OnSlideShowEnd);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
app.PresentationBeforeClose += new EApplication_PresentationBeforeCloseEventHandler(OnPresentationBeforeClose);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile("无法注册PresentationBeforeClose事件", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
|
|
||||||
|
_bindingEvents = true;
|
||||||
|
_forcePolling = false;
|
||||||
|
|
||||||
|
LogHelper.WriteLogToFile("PPT事件注册成功", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_bindingEvents = false;
|
||||||
|
_forcePolling = true;
|
||||||
|
LogHelper.WriteLogToFile("转换Application接口失败,无法注册事件", LogHelper.LogType.Warning);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"PPT事件注册失败: {ex}", LogHelper.LogType.Error);
|
_bindingEvents = false;
|
||||||
throw; // 重新抛出异常,让外层处理
|
_forcePolling = true;
|
||||||
|
LogHelper.WriteLogToFile($"无法注册事件: {ex.Message}", LogHelper.LogType.Warning);
|
||||||
}
|
}
|
||||||
}, DispatcherPriority.Normal, CancellationToken.None, TimeSpan.FromSeconds(2));
|
|
||||||
|
|
||||||
// 获取当前演示文稿信息
|
_bindingEvents = false;
|
||||||
UpdateCurrentPresentationInfo();
|
_forcePolling = true;
|
||||||
|
|
||||||
// 停止连接检查定时器
|
UpdateCurrentPresentationInfo();
|
||||||
_connectionCheckTimer?.Stop();
|
|
||||||
|
|
||||||
// 触发连接成功事件
|
PPTConnectionChanged?.Invoke(true);
|
||||||
PPTConnectionChanged?.Invoke(true);
|
|
||||||
|
|
||||||
LogHelper.WriteLogToFile("成功连接到PPT应用程序", LogHelper.LogType.Event);
|
LogHelper.WriteLogToFile($"成功绑定! {PPTApplication.Name}", LogHelper.LogType.Event);
|
||||||
|
|
||||||
if (IsInSlideShow)
|
|
||||||
{
|
|
||||||
OnSlideShowBegin(PPTApplication.SlideShowWindows[1]);
|
|
||||||
}
|
}
|
||||||
else if (CurrentPresentation != null)
|
catch
|
||||||
{
|
{
|
||||||
OnPresentationOpen(CurrentPresentation);
|
DisconnectFromPPT();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -429,87 +594,87 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisconnectFromPPT()
|
private void UnbindEvents()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (PPTApplication != null)
|
if (_bindingEvents && PPTApplication != null)
|
||||||
{
|
{
|
||||||
// 取消事件注册 - 使用更安全的方式
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 检查COM对象是否仍然有效
|
Microsoft.Office.Interop.PowerPoint.Application app = PPTApplication as Microsoft.Office.Interop.PowerPoint.Application;
|
||||||
if (Marshal.IsComObject(PPTApplication))
|
|
||||||
|
if (app != null)
|
||||||
{
|
{
|
||||||
// 尝试在主线程中取消事件注册
|
app.SlideShowNextSlide -= new EApplication_SlideShowNextSlideEventHandler(OnSlideShowNextSlide);
|
||||||
Application.Current?.Dispatcher?.Invoke(() =>
|
app.SlideShowBegin -= new EApplication_SlideShowBeginEventHandler(OnSlideShowBegin);
|
||||||
{
|
app.SlideShowEnd -= new EApplication_SlideShowEndEventHandler(OnSlideShowEnd);
|
||||||
try
|
app.PresentationBeforeClose -= new EApplication_PresentationBeforeCloseEventHandler(OnPresentationBeforeClose);
|
||||||
{
|
|
||||||
PPTApplication.PresentationOpen -= OnPresentationOpen;
|
|
||||||
PPTApplication.PresentationClose -= OnPresentationClose;
|
|
||||||
PPTApplication.SlideShowBegin -= OnSlideShowBegin;
|
|
||||||
PPTApplication.SlideShowNextSlide -= OnSlideShowNextSlide;
|
|
||||||
PPTApplication.SlideShowEnd -= OnSlideShowEnd;
|
|
||||||
}
|
|
||||||
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 ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"取消PPT事件注册失败: {ex}", LogHelper.LogType.Warning);
|
LogHelper.WriteLogToFile($"取消PPT事件注册失败: {ex.Message}", LogHelper.LogType.Trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeReleaseComObject(CurrentSlide, "CurrentSlide");
|
_bindingEvents = false;
|
||||||
SafeReleaseComObject(CurrentSlides, "CurrentSlides");
|
_forcePolling = false;
|
||||||
SafeReleaseComObject(CurrentPresentation, "CurrentPresentation");
|
}
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
if (PPTApplication != null && Marshal.IsComObject(PPTApplication))
|
private void DisconnectFromPPT()
|
||||||
|
{
|
||||||
|
if (PPTApplication == null && _pptActivePresentation == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UnbindEvents();
|
||||||
|
|
||||||
|
SafeReleaseComObject(_pptSlideShowWindow, "_pptSlideShowWindow");
|
||||||
|
SafeReleaseComObject(_pptActivePresentation, "_pptActivePresentation");
|
||||||
|
SafeReleaseComObject(CurrentSlide, "CurrentSlide");
|
||||||
|
SafeReleaseComObject(CurrentSlides, "CurrentSlides");
|
||||||
|
SafeReleaseComObject(CurrentPresentation, "CurrentPresentation");
|
||||||
|
|
||||||
|
if (PPTApplication != null && Marshal.IsComObject(PPTApplication))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Marshal.FinalReleaseComObject(PPTApplication);
|
||||||
|
}
|
||||||
|
catch
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Marshal.FinalReleaseComObject(PPTApplication);
|
int refCount = Marshal.ReleaseComObject(PPTApplication);
|
||||||
}
|
while (refCount > 0)
|
||||||
catch
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
int refCount = Marshal.ReleaseComObject(PPTApplication);
|
refCount = Marshal.ReleaseComObject(PPTApplication);
|
||||||
while (refCount > 0)
|
|
||||||
{
|
|
||||||
refCount = Marshal.ReleaseComObject(PPTApplication);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch { }
|
|
||||||
}
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PPTApplication = null;
|
PPTApplication = null;
|
||||||
|
_pptActivePresentation = null;
|
||||||
|
_pptSlideShowWindow = null;
|
||||||
CurrentPresentation = null;
|
CurrentPresentation = null;
|
||||||
CurrentSlides = null;
|
CurrentSlides = null;
|
||||||
CurrentSlide = null;
|
CurrentSlide = null;
|
||||||
SlidesCount = 0;
|
SlidesCount = 0;
|
||||||
|
_polling = 0;
|
||||||
|
_forcePolling = false;
|
||||||
|
_bindingEvents = false;
|
||||||
|
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
GC.WaitForPendingFinalizers();
|
GC.WaitForPendingFinalizers();
|
||||||
GC.Collect();
|
GC.Collect();
|
||||||
|
|
||||||
_isModuleUnloading = true;
|
|
||||||
_connectionCheckTimer?.Stop();
|
_connectionCheckTimer?.Stop();
|
||||||
_slideShowStateCheckTimer?.Stop();
|
_slideShowStateCheckTimer?.Stop();
|
||||||
|
|
||||||
@@ -588,9 +753,6 @@ namespace Ink_Canvas.Helpers
|
|||||||
|
|
||||||
private void UpdateCurrentPresentationInfo()
|
private void UpdateCurrentPresentationInfo()
|
||||||
{
|
{
|
||||||
object activePresentation = null;
|
|
||||||
object slideShowWindows = null;
|
|
||||||
object slideShowWindow = null;
|
|
||||||
object activeWindow = null;
|
object activeWindow = null;
|
||||||
object view = null;
|
object view = null;
|
||||||
object selection = null;
|
object selection = null;
|
||||||
@@ -602,11 +764,9 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
activePresentation = PPTApplication.ActivePresentation;
|
if (_pptActivePresentation != null)
|
||||||
if (activePresentation != null)
|
|
||||||
{
|
{
|
||||||
SafeReleaseComObject(CurrentPresentation, "CurrentPresentation");
|
CurrentPresentation = _pptActivePresentation;
|
||||||
CurrentPresentation = activePresentation as Presentation;
|
|
||||||
CurrentSlides = CurrentPresentation.Slides;
|
CurrentSlides = CurrentPresentation.Slides;
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -631,24 +791,18 @@ namespace Ink_Canvas.Helpers
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
slideShowWindows = PPTApplication.SlideShowWindows;
|
if (IsInSlideShow && _pptSlideShowWindow != null)
|
||||||
if (IsInSlideShow && slideShowWindows != null)
|
|
||||||
{
|
{
|
||||||
dynamic ssw = slideShowWindows;
|
try
|
||||||
if (ssw.Count > 0)
|
|
||||||
{
|
{
|
||||||
slideShowWindow = ssw[1];
|
view = _pptSlideShowWindow.View;
|
||||||
if (slideShowWindow != null)
|
if (view != null)
|
||||||
{
|
{
|
||||||
dynamic sswObj = slideShowWindow;
|
dynamic viewObj = view;
|
||||||
view = sswObj.View;
|
|
||||||
if (view != null)
|
|
||||||
{
|
|
||||||
dynamic viewObj = view;
|
|
||||||
CurrentSlide = viewObj.Slide as Slide;
|
CurrentSlide = viewObj.Slide as Slide;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch { }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -738,13 +892,7 @@ namespace Ink_Canvas.Helpers
|
|||||||
SafeReleaseComObject(slideRange);
|
SafeReleaseComObject(slideRange);
|
||||||
SafeReleaseComObject(selection);
|
SafeReleaseComObject(selection);
|
||||||
SafeReleaseComObject(view);
|
SafeReleaseComObject(view);
|
||||||
SafeReleaseComObject(slideShowWindow);
|
|
||||||
SafeReleaseComObject(activeWindow);
|
SafeReleaseComObject(activeWindow);
|
||||||
SafeReleaseComObject(slideShowWindows);
|
|
||||||
if (activePresentation != null && !ReferenceEquals(activePresentation, CurrentPresentation))
|
|
||||||
{
|
|
||||||
SafeReleaseComObject(activePresentation);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@@ -754,6 +902,16 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (PPTApplication != null && pres != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_pptActivePresentation = PPTApplication.ActivePresentation;
|
||||||
|
_updateTime = DateTime.Now;
|
||||||
|
}
|
||||||
|
catch { }
|
||||||
|
}
|
||||||
|
|
||||||
UpdateCurrentPresentationInfo();
|
UpdateCurrentPresentationInfo();
|
||||||
PresentationOpen?.Invoke(pres);
|
PresentationOpen?.Invoke(pres);
|
||||||
LogHelper.WriteLogToFile($"演示文稿已打开: {pres?.Name}", LogHelper.LogType.Event);
|
LogHelper.WriteLogToFile($"演示文稿已打开: {pres?.Name}", LogHelper.LogType.Event);
|
||||||
@@ -764,17 +922,40 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPresentationClose(Presentation pres)
|
private void OnPresentationBeforeClose(Presentation pres, ref bool cancel)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PresentationClose?.Invoke(pres);
|
LogHelper.WriteLogToFile("PresentationBeforeClose事件触发", LogHelper.LogType.Trace);
|
||||||
|
|
||||||
|
if (_bindingEvents && PPTApplication != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Microsoft.Office.Interop.PowerPoint.Application app = PPTApplication as Microsoft.Office.Interop.PowerPoint.Application;
|
||||||
|
|
||||||
|
if (app != null)
|
||||||
|
{
|
||||||
|
app.SlideShowNextSlide -= new EApplication_SlideShowNextSlideEventHandler(OnSlideShowNextSlide);
|
||||||
|
app.SlideShowBegin -= new EApplication_SlideShowBeginEventHandler(OnSlideShowBegin);
|
||||||
|
app.SlideShowEnd -= new EApplication_SlideShowEndEventHandler(OnSlideShowEnd);
|
||||||
|
app.PresentationBeforeClose -= new EApplication_PresentationBeforeCloseEventHandler(OnPresentationBeforeClose);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
LogHelper.WriteLogToFile($"取消PPT事件注册失败: {ex.Message}", LogHelper.LogType.Trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
_bindingEvents = false;
|
||||||
|
_forcePolling = false;
|
||||||
|
}
|
||||||
|
|
||||||
DisconnectFromPPT();
|
DisconnectFromPPT();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LogHelper.WriteLogToFile($"处理演示文稿关闭事件失败: {ex}", LogHelper.LogType.Error);
|
LogHelper.WriteLogToFile($"处理演示文稿关闭前事件失败: {ex}", LogHelper.LogType.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,6 +963,27 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_updateTime = DateTime.Now;
|
||||||
|
_pptSlideShowWindow = wn;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_pptActivePresentation != null)
|
||||||
|
{
|
||||||
|
int currentPage = GetCurrentSlideIndex(_pptSlideShowWindow);
|
||||||
|
int totalPage = GetTotalSlideIndex(_pptActivePresentation);
|
||||||
|
|
||||||
|
if (currentPage >= totalPage) _polling = 1;
|
||||||
|
else _polling = 0;
|
||||||
|
|
||||||
|
SlidesCount = totalPage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_polling = 1;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateCurrentPresentationInfo();
|
UpdateCurrentPresentationInfo();
|
||||||
SlideShowBegin?.Invoke(wn);
|
SlideShowBegin?.Invoke(wn);
|
||||||
}
|
}
|
||||||
@@ -795,6 +997,24 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_updateTime = DateTime.Now;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_pptActivePresentation != null && _pptSlideShowWindow != null)
|
||||||
|
{
|
||||||
|
int currentPage = GetCurrentSlideIndex(_pptSlideShowWindow);
|
||||||
|
int totalPage = GetTotalSlideIndex(_pptActivePresentation);
|
||||||
|
|
||||||
|
if (currentPage >= totalPage) _polling = 1;
|
||||||
|
else _polling = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_polling = 1;
|
||||||
|
}
|
||||||
|
|
||||||
UpdateCurrentPresentationInfo();
|
UpdateCurrentPresentationInfo();
|
||||||
SlideShowNextSlide?.Invoke(wn);
|
SlideShowNextSlide?.Invoke(wn);
|
||||||
}
|
}
|
||||||
@@ -808,12 +1028,16 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
_updateTime = DateTime.Now;
|
||||||
|
SlidesCount = 0;
|
||||||
|
|
||||||
// 记录WPS进程用于后续管理
|
// 记录WPS进程用于后续管理
|
||||||
if (IsSupportWPS && PPTApplication != null)
|
if (IsSupportWPS && PPTApplication != null)
|
||||||
{
|
{
|
||||||
RecordWpsProcessForManagement();
|
RecordWpsProcessForManagement();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateCurrentPresentationInfo();
|
||||||
SlideShowEnd?.Invoke(pres);
|
SlideShowEnd?.Invoke(pres);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -1211,11 +1435,49 @@ namespace Ink_Canvas.Helpers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前幻灯片编号
|
/// 获取当前幻灯片编号
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
private int GetCurrentSlideIndex(SlideShowWindow slideShowWindow)
|
||||||
|
{
|
||||||
|
object view = null;
|
||||||
|
object slide = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (slideShowWindow == null) return 0;
|
||||||
|
view = slideShowWindow.View;
|
||||||
|
if (view != null)
|
||||||
|
{
|
||||||
|
dynamic viewObj = view;
|
||||||
|
slide = viewObj.Slide;
|
||||||
|
if (slide != null)
|
||||||
|
{
|
||||||
|
dynamic slideObj = slide;
|
||||||
|
return slideObj.SlideIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SafeReleaseComObject(slide);
|
||||||
|
SafeReleaseComObject(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetTotalSlideIndex(Presentation presentation)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (presentation == null) return 0;
|
||||||
|
return presentation.Slides.Count;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public int GetCurrentSlideNumber()
|
public int GetCurrentSlideNumber()
|
||||||
{
|
{
|
||||||
object slideShowWindows = null;
|
|
||||||
object slideShowWindow = null;
|
|
||||||
object view = null;
|
|
||||||
object activeWindow = null;
|
object activeWindow = null;
|
||||||
object selection = null;
|
object selection = null;
|
||||||
object slideRange = null;
|
object slideRange = null;
|
||||||
@@ -1224,26 +1486,15 @@ namespace Ink_Canvas.Helpers
|
|||||||
if (!IsConnected || PPTApplication == null) return 0;
|
if (!IsConnected || PPTApplication == null) return 0;
|
||||||
if (!Marshal.IsComObject(PPTApplication)) return 0;
|
if (!Marshal.IsComObject(PPTApplication)) return 0;
|
||||||
|
|
||||||
if (IsInSlideShow)
|
if (IsInSlideShow && _pptSlideShowWindow != null)
|
||||||
{
|
{
|
||||||
slideShowWindows = PPTApplication.SlideShowWindows;
|
try
|
||||||
if (slideShowWindows != null)
|
|
||||||
{
|
{
|
||||||
dynamic ssw = slideShowWindows;
|
return GetCurrentSlideIndex(_pptSlideShowWindow);
|
||||||
if (ssw.Count > 0)
|
}
|
||||||
{
|
catch
|
||||||
slideShowWindow = ssw[1];
|
{
|
||||||
if (slideShowWindow != null)
|
return 0;
|
||||||
{
|
|
||||||
dynamic sswObj = slideShowWindow;
|
|
||||||
view = sswObj.View;
|
|
||||||
if (view != null)
|
|
||||||
{
|
|
||||||
dynamic viewObj = view;
|
|
||||||
return viewObj.CurrentShowPosition;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1292,9 +1543,6 @@ namespace Ink_Canvas.Helpers
|
|||||||
{
|
{
|
||||||
SafeReleaseComObject(slideRange);
|
SafeReleaseComObject(slideRange);
|
||||||
SafeReleaseComObject(selection);
|
SafeReleaseComObject(selection);
|
||||||
SafeReleaseComObject(view);
|
|
||||||
SafeReleaseComObject(slideShowWindow);
|
|
||||||
SafeReleaseComObject(slideShowWindows);
|
|
||||||
SafeReleaseComObject(activeWindow);
|
SafeReleaseComObject(activeWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2191,3 +2439,4 @@ namespace Ink_Canvas.Helpers
|
|||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ namespace Ink_Canvas.Helpers
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Private Methods
|
#region Public Methods
|
||||||
private static object GetAnyActivePowerPoint(object targetApp, out int bestPriority, out int targetPriority)
|
public static object GetAnyActivePowerPoint(object targetApp, out int bestPriority, out int targetPriority)
|
||||||
{
|
{
|
||||||
IRunningObjectTable rot = null;
|
IRunningObjectTable rot = null;
|
||||||
IEnumMoniker enumMoniker = null;
|
IEnumMoniker enumMoniker = null;
|
||||||
@@ -317,7 +317,7 @@ namespace Ink_Canvas.Helpers
|
|||||||
return bestApp;
|
return bestApp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool AreComObjectsEqual(object o1, object o2)
|
public static bool AreComObjectsEqual(object o1, object o2)
|
||||||
{
|
{
|
||||||
if (o1 == null || o2 == null) return false;
|
if (o1 == null || o2 == null) return false;
|
||||||
if (ReferenceEquals(o1, o2)) return true;
|
if (ReferenceEquals(o1, o2)) return true;
|
||||||
@@ -419,7 +419,7 @@ namespace Ink_Canvas.Helpers
|
|||||||
return hwnd;
|
return hwnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SafeReleaseComObject(object comObj)
|
public static void SafeReleaseComObject(object comObj)
|
||||||
{
|
{
|
||||||
if (comObj == null) return;
|
if (comObj == null) return;
|
||||||
|
|
||||||
@@ -442,6 +442,34 @@ namespace Ink_Canvas.Helpers
|
|||||||
if (bindCtx != null)
|
if (bindCtx != null)
|
||||||
Marshal.ReleaseComObject(bindCtx);
|
Marshal.ReleaseComObject(bindCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int GetSlideShowWindowsCount(Microsoft.Office.Interop.PowerPoint.Application pptApp)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (pptApp == null) return 0;
|
||||||
|
return pptApp.SlideShowWindows.Count;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool IsValidSlideShowWindow(SlideShowWindow pptSlideShowWindow)
|
||||||
|
{
|
||||||
|
if (pptSlideShowWindow == null) return false;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var _ = pptSlideShowWindow.Active;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user