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

1468 lines
72 KiB
C#
Raw Normal View History

2025-07-19 23:42:43 +08:00
using Ink_Canvas.Helpers;
2025-05-25 09:29:48 +08:00
using Microsoft.Office.Interop.PowerPoint;
using System;
2025-07-20 12:01:30 +08:00
using System.Diagnostics;
2025-05-25 09:29:48 +08:00
using System.IO;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using Application = System.Windows.Application;
using File = System.IO.File;
using MessageBox = System.Windows.MessageBox;
2025-07-19 23:42:43 +08:00
using iNKORE.UI.WPF.Modern;
using Microsoft.Office.Core;
2025-05-25 09:29:48 +08:00
namespace Ink_Canvas {
public partial class MainWindow : Window {
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")]
private static extern int GetWindowText(IntPtr hWnd, System.Text.StringBuilder lpString, int nMaxCount);
[DllImport("user32.dll")]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId, out uint lpdwThreadId);
private delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
2025-05-25 09:29:48 +08:00
public static Microsoft.Office.Interop.PowerPoint.Application pptApplication = null;
public static Presentation presentation = null;
public static Slides slides = null;
public static Slide slide = null;
public static int slidescount = 0;
private void BtnCheckPPT_Click(object sender, RoutedEventArgs e) {
try {
2025-07-19 23:42:43 +08:00
pptApplication =
(Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("kwpp.Application");
//pptApplication.SlideShowWindows[1].View.Next();
2025-06-07 10:50:21 +08:00
if (pptApplication != null) {
2025-06-08 23:47:27 +08:00
//获得演示文稿对象
2025-07-19 23:42:43 +08:00
presentation = pptApplication.ActivePresentation;
2025-06-07 10:50:21 +08:00
pptApplication.SlideShowBegin += PptApplication_SlideShowBegin;
pptApplication.SlideShowNextSlide += PptApplication_SlideShowNextSlide;
pptApplication.SlideShowEnd += PptApplication_SlideShowEnd;
// 获得幻灯片对象集合
slides = presentation.Slides;
// 获得幻灯片的数量
slidescount = slides.Count;
memoryStreams = new MemoryStream[slidescount + 2];
// 获得当前选中的幻灯片
try {
2025-07-19 23:42:43 +08:00
// 在普通视图下这种方式可以获得当前选中的幻灯片对象
// 然而在阅读模式下,这种方式会出现异常
2025-06-07 10:50:21 +08:00
slide = slides[pptApplication.ActiveWindow.Selection.SlideRange.SlideNumber];
}
catch {
2025-07-19 23:42:43 +08:00
// 在阅读模式下出现异常时,通过下面的方式来获得当前选中的幻灯片对象
2025-07-20 16:14:26 +08:00
try {
if (pptApplication.SlideShowWindows != null && pptApplication.SlideShowWindows.Count >= 1)
{
slide = pptApplication.SlideShowWindows[1].View.Slide;
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"获取当前幻灯片失败: {ex.ToString()}", LogHelper.LogType.Error);
}
2025-06-07 10:50:21 +08:00
}
2025-06-07 08:41:01 +08:00
}
2025-07-19 23:42:43 +08:00
2025-06-07 10:50:21 +08:00
if (pptApplication == null) throw new Exception();
2025-07-19 23:42:43 +08:00
//BtnCheckPPT.Visibility = Visibility.Collapsed;
2025-05-25 09:29:48 +08:00
StackPanelPPTControls.Visibility = Visibility.Visible;
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"检查PPT应用程序失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-07-19 23:42:43 +08:00
//BtnCheckPPT.Visibility = Visibility.Visible;
2025-05-25 09:29:48 +08:00
StackPanelPPTControls.Visibility = Visibility.Collapsed;
LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
MessageBox.Show("未找到幻灯片");
}
}
private void ToggleSwitchSupportWPS_Toggled(object sender, RoutedEventArgs e) {
if (!isLoaded) return;
Settings.PowerPointSettings.IsSupportWPS = ToggleSwitchSupportWPS.IsOn;
SaveSettingsToFile();
}
private static bool isWPSSupportOn => Settings.PowerPointSettings.IsSupportWPS;
public static bool IsShowingRestoreHiddenSlidesWindow = false;
private static bool IsShowingAutoplaySlidesWindow = false;
2025-07-20 12:36:21 +08:00
// WPP 相关变量
private static Process wppProcess = null;
private static bool hasWppProcessID = false;
private static System.Timers.Timer wppProcessCheckTimer = null;
2025-07-20 15:00:11 +08:00
private static DateTime wppProcessRecordTime = DateTime.MinValue; // 记录进程时间
private static int wppProcessCheckCount = 0; // 检查次数计数器
2025-07-20 12:01:30 +08:00
2025-06-08 19:37:15 +08:00
2025-07-19 23:42:43 +08:00
private void TimerCheckPPT_Elapsed(object sender, ElapsedEventArgs e) {
if (IsShowingRestoreHiddenSlidesWindow || IsShowingAutoplaySlidesWindow) return;
try {
2025-07-20 15:00:11 +08:00
2025-07-19 23:42:43 +08:00
pptApplication =
(Microsoft.Office.Interop.PowerPoint.Application)Marshal.GetActiveObject("PowerPoint.Application");
2025-05-25 09:29:48 +08:00
if (pptApplication != null) {
timerCheckPPT.Stop();
2025-06-08 23:47:27 +08:00
//获得演示文稿对象
2025-05-25 09:29:48 +08:00
presentation = pptApplication.ActivePresentation;
// 获得幻灯片对象集合
slides = presentation.Slides;
// 获得幻灯片的数量
slidescount = slides.Count;
memoryStreams = new MemoryStream[slidescount + 2];
// 获得当前选中的幻灯片
try {
// 在普通视图下这种方式可以获得当前选中的幻灯片对象
// 然而在阅读模式下,这种方式会出现异常
slide = slides[pptApplication.ActiveWindow.Selection.SlideRange.SlideNumber];
}
catch {
// 在阅读模式下出现异常时,通过下面的方式来获得当前选中的幻灯片对象
2025-07-20 16:14:26 +08:00
try {
if (pptApplication.SlideShowWindows != null && pptApplication.SlideShowWindows.Count >= 1)
{
slide = pptApplication.SlideShowWindows[1].View.Slide;
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"获取当前幻灯片失败: {ex.ToString()}", LogHelper.LogType.Error);
}
2025-05-25 09:29:48 +08:00
}
pptApplication.PresentationOpen += PptApplication_PresentationOpen;
pptApplication.PresentationClose += PptApplication_PresentationClose;
pptApplication.SlideShowBegin += PptApplication_SlideShowBegin;
pptApplication.SlideShowNextSlide += PptApplication_SlideShowNextSlide;
pptApplication.SlideShowEnd += PptApplication_SlideShowEnd;
}
if (pptApplication == null) return;
2025-07-19 23:42:43 +08:00
//BtnCheckPPT.Visibility = Visibility.Collapsed;
2025-05-25 09:29:48 +08:00
// 此处是已经开启了
2025-07-19 23:42:43 +08:00
PptApplication_PresentationOpen(null);
2025-05-25 09:29:48 +08:00
2025-06-08 23:47:27 +08:00
//如果检测到已经开始放映,则立即进入画板模式
2025-07-20 16:14:26 +08:00
if (pptApplication.SlideShowWindows != null && pptApplication.SlideShowWindows.Count >= 1)
{
try {
PptApplication_SlideShowBegin(pptApplication.SlideShowWindows[1]);
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"启动幻灯片放映失败: {ex.ToString()}", LogHelper.LogType.Error);
}
}
2025-05-25 09:29:48 +08:00
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"检查PPT状态失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-07-19 23:42:43 +08:00
//StackPanelPPTControls.Visibility = Visibility.Collapsed;
Application.Current.Dispatcher.Invoke(() => { BtnPPTSlideShow.Visibility = Visibility.Collapsed; });
timerCheckPPT.Start();
2025-05-25 09:29:48 +08:00
}
}
private void PptApplication_PresentationOpen(Presentation Pres) {
// 跳转到上次播放页
2025-07-19 23:42:43 +08:00
if (Settings.PowerPointSettings.IsNotifyPreviousPage)
Application.Current.Dispatcher.BeginInvoke(new Action(() => {
try {
2025-07-20 16:14:26 +08:00
// 添加安全检查
if (presentation == null)
{
LogHelper.WriteLogToFile("演示文稿为空,无法跳转到上次播放页", LogHelper.LogType.Warning);
return;
}
var folderPath = Settings.Automation.AutoSavedStrokesLocation +
@"\Auto Saved - Presentations\" + presentation.Name + "_" +
presentation.Slides.Count;
try {
if (!File.Exists(folderPath + "/Position")) return;
if (!int.TryParse(File.ReadAllText(folderPath + "/Position"), out var page)) return;
if (page <= 0) return;
new YesOrNoNotificationWindow($"上次播放到了第 {page} 页, 是否立即跳转", () => {
try {
if (pptApplication != null && pptApplication.SlideShowWindows != null && pptApplication.SlideShowWindows.Count >= 1)
// 如果已经播放了的话, 跳转
presentation.SlideShowWindow.View.GotoSlide(page);
else if (presentation.Windows != null && presentation.Windows.Count >= 1)
presentation.Windows[1].View.GotoSlide(page);
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"跳转到指定页面失败: {ex.ToString()}", LogHelper.LogType.Error);
}
}).ShowDialog();
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"读取上次播放位置失败: {ex.ToString()}", LogHelper.LogType.Error);
}
2025-07-19 23:42:43 +08:00
}
catch (Exception ex) {
2025-07-20 16:14:26 +08:00
LogHelper.WriteLogToFile($"处理上次播放页跳转失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-07-19 23:42:43 +08:00
}
}), DispatcherPriority.Normal);
2025-05-25 09:29:48 +08:00
//检查是否有隐藏幻灯片
if (Settings.PowerPointSettings.IsNotifyHiddenPage) {
2025-07-20 16:14:26 +08:00
try {
var isHaveHiddenSlide = false;
if (slides != null)
{
foreach (Slide slide in slides)
if (slide.SlideShowTransition.Hidden == Microsoft.Office.Core.MsoTriState.msoTrue) {
isHaveHiddenSlide = true;
break;
}
2025-05-25 09:29:48 +08:00
}
2025-07-20 16:14:26 +08:00
Application.Current.Dispatcher.BeginInvoke(new Action(() => {
if (isHaveHiddenSlide && !IsShowingRestoreHiddenSlidesWindow) {
IsShowingRestoreHiddenSlidesWindow = true;
new YesOrNoNotificationWindow("检测到此演示文档中包含隐藏的幻灯片,是否取消隐藏?",
() => {
try {
if (slides != null)
{
foreach (Slide slide in slides)
if (slide.SlideShowTransition.Hidden ==
Microsoft.Office.Core.MsoTriState.msoTrue)
slide.SlideShowTransition.Hidden =
Microsoft.Office.Core.MsoTriState.msoFalse;
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"取消隐藏幻灯片失败: {ex.ToString()}", LogHelper.LogType.Error);
}
finally {
IsShowingRestoreHiddenSlidesWindow = false;
}
}, () => { IsShowingRestoreHiddenSlidesWindow = false; },
() => { IsShowingRestoreHiddenSlidesWindow = false; }).ShowDialog();
}
BtnPPTSlideShow.Visibility = Visibility.Visible;
}), DispatcherPriority.Normal);
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"检查隐藏幻灯片失败: {ex.ToString()}", LogHelper.LogType.Error);
}
2025-05-25 09:29:48 +08:00
}
//检测是否有自动播放
if (Settings.PowerPointSettings.IsNotifyAutoPlayPresentation
2025-07-19 23:42:43 +08:00
// && presentation.SlideShowSettings.AdvanceMode == PpSlideShowAdvanceMode.ppSlideShowUseSlideTimings
2025-05-25 09:29:48 +08:00
&& BtnPPTSlideShowEnd.Visibility != Visibility.Visible) {
2025-07-20 16:14:26 +08:00
try {
bool hasSlideTimings = false;
if (presentation != null && presentation.Slides != null)
{
foreach (Slide slide in presentation.Slides) {
if (slide.SlideShowTransition.AdvanceOnTime == MsoTriState.msoTrue &&
slide.SlideShowTransition.AdvanceTime > 0) {
hasSlideTimings = true;
break;
}
}
2025-05-25 09:29:48 +08:00
}
2025-07-20 16:14:26 +08:00
if (hasSlideTimings) {
Application.Current.Dispatcher.BeginInvoke((Action)(() => {
if (hasSlideTimings && !IsShowingAutoplaySlidesWindow) {
IsShowingAutoplaySlidesWindow = true;
new YesOrNoNotificationWindow("检测到此演示文档中自动播放或排练计时已经启用,可能导致幻灯片自动翻页,是否取消?",
() => {
try {
if (presentation != null)
{
presentation.SlideShowSettings.AdvanceMode =
PpSlideShowAdvanceMode.ppSlideShowManualAdvance;
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"设置手动播放模式失败: {ex.ToString()}", LogHelper.LogType.Error);
}
finally {
IsShowingAutoplaySlidesWindow = false;
}
}, () => { IsShowingAutoplaySlidesWindow = false; },
() => { IsShowingAutoplaySlidesWindow = false; }).ShowDialog();
}
}));
try {
if (presentation != null)
{
presentation.SlideShowSettings.AdvanceMode = PpSlideShowAdvanceMode.ppSlideShowManualAdvance;
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"设置演示文稿播放模式失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
2025-07-20 16:14:26 +08:00
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"检查自动播放设置失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
}
private void PptApplication_PresentationClose(Presentation Pres) {
try {
pptApplication.PresentationOpen -= PptApplication_PresentationOpen;
pptApplication.PresentationClose -= PptApplication_PresentationClose;
pptApplication.SlideShowBegin -= PptApplication_SlideShowBegin;
pptApplication.SlideShowNextSlide -= PptApplication_SlideShowNextSlide;
pptApplication.SlideShowEnd -= PptApplication_SlideShowEnd;
timerCheckPPT.Start();
Application.Current.Dispatcher.Invoke(() => {
BtnPPTSlideShow.Visibility = Visibility.Collapsed;
BtnPPTSlideShowEnd.Visibility = Visibility.Collapsed;
});
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
}
private bool isPresentationHaveBlackSpace = false;
private string pptName = null;
private void UpdatePPTBtnStyleSettingsStatus() {
try {
var sopt = Settings.PowerPointSettings.PPTSButtonsOption.ToString();
char[] soptc = sopt.ToCharArray();
if (soptc[0] == '2')
{
PPTLSPageButton.Visibility = Visibility.Visible;
PPTRSPageButton.Visibility = Visibility.Visible;
}
else
{
PPTLSPageButton.Visibility = Visibility.Collapsed;
PPTRSPageButton.Visibility = Visibility.Collapsed;
}
if (soptc[2] == '2')
{
// 这里先堆一点屎山,没空用Resources了
PPTBtnLSBorder.Background = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTBtnRSBorder.Background = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTBtnLSBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(82, 82, 91));
PPTBtnRSBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(82, 82, 91));
PPTLSPreviousButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTRSPreviousButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTLSNextButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTRSNextButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTLSPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTRSPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTLSPageButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTRSPageButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTLSNextButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTRSNextButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
TextBlock.SetForeground(PPTLSPageButton, new SolidColorBrush(Colors.White));
TextBlock.SetForeground(PPTRSPageButton, new SolidColorBrush(Colors.White));
}
else
{
PPTBtnLSBorder.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
PPTBtnRSBorder.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
PPTBtnLSBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
PPTBtnRSBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
PPTLSPreviousButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTRSPreviousButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTLSNextButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTRSNextButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTLSPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTRSPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTLSPageButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTRSPageButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTLSNextButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTRSNextButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
TextBlock.SetForeground(PPTLSPageButton, new SolidColorBrush(Color.FromRgb(24, 24, 27)));
TextBlock.SetForeground(PPTRSPageButton, new SolidColorBrush(Color.FromRgb(24, 24, 27)));
}
if (soptc[1] == '2')
{
PPTBtnLSBorder.Opacity = 0.5;
PPTBtnRSBorder.Opacity = 0.5;
}
else
{
PPTBtnLSBorder.Opacity = 1;
PPTBtnRSBorder.Opacity = 1;
}
var bopt = Settings.PowerPointSettings.PPTBButtonsOption.ToString();
char[] boptc = bopt.ToCharArray();
if (boptc[0] == '2')
{
PPTLBPageButton.Visibility = Visibility.Visible;
PPTRBPageButton.Visibility = Visibility.Visible;
}
else
{
PPTLBPageButton.Visibility = Visibility.Collapsed;
PPTRBPageButton.Visibility = Visibility.Collapsed;
}
if (boptc[2] == '2')
{
// 这里先堆一点屎山,没空用Resources了
PPTBtnLBBorder.Background = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTBtnRBBorder.Background = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTBtnLBBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(82, 82, 91));
PPTBtnRBBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(82, 82, 91));
PPTLBPreviousButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTRBPreviousButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTLBNextButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTRBNextButtonGeometry.Brush = new SolidColorBrush(Colors.White);
PPTLBPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTRBPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTLBPageButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTRBPageButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTLBNextButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
PPTRBNextButtonFeedbackBorder.Background = new SolidColorBrush(Colors.White);
TextBlock.SetForeground(PPTLBPageButton, new SolidColorBrush(Colors.White));
TextBlock.SetForeground(PPTRBPageButton, new SolidColorBrush(Colors.White));
}
else
{
PPTBtnLBBorder.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
PPTBtnRBBorder.Background = new SolidColorBrush(Color.FromRgb(244, 244, 245));
PPTBtnLBBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
PPTBtnRBBorder.BorderBrush = new SolidColorBrush(Color.FromRgb(161, 161, 170));
PPTLBPreviousButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTRBPreviousButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTLBNextButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTRBNextButtonGeometry.Brush = new SolidColorBrush(Color.FromRgb(39, 39, 42));
PPTLBPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTRBPreviousButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTLBPageButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTRBPageButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTLBNextButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
PPTRBNextButtonFeedbackBorder.Background = new SolidColorBrush(Color.FromRgb(24, 24, 27));
TextBlock.SetForeground(PPTLBPageButton, new SolidColorBrush(Color.FromRgb(24, 24, 27)));
TextBlock.SetForeground(PPTRBPageButton, new SolidColorBrush(Color.FromRgb(24, 24, 27)));
}
if (boptc[1] == '2')
{
PPTBtnLBBorder.Opacity = 0.5;
PPTBtnRBBorder.Opacity = 0.5;
}
else
{
PPTBtnLBBorder.Opacity = 1;
PPTBtnRBBorder.Opacity = 1;
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
}
private void UpdatePPTBtnDisplaySettingsStatus() {
try {
2025-06-08 19:37:15 +08:00
// 检查是否应该显示PPT按钮
bool shouldShowButtons = Settings.PowerPointSettings.ShowPPTButton &&
(BtnPPTSlideShowEnd.Visibility == Visibility.Visible ||
2025-07-20 16:14:26 +08:00
(pptApplication != null && pptApplication.SlideShowWindows != null && pptApplication.SlideShowWindows.Count > 0));
2025-06-08 19:37:15 +08:00
if (!shouldShowButtons)
2025-05-25 09:29:48 +08:00
{
LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
return;
}
var lsp = Settings.PowerPointSettings.PPTLSButtonPosition;
LeftSidePanelForPPTNavigation.Margin = new Thickness(0, 0, 0, lsp*2);
var rsp = Settings.PowerPointSettings.PPTRSButtonPosition;
RightSidePanelForPPTNavigation.Margin = new Thickness(0, 0, 0, rsp*2);
var dopt = Settings.PowerPointSettings.PPTButtonsDisplayOption.ToString();
char[] doptc = dopt.ToCharArray();
if (doptc[0] == '2') AnimationsHelper.ShowWithFadeIn(LeftBottomPanelForPPTNavigation);
else LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
if (doptc[1] == '2') AnimationsHelper.ShowWithFadeIn(RightBottomPanelForPPTNavigation);
else RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
if (doptc[2] == '2') AnimationsHelper.ShowWithFadeIn(LeftSidePanelForPPTNavigation);
else LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
if (doptc[3] == '2') AnimationsHelper.ShowWithFadeIn(RightSidePanelForPPTNavigation);
else RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
}
catch (Exception ex) {
2025-07-20 16:14:26 +08:00
LogHelper.WriteLogToFile($"更新PPT按钮显示状态失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
private async void PptApplication_SlideShowBegin(SlideShowWindow Wn) {
try {
2025-06-09 08:41:23 +08:00
2025-05-25 09:29:48 +08:00
if (Settings.Automation.IsAutoFoldInPPTSlideShow && !isFloatingBarFolded)
await FoldFloatingBar(new object());
else if (isFloatingBarFolded) await UnFoldFloatingBar(new object());
isStopInkReplay = true;
LogHelper.WriteLogToFile("PowerPoint Application Slide Show Begin", LogHelper.LogType.Event);
await Application.Current.Dispatcher.InvokeAsync(() => {
//调整颜色
var screenRatio = SystemParameters.PrimaryScreenWidth / SystemParameters.PrimaryScreenHeight;
if (Math.Abs(screenRatio - 16.0 / 9) <= -0.01) {
if (Wn.Presentation.PageSetup.SlideWidth / Wn.Presentation.PageSetup.SlideHeight < 1.65) {
isPresentationHaveBlackSpace = true;
if (BtnSwitchTheme.Content.ToString() == "深色") {
//Light
BtnExit.Foreground = Brushes.White;
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark;
} else {
//Dark
}
}
} else if (screenRatio == -256 / 135) { }
lastDesktopInkColor = 1;
slidescount = Wn.Presentation.Slides.Count;
previousSlideID = 0;
memoryStreams = new MemoryStream[slidescount + 2];
pptName = Wn.Presentation.Name;
LogHelper.NewLog("Name: " + Wn.Presentation.Name);
LogHelper.NewLog("Slides Count: " + slidescount.ToString());
//检查是否有已有墨迹,并加载
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint)
2025-07-12 09:09:20 +08:00
if (Directory.Exists(Settings.Automation.AutoSavedStrokesLocation +
@"\Auto Saved - Presentations\" + Wn.Presentation.Name + "_" +
Wn.Presentation.Slides.Count)) {
2025-05-25 09:29:48 +08:00
LogHelper.WriteLogToFile("Found saved strokes", LogHelper.LogType.Trace);
2025-07-12 09:09:20 +08:00
var files = new DirectoryInfo(Settings.Automation.AutoSavedStrokesLocation +
@"\Auto Saved - Presentations\" + Wn.Presentation.Name + "_" +
Wn.Presentation.Slides.Count).GetFiles();
2025-05-25 09:29:48 +08:00
var count = 0;
foreach (var file in files)
if (file.Name != "Position") {
var i = -1;
try {
i = int.Parse(Path.GetFileNameWithoutExtension(file.Name));
memoryStreams[i] = new MemoryStream(File.ReadAllBytes(file.FullName));
memoryStreams[i].Position = 0;
count++;
}
catch (Exception ex) {
LogHelper.WriteLogToFile(
$"Failed to load strokes on Slide {i}\n{ex.ToString()}",
LogHelper.LogType.Error);
}
}
LogHelper.WriteLogToFile($"Loaded {count.ToString()} saved strokes");
}
StackPanelPPTControls.Visibility = Visibility.Visible;
UpdatePPTBtnDisplaySettingsStatus();
UpdatePPTBtnStyleSettingsStatus();
BtnPPTSlideShow.Visibility = Visibility.Collapsed;
BtnPPTSlideShowEnd.Visibility = Visibility.Visible;
ViewBoxStackPanelMain.Margin = new Thickness(10, 10, 10, 10);
ViewboxFloatingBar.Opacity = Settings.Appearance.ViewboxFloatingBarOpacityInPPTValue;
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow &&
!Settings.Automation.IsAutoFoldInPPTSlideShow &&
GridTransparencyFakeBackground.Background == Brushes.Transparent && !isFloatingBarFolded) {
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
}
if (currentMode != 0)
{
ImageBlackboard_MouseUp(null,null);
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
}
BorderFloatingBarMainControls.Visibility = Visibility.Visible;
if (Settings.PowerPointSettings.IsShowCanvasAtNewSlideShow &&
!Settings.Automation.IsAutoFoldInPPTSlideShow)
BtnColorRed_Click(null, null);
isEnteredSlideShowEndEvent = false;
PPTBtnPageNow.Text = $"{Wn.View.CurrentShowPosition}";
PPTBtnPageTotal.Text = $"/ {Wn.Presentation.Slides.Count}";
LogHelper.NewLog("PowerPoint Slide Show Loading process complete");
if (!isFloatingBarFolded) {
new Thread(new ThreadStart(() => {
Thread.Sleep(100);
Application.Current.Dispatcher.Invoke(() => {
ViewboxFloatingBarMarginAnimation(60);
});
})).Start();
}
});
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
}
private bool isEnteredSlideShowEndEvent = false; //防止重复调用本函数导致墨迹保存失效
private async void PptApplication_SlideShowEnd(Presentation Pres) {
try {
if (isFloatingBarFolded) await UnFoldFloatingBar(new object());
2025-07-20 12:36:21 +08:00
// 记录 WPP 进程 ID,用于后续检测未关闭的进程
if (pptApplication != null && pptApplication.Path.Contains("Kingsoft\\WPS Office\\"))
2025-07-20 12:01:30 +08:00
{
uint processId;
GetWindowThreadProcessId((IntPtr)pptApplication.HWND, out processId);
2025-07-20 12:36:21 +08:00
wppProcess = Process.GetProcessById((int)processId);
hasWppProcessID = true;
2025-07-20 15:00:11 +08:00
wppProcessRecordTime = DateTime.Now;
wppProcessCheckCount = 0;
2025-07-20 12:36:21 +08:00
LogHelper.WriteLogToFile($"记录 WPP 进程 ID: {processId}", LogHelper.LogType.Trace);
2025-07-20 12:19:32 +08:00
}
2025-07-20 12:01:30 +08:00
2025-05-25 09:29:48 +08:00
LogHelper.WriteLogToFile(string.Format("PowerPoint Slide Show End"), LogHelper.LogType.Event);
if (isEnteredSlideShowEndEvent) {
LogHelper.WriteLogToFile("Detected previous entrance, returning");
return;
}
isEnteredSlideShowEndEvent = true;
if (Settings.PowerPointSettings.IsAutoSaveStrokesInPowerPoint) {
2025-07-12 09:09:20 +08:00
var folderPath = Settings.Automation.AutoSavedStrokesLocation + @"\Auto Saved - Presentations\" +
Pres.Name + "_" + Pres.Slides.Count;
2025-05-25 09:29:48 +08:00
if (!Directory.Exists(folderPath)) Directory.CreateDirectory(folderPath);
try {
File.WriteAllText(folderPath + "/Position", previousSlideID.ToString());
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
for (var i = 1; i <= Pres.Slides.Count; i++)
if (memoryStreams[i] != null)
try {
if (memoryStreams[i].Length > 8) {
var srcBuf = new byte[memoryStreams[i].Length];
memoryStreams[i].Position = 0;
var byteLength = memoryStreams[i].Read(srcBuf, 0, srcBuf.Length);
2025-06-09 08:41:23 +08:00
// 使用Path.Combine构建文件路径
2025-07-12 09:09:20 +08:00
File.WriteAllBytes(folderPath + @"\" + i.ToString("0000") + ".icstk", srcBuf);
LogHelper.WriteLogToFile(string.Format(
"Saved strokes for Slide {0}, size={1}, byteLength={2}", i.ToString(),
memoryStreams[i].Length, byteLength));
2025-05-25 09:29:48 +08:00
} else {
2025-07-12 09:09:20 +08:00
if (File.Exists(folderPath + @"\" + i.ToString("0000") + ".icstk"))
File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
2025-05-25 09:29:48 +08:00
}
}
catch (Exception ex) {
2025-07-12 09:09:20 +08:00
LogHelper.WriteLogToFile(
$"Failed to save strokes for Slide {i}\n{ex.ToString()}",
LogHelper.LogType.Error);
if (File.Exists(folderPath + @"\" + i.ToString("0000") + ".icstk"))
File.Delete(folderPath + @"\" + i.ToString("0000") + ".icstk");
2025-05-25 09:29:48 +08:00
}
}
await Application.Current.Dispatcher.InvokeAsync(() => {
try {
isPresentationHaveBlackSpace = false;
if (BtnSwitchTheme.Content.ToString() == "深色") {
//Light
BtnExit.Foreground = Brushes.Black;
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Light;
} else {
//Dark
}
BtnPPTSlideShow.Visibility = Visibility.Visible;
BtnPPTSlideShowEnd.Visibility = Visibility.Collapsed;
StackPanelPPTControls.Visibility = Visibility.Collapsed;
LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
ViewBoxStackPanelMain.Margin = new Thickness(10, 10, 10, 55);
if (currentMode != 0) {
CloseWhiteboardImmediately();
currentMode = 0;
}
ClearStrokes(true);
if (GridTransparencyFakeBackground.Background != Brushes.Transparent)
BtnHideInkCanvas_Click(BtnHideInkCanvas, null);
ViewboxFloatingBar.Opacity = Settings.Appearance.ViewboxFloatingBarOpacityValue;
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
});
await Task.Delay(150);
2025-06-11 21:58:40 +08:00
await Application.Current.Dispatcher.InvokeAsync(() => {
2025-05-25 09:29:48 +08:00
ViewboxFloatingBarMarginAnimation(100, true);
});
2025-07-20 12:36:21 +08:00
// 启动 WPP 进程检测定时器
if (hasWppProcessID && wppProcess != null)
{
StartWppProcessCheckTimer();
}
2025-05-25 09:29:48 +08:00
}
catch (Exception ex) {
LogHelper.WriteLogToFile(ex.ToString(), LogHelper.LogType.Error);
}
}
private int previousSlideID = 0;
private MemoryStream[] memoryStreams = new MemoryStream[50];
private void PptApplication_SlideShowNextSlide(SlideShowWindow Wn) {
try {
2025-07-20 16:14:26 +08:00
// 添加安全检查
if (Wn == null || Wn.View == null)
{
LogHelper.WriteLogToFile("幻灯片放映窗口或视图为空", LogHelper.LogType.Warning);
return;
}
2025-05-25 09:29:48 +08:00
LogHelper.WriteLogToFile($"PowerPoint Next Slide (Slide {Wn.View.CurrentShowPosition})",
LogHelper.LogType.Event);
if (Wn.View.CurrentShowPosition == previousSlideID) return;
Application.Current.Dispatcher.Invoke(() => {
try {
var ms = new MemoryStream();
inkCanvas.Strokes.Save(ms);
ms.Position = 0;
memoryStreams[previousSlideID] = ms;
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint && !_isPptClickingBtnTurned)
SaveScreenShot(true, Wn.Presentation.Name + "/" + Wn.View.CurrentShowPosition);
_isPptClickingBtnTurned = false;
ClearStrokes(true);
timeMachine.ClearStrokeHistory();
if (memoryStreams[Wn.View.CurrentShowPosition] != null &&
memoryStreams[Wn.View.CurrentShowPosition].Length > 0) {
memoryStreams[Wn.View.CurrentShowPosition].Position = 0;
inkCanvas.Strokes.Add(new StrokeCollection(memoryStreams[Wn.View.CurrentShowPosition]));
}
PPTBtnPageNow.Text = $"{Wn.View.CurrentShowPosition}";
PPTBtnPageTotal.Text = $"/ {Wn.Presentation.Slides.Count}";
}
catch (Exception ex) {
2025-07-20 16:14:26 +08:00
LogHelper.WriteLogToFile($"处理幻灯片切换时出错: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
});
previousSlideID = Wn.View.CurrentShowPosition;
}
catch (Exception ex) {
2025-07-20 16:14:26 +08:00
LogHelper.WriteLogToFile($"幻灯片切换事件处理失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
private bool _isPptClickingBtnTurned = false;
2025-06-12 18:55:50 +08:00
private void BtnPPTSlidesUp_Click(object sender, RoutedEventArgs e) {
if (currentMode == 1) {
GridBackgroundCover.Visibility = Visibility.Collapsed;
AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide);
currentMode = 0;
}
2025-05-25 09:29:48 +08:00
2025-06-12 18:55:50 +08:00
_isPptClickingBtnTurned = true;
2025-05-25 09:29:48 +08:00
2025-07-20 16:14:26 +08:00
// 添加安全检查
if (pptApplication == null)
{
LogHelper.WriteLogToFile("PPT应用程序为空,无法执行上一页操作", LogHelper.LogType.Warning);
return;
}
try
{
// 检查SlideShowWindows是否存在且有效
if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0)
{
LogHelper.WriteLogToFile("PPT放映窗口不存在,无法执行上一页操作", LogHelper.LogType.Warning);
return;
}
// 安全访问当前幻灯片信息
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null && slideShowWindow.View != null)
{
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
SaveScreenShot(true,
slideShowWindow.Presentation.Name + "/" +
slideShowWindow.View.CurrentShowPosition);
}
}
2025-05-25 09:29:48 +08:00
new Thread(new ThreadStart(() => {
try {
2025-07-20 16:14:26 +08:00
// 安全访问SlideShowWindows[1]
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null)
{
slideShowWindow.Activate();
}
}
2025-05-25 09:29:48 +08:00
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"激活PPT放映窗口失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
2025-06-12 18:55:50 +08:00
try {
2025-07-20 16:14:26 +08:00
// 安全访问SlideShowWindows[1]
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null && slideShowWindow.View != null)
{
slideShowWindow.View.Previous();
}
}
2025-06-12 18:55:50 +08:00
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"PPT上一页操作失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-06-12 18:55:50 +08:00
} // Without this catch{}, app will crash when click the pre-page button in the fir page in some special env.
2025-05-25 09:29:48 +08:00
})).Start();
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"PPT上一页操作异常: {ex.ToString()}", LogHelper.LogType.Error);
2025-06-12 18:55:50 +08:00
StackPanelPPTControls.Visibility = Visibility.Collapsed;
LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
2025-05-25 09:29:48 +08:00
}
}
private void BtnPPTSlidesDown_Click(object sender, RoutedEventArgs e) {
2025-06-12 18:55:50 +08:00
if (currentMode == 1) {
GridBackgroundCover.Visibility = Visibility.Collapsed;
AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide);
AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide);
currentMode = 0;
}
2025-05-25 09:29:48 +08:00
2025-06-12 18:55:50 +08:00
_isPptClickingBtnTurned = true;
2025-07-20 16:14:26 +08:00
// 添加安全检查
if (pptApplication == null)
{
LogHelper.WriteLogToFile("PPT应用程序为空,无法执行下一页操作", LogHelper.LogType.Warning);
return;
}
try
{
// 检查SlideShowWindows是否存在且有效
if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0)
{
LogHelper.WriteLogToFile("PPT放映窗口不存在,无法执行下一页操作", LogHelper.LogType.Warning);
return;
}
// 安全访问当前幻灯片信息
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null && slideShowWindow.View != null)
{
if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber &&
Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint)
SaveScreenShot(true,
slideShowWindow.Presentation.Name + "/" +
slideShowWindow.View.CurrentShowPosition);
}
}
2025-05-25 09:29:48 +08:00
new Thread(new ThreadStart(() => {
try {
2025-07-20 16:14:26 +08:00
// 安全访问SlideShowWindows[1]
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null)
{
slideShowWindow.Activate();
}
}
2025-06-12 18:55:50 +08:00
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"激活PPT放映窗口失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-06-12 18:55:50 +08:00
}
try {
2025-07-20 16:14:26 +08:00
// 安全访问SlideShowWindows[1]
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null && slideShowWindow.View != null)
{
slideShowWindow.View.Next();
}
}
2025-05-25 09:29:48 +08:00
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"PPT下一页操作失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
})).Start();
}
2025-07-20 16:14:26 +08:00
catch (Exception ex) {
LogHelper.WriteLogToFile($"PPT下一页操作异常: {ex.ToString()}", LogHelper.LogType.Error);
2025-06-12 18:55:50 +08:00
StackPanelPPTControls.Visibility = Visibility.Collapsed;
LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed;
LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed;
2025-05-25 09:29:48 +08:00
}
}
2025-06-12 18:55:50 +08:00
private async 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-06-12 18:55:50 +08:00
private async 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-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-20 16:14:26 +08:00
// 添加安全检查
if (pptApplication == null)
{
LogHelper.WriteLogToFile("PPT应用程序为空,无法执行翻页操作", LogHelper.LogType.Warning);
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
{
// 检查SlideShowWindows是否存在且有效
if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0)
{
LogHelper.WriteLogToFile("PPT放映窗口不存在,无法执行翻页操作", LogHelper.LogType.Warning);
return;
}
GridTransparencyFakeBackground.Opacity = 1;
GridTransparencyFakeBackground.Background = new SolidColorBrush(StringToColor("#01FFFFFF"));
CursorIcon_Click(null, null);
try {
// 安全访问SlideShowWindows[1]
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null)
{
slideShowWindow.SlideNavigation.Visible = true;
}
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"设置PPT导航可见性失败: {ex.ToString()}", LogHelper.LogType.Error);
}
// 控制居中
if (!isFloatingBarFolded) {
await Task.Delay(100);
ViewboxFloatingBarMarginAnimation(60);
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"PPT翻页控件操作失败: {ex.ToString()}", LogHelper.LogType.Error);
2025-05-25 09:29:48 +08:00
}
}
private void BtnPPTSlideShow_Click(object sender, RoutedEventArgs e) {
2025-06-12 18:55:50 +08:00
new Thread(new ThreadStart(() => {
try {
presentation.SlideShowSettings.Run();
}
catch { }
})).Start();
2025-05-25 09:29:48 +08:00
}
2025-06-08 23:47:27 +08:00
private async void BtnPPTSlideShowEnd_Click(object sender, RoutedEventArgs e) {
2025-07-20 16:14:26 +08:00
// 添加安全检查
if (pptApplication == null)
{
LogHelper.WriteLogToFile("PPT应用程序为空,无法结束放映", LogHelper.LogType.Warning);
return;
}
try
{
// 检查SlideShowWindows是否存在且有效
if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0)
{
LogHelper.WriteLogToFile("PPT放映窗口不存在,无法结束放映", LogHelper.LogType.Warning);
return;
2025-06-12 18:55:50 +08:00
}
2025-06-08 23:47:27 +08:00
2025-07-20 16:14:26 +08:00
Application.Current.Dispatcher.Invoke(() => {
try {
// 安全访问SlideShowWindows[1]
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null && slideShowWindow.View != null)
{
var ms = new MemoryStream();
inkCanvas.Strokes.Save(ms);
ms.Position = 0;
memoryStreams[slideShowWindow.View.CurrentShowPosition] = ms;
timeMachine.ClearStrokeHistory();
}
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"保存当前页面墨迹失败: {ex.ToString()}", LogHelper.LogType.Error);
}
});
new Thread(new ThreadStart(() => {
try {
// 安全访问SlideShowWindows[1]
if (pptApplication.SlideShowWindows.Count >= 1)
{
var slideShowWindow = pptApplication.SlideShowWindows[1];
if (slideShowWindow != null && slideShowWindow.View != null)
{
slideShowWindow.View.Exit();
}
}
}
catch (Exception ex) {
LogHelper.WriteLogToFile($"退出PPT放映失败: {ex.ToString()}", LogHelper.LogType.Error);
}
})).Start();
HideSubPanels("cursor");
await Task.Delay(150);
ViewboxFloatingBarMarginAnimation(100, true);
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"结束PPT放映操作异常: {ex.ToString()}", LogHelper.LogType.Error);
}
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;
if (sender == PPTLSPreviousButtonBorder) {
PPTLSPreviousButtonFeedbackBorder.Opacity = 0.15;
} else if (sender == PPTRSPreviousButtonBorder) {
PPTRSPreviousButtonFeedbackBorder.Opacity = 0.15;
} else if (sender == PPTLBPreviousButtonBorder)
{
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
}
}
private void GridPPTControlPrevious_MouseLeave(object sender, MouseEventArgs e)
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = null;
if (sender == PPTLSPreviousButtonBorder) {
PPTLSPreviousButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTRSPreviousButtonBorder) {
PPTRSPreviousButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTLBPreviousButtonBorder)
{
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
}
}
private void GridPPTControlPrevious_MouseUp(object sender, MouseButtonEventArgs e) {
2025-06-12 18:55:50 +08:00
if (lastBorderMouseDownObject != sender) return;
if (sender == PPTLSPreviousButtonBorder) {
PPTLSPreviousButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTRSPreviousButtonBorder) {
PPTRSPreviousButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTLBPreviousButtonBorder)
{
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-06-12 18:55:50 +08:00
BtnPPTSlidesUp_Click(BtnPPTSlidesUp, null);
2025-05-25 09:29:48 +08:00
}
private void GridPPTControlNext_MouseDown(object sender, MouseButtonEventArgs e) {
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = sender;
if (sender == PPTLSNextButtonBorder) {
PPTLSNextButtonFeedbackBorder.Opacity = 0.15;
} else if (sender == PPTRSNextButtonBorder) {
PPTRSNextButtonFeedbackBorder.Opacity = 0.15;
} else if (sender == PPTLBNextButtonBorder)
{
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
}
}
private void GridPPTControlNext_MouseLeave(object sender, MouseEventArgs e)
{
2025-06-12 18:55:50 +08:00
lastBorderMouseDownObject = null;
if (sender == PPTLSNextButtonBorder) {
PPTLSNextButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTRSNextButtonBorder) {
PPTRSNextButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTLBNextButtonBorder)
{
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
}
}
private void GridPPTControlNext_MouseUp(object sender, MouseButtonEventArgs e) {
2025-06-12 18:55:50 +08:00
if (lastBorderMouseDownObject != sender) return;
if (sender == PPTLSNextButtonBorder) {
PPTLSNextButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTRSNextButtonBorder) {
PPTRSNextButtonFeedbackBorder.Opacity = 0;
} else if (sender == PPTLBNextButtonBorder)
{
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-06-12 18:55:50 +08:00
BtnPPTSlidesDown_Click(BtnPPTSlidesDown, null);
2025-05-25 09:29:48 +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-07-20 12:36:21 +08:00
private void StartWppProcessCheckTimer()
{
if (wppProcessCheckTimer != null)
{
wppProcessCheckTimer.Stop();
wppProcessCheckTimer.Dispose();
}
wppProcessCheckTimer = new System.Timers.Timer(2000); // 2秒检查一次
wppProcessCheckTimer.Elapsed += WppProcessCheckTimer_Elapsed;
wppProcessCheckTimer.Start();
LogHelper.WriteLogToFile("启动 WPP 进程检测定时器", LogHelper.LogType.Trace);
}
private void WppProcessCheckTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
try
{
if (wppProcess == null || hasWppProcessID == false)
{
StopWppProcessCheckTimer();
return;
}
// 刷新进程状态
wppProcess.Refresh();
2025-07-20 15:00:11 +08:00
wppProcessCheckCount++;
2025-07-20 12:36:21 +08:00
if (wppProcess.HasExited)
{
LogHelper.WriteLogToFile("WPP 进程已正常关闭", LogHelper.LogType.Trace);
StopWppProcessCheckTimer();
}
else
{
2025-07-20 15:00:11 +08:00
// 检查是否有其他WPS窗口打开
bool hasOtherWpsWindows = CheckForOtherWpsWindows();
if (hasOtherWpsWindows)
{
LogHelper.WriteLogToFile("检测到其他WPS窗口打开,停止强制关闭进程", LogHelper.LogType.Trace);
StopWppProcessCheckTimer();
return;
}
// 计算从记录进程开始的时间
var timeSinceRecord = DateTime.Now - wppProcessRecordTime;
2025-07-20 12:36:21 +08:00
2025-07-20 17:20:33 +08:00
// 更保守的关闭策略:只有在超过0.5秒且检查次数超过2次时才强制关闭
if (timeSinceRecord.TotalSeconds > 0.5 && wppProcessCheckCount >= 2)
2025-07-20 12:36:21 +08:00
{
2025-07-20 15:00:11 +08:00
LogHelper.WriteLogToFile($"检测到长时间未关闭的 WPP 进程(已运行{timeSinceRecord.TotalSeconds:F1}秒,检查{wppProcessCheckCount}次),开始强制关闭", LogHelper.LogType.Event);
2025-07-20 12:36:21 +08:00
wppProcess.Kill();
LogHelper.WriteLogToFile("强制关闭 WPP 进程成功", LogHelper.LogType.Event);
StopWppProcessCheckTimer();
}
2025-07-20 15:00:11 +08:00
else
{
LogHelper.WriteLogToFile($"WPP 进程仍在运行,已检查{wppProcessCheckCount}次,运行时间{timeSinceRecord.TotalSeconds:F1}秒", LogHelper.LogType.Trace);
}
2025-07-20 12:36:21 +08:00
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"WPP 进程检测失败: {ex.ToString()}", LogHelper.LogType.Error);
StopWppProcessCheckTimer();
}
}
2025-07-20 15:00:11 +08:00
private bool CheckForOtherWpsWindows()
{
try
{
// 检查是否有其他WPS窗口打开
var wpsProcesses = Process.GetProcessesByName("wpp");
if (wpsProcesses.Length > 1)
{
LogHelper.WriteLogToFile($"检测到{wpsProcesses.Length}个WPP进程", LogHelper.LogType.Trace);
return true;
}
// 检查是否有WPS相关的其他进程
var kingsoftProcesses = Process.GetProcessesByName("wps");
if (kingsoftProcesses.Length > 0)
{
LogHelper.WriteLogToFile("检测到WPS主程序进程", LogHelper.LogType.Trace);
return true;
}
// 检查是否有其他WPS相关进程
var etProcesses = Process.GetProcessesByName("et"); // WPS表格
var wpsProcesses2 = Process.GetProcessesByName("wps"); // WPS文字
if (etProcesses.Length > 0 || wpsProcesses2.Length > 0)
{
LogHelper.WriteLogToFile($"检测到其他WPS组件进程:ET进程{etProcesses.Length}个,WPS进程{wpsProcesses2.Length}个", LogHelper.LogType.Trace);
return true;
}
// 检查当前WPP进程是否有多个窗口
if (wppProcess != null)
{
try
{
var windowCount = 0;
foreach (ProcessThread thread in wppProcess.Threads)
{
// 简单检查是否有多个窗口句柄
if (thread.ThreadState == System.Diagnostics.ThreadState.Running)
{
windowCount++;
}
}
if (windowCount > 1)
{
LogHelper.WriteLogToFile($"当前WPP进程有{windowCount}个活动线程,可能存在多个窗口", LogHelper.LogType.Trace);
return true;
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"检查WPP进程窗口失败: {ex.ToString()}", LogHelper.LogType.Error);
}
}
// 通过枚举窗口检查是否有其他WPS窗口
return CheckForWpsWindowsByEnumeration();
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"检查其他WPS窗口失败: {ex.ToString()}", LogHelper.LogType.Error);
return false; // 出错时保守处理,不强制关闭
}
}
private bool CheckForWpsWindowsByEnumeration()
{
try
{
var wpsWindowCount = 0;
var currentProcessId = wppProcess?.Id ?? 0;
EnumWindows((IntPtr hWnd, IntPtr lParam) =>
{
try
{
uint windowProcessId;
GetWindowThreadProcessId(hWnd, out windowProcessId);
// 检查是否是WPP进程的窗口
if (windowProcessId == currentProcessId)
{
var windowTitle = new System.Text.StringBuilder(256);
GetWindowText(hWnd, windowTitle, 256);
var title = windowTitle.ToString().Trim();
// 检查窗口标题是否包含WPS相关标识
if (!string.IsNullOrEmpty(title) &&
(title.Contains("WPS") || title.Contains("演示文稿") || title.Contains(".ppt") || title.Contains(".pptx")))
{
wpsWindowCount++;
LogHelper.WriteLogToFile($"发现WPS窗口: {title}", LogHelper.LogType.Trace);
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"枚举窗口时出错: {ex.ToString()}", LogHelper.LogType.Error);
}
return true; // 继续枚举
}, IntPtr.Zero);
if (wpsWindowCount > 1)
{
LogHelper.WriteLogToFile($"检测到{wpsWindowCount}个WPS窗口,可能存在多个文档", LogHelper.LogType.Trace);
return true;
}
return false;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"通过枚举检查WPS窗口失败: {ex.ToString()}", LogHelper.LogType.Error);
return false;
}
}
2025-07-20 12:36:21 +08:00
private void StopWppProcessCheckTimer()
{
if (wppProcessCheckTimer != null)
{
wppProcessCheckTimer.Stop();
wppProcessCheckTimer.Dispose();
wppProcessCheckTimer = null;
}
wppProcess = null;
hasWppProcessID = false;
2025-07-20 15:00:11 +08:00
wppProcessRecordTime = DateTime.MinValue;
wppProcessCheckCount = 0;
2025-07-20 12:36:21 +08:00
LogHelper.WriteLogToFile("停止 WPP 进程检测定时器", LogHelper.LogType.Trace);
}
2025-05-25 09:29:48 +08:00
}
2025-07-12 09:09:20 +08:00
}