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

321 lines
11 KiB
C#
Raw Normal View History

2025-08-31 11:43:52 +08:00
using Ink_Canvas.Helpers;
using System;
2025-07-30 19:56:22 +08:00
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
2025-08-31 09:54:13 +08:00
using System.Windows.Controls.Primitives;
using System.Windows.Forms;
2025-08-30 22:54:16 +08:00
using System.Windows.Ink;
2025-07-30 19:56:22 +08:00
using System.Windows.Input;
2025-08-31 09:54:13 +08:00
using System.Windows.Media;
2025-07-30 19:56:22 +08:00
using System.Windows.Media.Imaging;
2025-08-31 09:54:13 +08:00
using System.Windows.Threading;
using Clipboard = System.Windows.Clipboard;
using ContextMenu = System.Windows.Controls.ContextMenu;
using Cursors = System.Windows.Input.Cursors;
using MenuItem = System.Windows.Controls.MenuItem;
2025-07-30 19:56:22 +08:00
namespace Ink_Canvas
{
public partial class MainWindow : Window
{
2025-08-31 09:54:13 +08:00
private bool isClipboardMonitoringEnabled;
private BitmapSource lastClipboardImage;
2025-07-30 19:56:22 +08:00
// 初始化剪贴板监控
private void InitializeClipboardMonitoring()
{
try
{
// 监听剪贴板变化
ClipboardNotification.ClipboardUpdate += OnClipboardUpdate;
isClipboardMonitoringEnabled = true;
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"初始化剪贴板监控失败: {ex.Message}", LogHelper.LogType.Error);
}
}
// 剪贴板内容变化事件处理
private void OnClipboardUpdate()
{
try
{
if (Clipboard.ContainsImage())
{
var clipboardImage = Clipboard.GetImage();
if (clipboardImage != null && clipboardImage != lastClipboardImage)
{
lastClipboardImage = clipboardImage;
// 在白板模式下显示粘贴提示
if (currentMode == 1) // 白板模式
{
ShowPasteNotification();
}
}
}
}
catch (Exception ex)
{
LogHelper.WriteLogToFile($"处理剪贴板更新失败: {ex.Message}", LogHelper.LogType.Error);
}
}
// 显示粘贴提示
private void ShowPasteNotification()
{
try
{
Dispatcher.Invoke(() =>
{
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();
2025-08-03 16:46:33 +08:00
2025-07-30 19:56:22 +08:00
var pasteMenuItem = new MenuItem
{
Header = "粘贴图片"
};
2025-08-03 16:46:33 +08:00
2025-07-30 19:56:22 +08:00
pasteMenuItem.Click += async (s, e) => await PasteImageFromClipboard(position);
contextMenu.Items.Add(pasteMenuItem);
// 显示菜单
contextMenu.IsOpen = true;
contextMenu.PlacementTarget = inkCanvas;
2025-08-31 09:54:13 +08:00
contextMenu.Placement = PlacementMode.MousePoint;
2025-07-30 19:56:22 +08:00
}
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,
2025-08-31 09:54:13 +08:00
Stretch = Stretch.Fill
2025-07-30 19:56:22 +08:00
};
// 生成唯一名称
string timestamp = "img_clipboard_" + DateTime.Now.ToString("yyyyMMdd_HH_mm_ss_fff");
image.Name = timestamp;
2025-08-30 22:54:16 +08:00
// 初始化TransformGroup
if (image is FrameworkElement element)
{
var transformGroup = new TransformGroup();
transformGroup.Children.Add(new ScaleTransform(1, 1));
transformGroup.Children.Add(new TranslateTransform(0, 0));
transformGroup.Children.Add(new RotateTransform(0));
element.RenderTransform = transformGroup;
}
// 设置图片属性,避免被InkCanvas选择系统处理
image.IsHitTestVisible = true;
image.Focusable = false;
2025-08-31 11:43:52 +08:00
2025-08-30 22:54:16 +08:00
// 初始化InkCanvas选择设置
if (inkCanvas != null)
{
// 清除当前选择,避免显示控制点
inkCanvas.Select(new StrokeCollection());
2025-08-31 09:18:30 +08:00
// 设置编辑模式为非选择模式,这样可以保持图片的交互功能
2025-08-30 23:19:53 +08:00
// 同时通过图片的IsHitTestVisible和Focusable属性来避免InkCanvas选择系统的干扰
2025-08-31 09:18:30 +08:00
inkCanvas.EditingMode = InkCanvasEditingMode.None;
2025-08-30 22:54:16 +08:00
}
2025-07-30 19:56:22 +08:00
// 添加到画布
inkCanvas.Children.Add(image);
2025-08-31 09:20:35 +08:00
// 等待图片加载完成后再进行居中处理
image.Loaded += (sender, e) =>
2025-08-30 22:54:16 +08:00
{
2025-08-31 09:20:35 +08:00
// 确保在UI线程中执行
Dispatcher.BeginInvoke(new Action(() =>
{
// 先进行缩放居中处理
CenterAndScaleElement(image);
2025-08-31 11:43:52 +08:00
2025-08-31 09:20:35 +08:00
// 如果有指定位置,调整到指定位置
if (position.HasValue)
{
// 在指定位置居中显示
InkCanvas.SetLeft(image, position.Value.X - image.Width / 2);
InkCanvas.SetTop(image, position.Value.Y - image.Height / 2);
}
2025-08-31 11:43:52 +08:00
2025-08-31 09:20:35 +08:00
// 绑定事件处理器
if (image is FrameworkElement elementForEvents)
{
// 鼠标事件
elementForEvents.MouseLeftButtonDown += Element_MouseLeftButtonDown;
elementForEvents.MouseLeftButtonUp += Element_MouseLeftButtonUp;
elementForEvents.MouseMove += Element_MouseMove;
elementForEvents.MouseWheel += Element_MouseWheel;
// 触摸事件
elementForEvents.IsManipulationEnabled = true;
elementForEvents.ManipulationDelta += Element_ManipulationDelta;
elementForEvents.ManipulationCompleted += Element_ManipulationCompleted;
// 设置光标
elementForEvents.Cursor = Cursors.Hand;
}
2025-08-31 09:54:13 +08:00
}), DispatcherPriority.Loaded);
2025-08-31 09:20:35 +08:00
};
2025-08-30 22:54:16 +08:00
2025-07-30 19:56:22 +08:00
// 提交到历史记录
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);
}
}
// 处理全局粘贴快捷键
2025-08-23 21:39:00 +08:00
internal async void HandleGlobalPaste(object sender, ExecutedRoutedEventArgs e)
2025-07-30 19:56:22 +08:00
{
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;
2025-08-31 09:54:13 +08:00
private static Timer clipboardTimer;
2025-07-30 19:56:22 +08:00
private static string lastClipboardText = "";
2025-08-31 09:54:13 +08:00
private static bool lastHadImage;
2025-07-30 19:56:22 +08:00
static ClipboardNotification()
{
2025-08-31 09:54:13 +08:00
clipboardTimer = new Timer();
2025-07-30 19:56:22 +08:00
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();
}
}
}