From 28fc53799a1188a677ca0934558378de17ae6510 Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Mon, 21 Jul 2025 20:30:07 +0800 Subject: [PATCH] fix:issue #92 #94 --- Ink Canvas/Helpers/ForegroundWindowInfo.cs | 124 ++-------- Ink Canvas/MainWindow_cs/MW_PPT.cs | 264 +++++++-------------- 2 files changed, 103 insertions(+), 285 deletions(-) diff --git a/Ink Canvas/Helpers/ForegroundWindowInfo.cs b/Ink Canvas/Helpers/ForegroundWindowInfo.cs index fd94c116..cd6d3c17 100644 --- a/Ink Canvas/Helpers/ForegroundWindowInfo.cs +++ b/Ink Canvas/Helpers/ForegroundWindowInfo.cs @@ -2,6 +2,8 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Text; +using System.Windows.Forms; +using System.Drawing; namespace Ink_Canvas.Helpers { @@ -23,44 +25,6 @@ namespace Ink_Canvas.Helpers [DllImport("user32.dll")] private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId); - [DllImport("shell32.dll")] - private static extern IntPtr SHAppBarMessage(uint dwMessage, ref APPBARDATA pData); - - [DllImport("user32.dll")] - private static extern int SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni); - - [DllImport("user32.dll")] - private static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFO lpmi); - - [DllImport("user32.dll")] - private static extern IntPtr MonitorFromWindow(IntPtr hwnd, uint dwFlags); - - private const uint ABM_GETTASKBARPOS = 0x00000005; - private const uint ABM_GETSTATE = 0x00000004; - private const int SPI_GETWORKAREA = 0x0030; - private const uint MONITOR_DEFAULTTOPRIMARY = 1; - private const int ABS_AUTOHIDE = 0x0000001; - - [StructLayout(LayoutKind.Sequential)] - private struct MONITORINFO - { - public int cbSize; - public RECT rcMonitor; - public RECT rcWork; - public uint dwFlags; - } - - [StructLayout(LayoutKind.Sequential)] - private struct APPBARDATA - { - public int cbSize; - public IntPtr hWnd; - public uint uCallbackMessage; - public uint uEdge; - public RECT rc; - public IntPtr lParam; - } - [StructLayout(LayoutKind.Sequential)] public struct RECT { public int Left; @@ -72,72 +36,6 @@ namespace Ink_Canvas.Helpers public int Height => Bottom - Top; } - /// - /// 获取Windows任务栏的高度(仅计算任务栏,不包括其他应用的停靠栏) - /// - /// 当前屏幕 - /// DPI缩放Y值 - /// 任务栏高度 - public static double GetTaskbarHeight(System.Windows.Forms.Screen screen, double dpiScaleY) - { - try - { - // 创建APPBARDATA结构 - var abd = new APPBARDATA(); - abd.cbSize = Marshal.SizeOf(abd); - - // 获取任务栏状态 - IntPtr state = SHAppBarMessage(ABM_GETSTATE, ref abd); - bool isAutoHide = (state.ToInt32() & ABS_AUTOHIDE) == ABS_AUTOHIDE; - - // 如果任务栏是自动隐藏的,返回0 - if (isAutoHide) - { - LogHelper.WriteLogToFile("任务栏处于自动隐藏状态", LogHelper.LogType.Info); - return 0; - } - - // 获取任务栏信息 - IntPtr result = SHAppBarMessage(ABM_GETTASKBARPOS, ref abd); - if (result != IntPtr.Zero) - { - RECT taskbarRect = abd.rc; - System.Drawing.Rectangle screenRect = screen.Bounds; - System.Drawing.Rectangle taskbarRectangle = new System.Drawing.Rectangle(taskbarRect.Left, taskbarRect.Top, taskbarRect.Width, taskbarRect.Height); - - // 根据任务栏位置计算高度 - int taskbarHeight = 0; - - // 任务栏的uEdge: 0=左, 1=上, 2=右, 3=下 - switch (abd.uEdge) - { - case 1: // 上 - taskbarHeight = abd.rc.Height; - break; - case 3: // 下 - taskbarHeight = abd.rc.Height; - break; - case 0: // 左 - case 2: // 右 - // 水平任务栏不影响高度 - taskbarHeight = 0; - break; - } - - // 考虑DPI缩放 - return taskbarHeight / dpiScaleY; - } - } - catch (Exception ex) - { - Debug.WriteLine($"获取任务栏高度出错: {ex.Message}"); - LogHelper.WriteLogToFile($"获取任务栏高度出错: {ex.Message}", LogHelper.LogType.Error); - } - - // 如果获取失败,回退到通用方法 - return (screen.Bounds.Height - screen.WorkingArea.Height) / dpiScaleY; - } - public static string WindowTitle() { IntPtr foregroundWindowHandle = GetForegroundWindow(); @@ -197,5 +95,23 @@ namespace Ink_Canvas.Helpers return "Unknown"; } } + + public static int GetTaskbarHeight(Screen screen, double dpiScaleY) + { + // 优先用工作区和屏幕区的差值法,兼容多屏 + int height = 0; + if (screen.Bounds.Height > screen.WorkingArea.Height) + { + // 任务栏在上下 + height = screen.Bounds.Height - screen.WorkingArea.Height; + } + else if (screen.Bounds.Width > screen.WorkingArea.Width) + { + // 任务栏在左右 + height = screen.Bounds.Width - screen.WorkingArea.Width; + } + // 考虑DPI缩放 + return (int)(height / dpiScaleY); + } } } \ No newline at end of file diff --git a/Ink Canvas/MainWindow_cs/MW_PPT.cs b/Ink Canvas/MainWindow_cs/MW_PPT.cs index 62003343..7820f421 100644 --- a/Ink Canvas/MainWindow_cs/MW_PPT.cs +++ b/Ink Canvas/MainWindow_cs/MW_PPT.cs @@ -949,41 +949,27 @@ namespace Ink_Canvas { LogHelper.WriteLogToFile("幻灯片放映窗口或视图为空", LogHelper.LogType.Warning); return; } - 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; + var ms = new MemoryStream(); + inkCanvas.Strokes.Save(ms); + ms.Position = 0; + if (previousSlideID > 0 && previousSlideID < memoryStreams.Length) 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) { - LogHelper.WriteLogToFile($"处理幻灯片切换时出错: {ex.ToString()}", LogHelper.LogType.Error); + ClearStrokes(true); + timeMachine.ClearStrokeHistory(); + int newPage = Wn.View.CurrentShowPosition; + if (newPage > 0 && newPage < memoryStreams.Length && + memoryStreams[newPage] != null && memoryStreams[newPage].Length > 0) { + memoryStreams[newPage].Position = 0; + inkCanvas.Strokes.Add(new StrokeCollection(memoryStreams[newPage])); } + PPTBtnPageNow.Text = $"{Wn.View.CurrentShowPosition}"; + PPTBtnPageTotal.Text = $"/ {Wn.Presentation.Slides.Count}"; + previousSlideID = newPage; // 最后赋值,确保索引同步 }); - - previousSlideID = Wn.View.CurrentShowPosition; } catch (Exception ex) { LogHelper.WriteLogToFile($"幻灯片切换事件处理失败: {ex.ToString()}", LogHelper.LogType.Error); @@ -993,179 +979,95 @@ namespace Ink_Canvas { private bool _isPptClickingBtnTurned = false; 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; - } - - // 切换前同步保存墨迹 Application.Current.Dispatcher.Invoke(() => { + // 切换前同步保存墨迹 SaveCurrentSlideInkStrokes(); - }); - - _isPptClickingBtnTurned = true; - - // 添加安全检查 - if (pptApplication == null) - { - LogHelper.WriteLogToFile("PPT应用程序为空,无法执行上一页操作", LogHelper.LogType.Warning); - return; - } - - try - { - // 检查SlideShowWindows是否存在且有效 - if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0) + _isPptClickingBtnTurned = true; + // 添加安全检查 + if (pptApplication == null) { - LogHelper.WriteLogToFile("PPT放映窗口不存在,无法执行上一页操作", LogHelper.LogType.Warning); + LogHelper.WriteLogToFile("PPT应用程序为空,无法执行上一页操作", LogHelper.LogType.Warning); return; } - - // 安全访问当前幻灯片信息 - if (pptApplication.SlideShowWindows.Count >= 1) + try { - var slideShowWindow = pptApplication.SlideShowWindows[1]; - if (slideShowWindow != null && slideShowWindow.View != null) + // 检查SlideShowWindows是否存在且有效 + if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0) { - if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber && - Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint) - SaveScreenShot(true, - slideShowWindow.Presentation.Name + "/" + - slideShowWindow.View.CurrentShowPosition); + 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); + slideShowWindow.Activate(); + slideShowWindow.View.Previous(); + } } } - - new Thread(new ThreadStart(() => { - try { - // 安全访问SlideShowWindows[1] - if (pptApplication.SlideShowWindows.Count >= 1) - { - var slideShowWindow = pptApplication.SlideShowWindows[1]; - if (slideShowWindow != null) - { - slideShowWindow.Activate(); - } - } - } - catch (Exception ex) { - LogHelper.WriteLogToFile($"激活PPT放映窗口失败: {ex.ToString()}", LogHelper.LogType.Error); - } - - try { - // 安全访问SlideShowWindows[1] - if (pptApplication.SlideShowWindows.Count >= 1) - { - var slideShowWindow = pptApplication.SlideShowWindows[1]; - if (slideShowWindow != null && slideShowWindow.View != null) - { - slideShowWindow.View.Previous(); - } - } - } - catch (Exception ex) { - LogHelper.WriteLogToFile($"PPT上一页操作失败: {ex.ToString()}", LogHelper.LogType.Error); - } // Without this catch{}, app will crash when click the pre-page button in the fir page in some special env. - })).Start(); - } - catch (Exception ex) { - LogHelper.WriteLogToFile($"PPT上一页操作异常: {ex.ToString()}", LogHelper.LogType.Error); - StackPanelPPTControls.Visibility = Visibility.Collapsed; - LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; - RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; - LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; - RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; - } + catch (Exception ex) { + LogHelper.WriteLogToFile($"PPT上一页操作异常: {ex.ToString()}", LogHelper.LogType.Error); + StackPanelPPTControls.Visibility = Visibility.Collapsed; + LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; + RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; + LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; + RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; + } + }); } private void BtnPPTSlidesDown_Click(object sender, RoutedEventArgs e) { - if (currentMode == 1) { - GridBackgroundCover.Visibility = Visibility.Collapsed; - AnimationsHelper.HideWithSlideAndFade(BlackboardLeftSide); - AnimationsHelper.HideWithSlideAndFade(BlackboardCenterSide); - AnimationsHelper.HideWithSlideAndFade(BlackboardRightSide); - currentMode = 0; - } - - // 切换前同步保存墨迹 Application.Current.Dispatcher.Invoke(() => { + // 切换前同步保存墨迹 SaveCurrentSlideInkStrokes(); - }); - - _isPptClickingBtnTurned = true; - - // 添加安全检查 - if (pptApplication == null) - { - LogHelper.WriteLogToFile("PPT应用程序为空,无法执行下一页操作", LogHelper.LogType.Warning); - return; - } - - try - { - // 检查SlideShowWindows是否存在且有效 - if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0) + _isPptClickingBtnTurned = true; + // 添加安全检查 + if (pptApplication == null) { - LogHelper.WriteLogToFile("PPT放映窗口不存在,无法执行下一页操作", LogHelper.LogType.Warning); + LogHelper.WriteLogToFile("PPT应用程序为空,无法执行下一页操作", LogHelper.LogType.Warning); return; } - - // 安全访问当前幻灯片信息 - if (pptApplication.SlideShowWindows.Count >= 1) + try { - var slideShowWindow = pptApplication.SlideShowWindows[1]; - if (slideShowWindow != null && slideShowWindow.View != null) + // 检查SlideShowWindows是否存在且有效 + if (pptApplication.SlideShowWindows == null || pptApplication.SlideShowWindows.Count == 0) { - if (inkCanvas.Strokes.Count > Settings.Automation.MinimumAutomationStrokeNumber && - Settings.PowerPointSettings.IsAutoSaveScreenShotInPowerPoint) - SaveScreenShot(true, - slideShowWindow.Presentation.Name + "/" + - slideShowWindow.View.CurrentShowPosition); + 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); + slideShowWindow.Activate(); + slideShowWindow.View.Next(); + } } } - - new Thread(new ThreadStart(() => { - try { - // 安全访问SlideShowWindows[1] - if (pptApplication.SlideShowWindows.Count >= 1) - { - var slideShowWindow = pptApplication.SlideShowWindows[1]; - if (slideShowWindow != null) - { - slideShowWindow.Activate(); - } - } - } - catch (Exception ex) { - LogHelper.WriteLogToFile($"激活PPT放映窗口失败: {ex.ToString()}", LogHelper.LogType.Error); - } - - try { - // 安全访问SlideShowWindows[1] - if (pptApplication.SlideShowWindows.Count >= 1) - { - var slideShowWindow = pptApplication.SlideShowWindows[1]; - if (slideShowWindow != null && slideShowWindow.View != null) - { - slideShowWindow.View.Next(); - } - } - } - catch (Exception ex) { - LogHelper.WriteLogToFile($"PPT下一页操作失败: {ex.ToString()}", LogHelper.LogType.Error); - } - })).Start(); - } - catch (Exception ex) { - LogHelper.WriteLogToFile($"PPT下一页操作异常: {ex.ToString()}", LogHelper.LogType.Error); - StackPanelPPTControls.Visibility = Visibility.Collapsed; - LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; - RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; - LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; - RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; - } + catch (Exception ex) { + LogHelper.WriteLogToFile($"PPT下一页操作异常: {ex.ToString()}", LogHelper.LogType.Error); + StackPanelPPTControls.Visibility = Visibility.Collapsed; + LeftBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; + RightBottomPanelForPPTNavigation.Visibility = Visibility.Collapsed; + LeftSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; + RightSidePanelForPPTNavigation.Visibility = Visibility.Collapsed; + } + }); } private async void PPTNavigationBtn_MouseDown(object sender, MouseButtonEventArgs e)