From 00554e066b8203e7db60b7d484ea34527a00511e Mon Sep 17 00:00:00 2001 From: CJKmkp <2564608840@qq.com> Date: Wed, 30 Jul 2025 19:56:22 +0800 Subject: [PATCH] =?UTF-8?q?add:=E6=88=AA=E5=9B=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Ink Canvas/MainWindow.xaml | 93 +++++- Ink Canvas/MainWindow.xaml.cs | 8 + .../MainWindow_cs/MW_ClipboardHandler.cs | 267 ++++++++++++++++++ .../MainWindow_cs/MW_FloatingBarIcons.cs | 69 ++++- Ink Canvas/MainWindow_cs/MW_Screenshot.cs | 90 +++++- 5 files changed, 522 insertions(+), 5 deletions(-) create mode 100644 Ink Canvas/MainWindow_cs/MW_ClipboardHandler.cs diff --git a/Ink Canvas/MainWindow.xaml b/Ink Canvas/MainWindow.xaml index 13acc9ef..19b38b3f 100644 --- a/Ink Canvas/MainWindow.xaml +++ b/Ink Canvas/MainWindow.xaml @@ -60,6 +60,7 @@ + @@ -148,6 +149,7 @@ + @@ -175,6 +177,8 @@ Executed="KeyHide" /> + @@ -4916,7 +4920,7 @@ @@ -5244,6 +5248,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + { + ShowNotification("检测到剪贴板中有图片,右键点击白板可粘贴"); + }); + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"显示粘贴提示失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 处理右键菜单显示 + private void ShowPasteContextMenu(Point position) + { + try + { + if (!Clipboard.ContainsImage()) return; + + // 创建右键菜单 + var contextMenu = new ContextMenu(); + + var pasteMenuItem = new MenuItem + { + Header = "粘贴图片" + }; + + pasteMenuItem.Click += async (s, e) => await PasteImageFromClipboard(position); + contextMenu.Items.Add(pasteMenuItem); + + // 显示菜单 + contextMenu.IsOpen = true; + contextMenu.PlacementTarget = inkCanvas; + contextMenu.Placement = System.Windows.Controls.Primitives.PlacementMode.MousePoint; + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"显示粘贴菜单失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 从剪贴板粘贴图片 + private async Task PasteImageFromClipboard(Point? position = null) + { + try + { + if (!Clipboard.ContainsImage()) + { + ShowNotification("剪贴板中没有图片"); + return; + } + + var clipboardImage = Clipboard.GetImage(); + if (clipboardImage == null) + { + ShowNotification("无法获取剪贴板图片"); + return; + } + + // 创建Image控件 + var image = new Image + { + Source = clipboardImage, + Width = clipboardImage.PixelWidth, + Height = clipboardImage.PixelHeight, + Stretch = System.Windows.Media.Stretch.Fill + }; + + // 生成唯一名称 + string timestamp = "img_clipboard_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff"); + image.Name = timestamp; + + // 设置位置 + if (position.HasValue) + { + // 在指定位置居中显示 + InkCanvas.SetLeft(image, position.Value.X - image.Width / 2); + InkCanvas.SetTop(image, position.Value.Y - image.Height / 2); + } + else + { + // 使用与文件选择相同的居中和缩放逻辑 + CenterAndScaleElement(image); + } + + // 添加到画布 + inkCanvas.Children.Add(image); + + // 添加鼠标事件处理 + image.MouseDown += UIElement_MouseDown; + image.IsManipulationEnabled = true; + + // 提交到历史记录 + timeMachine.CommitElementInsertHistory(image); + + ShowNotification("图片已从剪贴板粘贴"); + } + catch (Exception ex) + { + ShowNotification($"粘贴图片失败: {ex.Message}"); + LogHelper.WriteLogToFile($"粘贴图片失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + + + // 处理白板右键事件 + private void InkCanvas_MouseRightButtonUp(object sender, MouseButtonEventArgs e) + { + try + { + // 只在白板模式下处理 + if (currentMode != 1) return; + + // 检查是否有图片在剪贴板中 + if (Clipboard.ContainsImage()) + { + var position = e.GetPosition(inkCanvas); + ShowPasteContextMenu(position); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"处理右键事件失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 处理全局粘贴快捷键 + private async void HandleGlobalPaste(object sender, ExecutedRoutedEventArgs e) + { + try + { + // 只在白板模式下处理 + if (currentMode != 1) return; + + if (Clipboard.ContainsImage()) + { + await PasteImageFromClipboard(); + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"处理全局粘贴失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 清理剪贴板监控 + private void CleanupClipboardMonitoring() + { + try + { + if (isClipboardMonitoringEnabled) + { + ClipboardNotification.ClipboardUpdate -= OnClipboardUpdate; + isClipboardMonitoringEnabled = false; + } + } + catch (Exception ex) + { + LogHelper.WriteLogToFile($"清理剪贴板监控失败: {ex.Message}", LogHelper.LogType.Error); + } + } + } + + // 剪贴板通知类 + public static class ClipboardNotification + { + public static event Action ClipboardUpdate; + + private static System.Windows.Forms.Timer clipboardTimer; + private static string lastClipboardText = ""; + private static bool lastHadImage = false; + + static ClipboardNotification() + { + clipboardTimer = new System.Windows.Forms.Timer(); + clipboardTimer.Interval = 500; // 每500ms检查一次 + clipboardTimer.Tick += CheckClipboard; + clipboardTimer.Start(); + } + + private static void CheckClipboard(object sender, EventArgs e) + { + try + { + bool currentHasImage = Clipboard.ContainsImage(); + string currentText = Clipboard.ContainsText() ? Clipboard.GetText() : ""; + + if (currentHasImage != lastHadImage || currentText != lastClipboardText) + { + lastHadImage = currentHasImage; + lastClipboardText = currentText; + ClipboardUpdate?.Invoke(); + } + } + catch + { + // 忽略剪贴板访问错误 + } + } + + public static void Stop() + { + clipboardTimer?.Stop(); + clipboardTimer?.Dispose(); + } + } +} diff --git a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs index 500039ce..9a7194bb 100644 --- a/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs +++ b/Ink Canvas/MainWindow_cs/MW_FloatingBarIcons.cs @@ -208,6 +208,7 @@ namespace Ink_Canvas { BorderSettings.Visibility = Visibility.Collapsed; BoardBorderLeftPageListView.Visibility = Visibility.Collapsed; BoardBorderRightPageListView.Visibility = Visibility.Collapsed; + BoardImageOptionsPanel.Visibility = Visibility.Collapsed; } /// @@ -279,7 +280,8 @@ namespace Ink_Canvas { AnimationsHelper.HideWithSlideAndFade(BorderDrawShape); AnimationsHelper.HideWithSlideAndFade(BoardBorderLeftPageListView); AnimationsHelper.HideWithSlideAndFade(BoardBorderRightPageListView); - + AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel); + // 隐藏背景设置面板 var bgPalette = LogicalTreeHelper.FindLogicalNode(this, "BackgroundPalette") as Border; if (bgPalette != null) @@ -2065,6 +2067,71 @@ namespace Ink_Canvas { #endregion + private void InsertImageOptions_MouseUp(object sender, MouseButtonEventArgs e) + { + // Hide other sub-panels first + HideSubPanelsImmediately(); + + // Show the image options panel + if (BoardImageOptionsPanel.Visibility == Visibility.Collapsed) + { + AnimationsHelper.ShowWithSlideFromBottomAndFade(BoardImageOptionsPanel); + } + else + { + AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel); + } + } + + private void CloseImageOptionsPanel_MouseUp(object sender, MouseButtonEventArgs e) + { + AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel); + } + + private async void ImageOptionScreenshot_MouseUp(object sender, MouseButtonEventArgs e) + { + // Hide the options panel + AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel); + + // Wait a bit for the panel to hide + await Task.Delay(100); + + // Capture screenshot and copy to clipboard + await CaptureScreenshotToClipboard(); + } + + private async void ImageOptionSelectFile_MouseUp(object sender, MouseButtonEventArgs e) + { + // Hide the options panel + AnimationsHelper.HideWithSlideAndFade(BoardImageOptionsPanel); + + // Open file dialog to select image + var dialog = new OpenFileDialog + { + Filter = "图片文件|*.jpg;*.jpeg;*.png;*.bmp;*.gif" + }; + if (dialog.ShowDialog() == true) + { + string filePath = dialog.FileName; + Image image = await CreateAndCompressImageAsync(filePath); + if (image != null) + { + string timestamp = "img_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff"); + image.Name = timestamp; + + CenterAndScaleElement(image); + inkCanvas.Children.Add(image); + + // 添加鼠标事件处理,使图片可以被选择 + image.MouseDown += UIElement_MouseDown; + image.IsManipulationEnabled = true; + + timeMachine.CommitElementInsertHistory(image); + } + } + } + + // Keep the old method for backward compatibility private async void InsertImage_MouseUp(object sender, MouseButtonEventArgs e) { var dialog = new OpenFileDialog diff --git a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs index 43e93d76..4f76e6bf 100644 --- a/Ink Canvas/MainWindow_cs/MW_Screenshot.cs +++ b/Ink Canvas/MainWindow_cs/MW_Screenshot.cs @@ -2,8 +2,12 @@ using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; +using System.Threading.Tasks; using System.Windows; using System.Windows.Forms; +using System.Windows.Media.Imaging; +using Ink_Canvas.Helpers; +using Clipboard = System.Windows.Clipboard; namespace Ink_Canvas { public partial class MainWindow : Window { @@ -71,14 +75,94 @@ namespace Ink_Canvas { private string GetDefaultFolderPath() { var basePath = Settings.Automation.AutoSavedStrokesLocation; var screenshotsFolder = Path.Combine(basePath, "Auto Saved - Screenshots"); - + if (!Directory.Exists(screenshotsFolder)) { Directory.CreateDirectory(screenshotsFolder); } - + return Path.Combine( - screenshotsFolder, + screenshotsFolder, $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.png"); } + + // 截图并复制到剪贴板 + private async Task CaptureScreenshotToClipboard() { + try { + // 隐藏主窗口以避免截图包含窗口本身 + var originalVisibility = this.Visibility; + this.Visibility = Visibility.Hidden; + + // 等待窗口隐藏 + await Task.Delay(200); + + var rc = SystemInformation.VirtualScreen; + using (var bitmap = new Bitmap(rc.Width, rc.Height, PixelFormat.Format32bppArgb)) + using (var memoryGraphics = Graphics.FromImage(bitmap)) { + memoryGraphics.CopyFromScreen(rc.X, rc.Y, 0, 0, rc.Size, CopyPixelOperation.SourceCopy); + + // 将截图复制到剪贴板 + CopyBitmapToClipboard(bitmap); + + // 恢复窗口显示 + this.Visibility = originalVisibility; + + // 等待窗口完全显示后自动粘贴 + await Task.Delay(100); + await AutoPasteScreenshot(); + } + } + catch (Exception ex) { + ShowNotification($"截图失败: {ex.Message}"); + this.Visibility = Visibility.Visible; + } + } + + // 自动粘贴截图到画布 + private async Task AutoPasteScreenshot() { + try { + // 只在白板模式下自动粘贴 + if (currentMode == 1) { + await PasteImageFromClipboard(); + ShowNotification("截图已自动插入到画布"); + } else { + ShowNotification("截图已复制到剪贴板,可在白板模式下粘贴"); + } + } + catch (Exception ex) { + ShowNotification($"自动粘贴截图失败: {ex.Message}"); + LogHelper.WriteLogToFile($"自动粘贴截图失败: {ex.Message}", LogHelper.LogType.Error); + } + } + + // 将Bitmap复制到剪贴板 + private void CopyBitmapToClipboard(Bitmap bitmap) { + try { + // 将System.Drawing.Bitmap转换为WPF BitmapSource + var bitmapSource = ConvertBitmapToBitmapSource(bitmap); + + // 复制到剪贴板 + Clipboard.SetImage(bitmapSource); + } + catch (Exception ex) { + ShowNotification($"复制到剪贴板失败: {ex.Message}"); + } + } + + // 将System.Drawing.Bitmap转换为WPF BitmapSource + private BitmapSource ConvertBitmapToBitmapSource(Bitmap bitmap) { + using (var memory = new MemoryStream()) { + bitmap.Save(memory, ImageFormat.Png); + memory.Position = 0; + + var bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.StreamSource = memory; + bitmapImage.CacheOption = BitmapCacheOption.OnLoad; + bitmapImage.EndInit(); + bitmapImage.Freeze(); + + return bitmapImage; + } + } } }