如何防止系统剪贴板图像数据被粘贴到 WPF RichTextBox 中

发布于 2024-09-28 07:38:22 字数 1424 浏览 7 评论 0原文

我目前有一些代码可以拦截 WPF 中 RichTextBox 中的所有剪切、复制和粘贴事件。这些旨在去除除纯文本之外的所有内容,并且不允许粘贴除纯文本之外的内容(通过使用检查 Clipboard.ContainsText() 方法。)这似乎成功地阻止了所有此类操作内部 表格。用户只能复制、剪切和粘贴文本,不允许使用图像/音频数据/随机垃圾。

但是,如果我使用 PrintScreen 函数,并将其粘贴到其中一个 RichTextBox 中,则图像会被粘贴(不是想要的行为)。如果您随后尝试将此图像从一个 RichTextBox 粘贴到另一个 RichTextBox 中,则它不会让你(期望的行为)。

我当前覆盖的命令是使用

// Command handlers for Cut, Copy and Paste commands.
            // To enforce that data can be copied or pasted from the clipboard in text format only.
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Copy, new ExecutedRoutedEventHandler(OnCopy), 
                new CanExecuteRoutedEventHandler(OnCanExecuteCopy)));
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Paste, new ExecutedRoutedEventHandler(OnPaste), 
                new CanExecuteRoutedEventHandler(OnCanExecutePaste)));
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Cut, new ExecutedRoutedEventHandler(OnCut), 
                new CanExecuteRoutedEventHandler(OnCanExecuteCut)));

OnCopy (等)方法完成的,然后在允许任何操作之前检查是否仅存在文本。

这里似乎有两个剪贴板在工作,其中之一我没有限制/锁定。有谁知道这方面的技术细节,以及可以有效锁定和定制所有剪贴板活动(表单和系统)的任何方式?

提前致谢。

I have some code in place currently to intercept all Cut, Copy and Paste events into a RichTextBox in WPF. These are designed to strip all content out except plain text, and allow no pasting except plain text (by using a check the Clipboard.ContainsText() method.) This seems to be successful at preventing all such operations from inside the forms. A user can only copy, cut and paste text around, with images / audio data / random junk not being allowed.

However, if I use the PrintScreen function, and paste it into one of the RichTextBoxes, the image is pasted in (not the wanted behaviour.) If you then try and paste this image from one RichTextBox to another though, it won't let you (the desired behaviour).

The commands I'm currently overriding are done using

// Command handlers for Cut, Copy and Paste commands.
            // To enforce that data can be copied or pasted from the clipboard in text format only.
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Copy, new ExecutedRoutedEventHandler(OnCopy), 
                new CanExecuteRoutedEventHandler(OnCanExecuteCopy)));
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Paste, new ExecutedRoutedEventHandler(OnPaste), 
                new CanExecuteRoutedEventHandler(OnCanExecutePaste)));
            CommandManager.RegisterClassCommandBinding(typeof(MyRichTextBox),
                new CommandBinding(ApplicationCommands.Cut, new ExecutedRoutedEventHandler(OnCut), 
                new CanExecuteRoutedEventHandler(OnCanExecuteCut)));

The OnCopy (etc) methods then essentially check that only text is present before allowing any operations.

There seems to be two Clipboards at work here, one of which I'm not restricting / locking down. Does anyone know of the technicalities of this, and any way in which all Clipboard activity (both Form and System) can be locked down and customized effectively?

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

古镇旧梦 2024-10-05 07:38:22

这对于用户来说可能有点无情,但您可以像在粘贴之前劫持并清除剪贴板一样简单。只需挂接 PreviewKeyDown(因为在 KeyUp 上它已经被插入)并清除剪贴板(如果我们有图像并按下 Ctrl+V):

public Window1()
{
    InitializeComponent();

    _rtf.PreviewKeyDown += OnClearClipboard;
}

private void OnClearClipboard(object sender, KeyEventArgs keyEventArgs)
{
    if (Clipboard.ContainsImage() && keyEventArgs.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) != 0)
        Clipboard.Clear();
}

这不是最简洁的解决方案,但它可以解决问题。

It might be a bit unforgiving for the user but you could do it as simple as hijacking and clearing the Clipboard before pasting. Just hook the PreviewKeyDown (since on KeyUp it´s already been inserted) and clear the clipboard if we´ve got an image and is pressing Ctrl+V:

public Window1()
{
    InitializeComponent();

    _rtf.PreviewKeyDown += OnClearClipboard;
}

private void OnClearClipboard(object sender, KeyEventArgs keyEventArgs)
{
    if (Clipboard.ContainsImage() && keyEventArgs.Key == Key.V && (Keyboard.Modifiers & ModifierKeys.Control) != 0)
        Clipboard.Clear();
}

Not the neatest solution but it´ll do the trick.

水波映月 2024-10-05 07:38:22

实际上,您不需要任何像捕获 KeyDown 事件这样的技巧(这不会阻止通过上下文菜单粘贴或拖放)。有一个特定的附加事件:DataObject。粘贴

XAML:

<RichTextBox DataObject.Pasting="RichTextBox1_Pasting" ... />

代码隐藏:

    private void RichTextBox1_Pasting(object sender, DataObjectPastingEventArgs e)
    {
        if (e.FormatToApply == "Bitmap")
        {
            e.CancelCommand();
        }
    }

它阻止所有形式的粘贴(Ctrl-V、右键单击 -> 粘贴、拖放)。

如果您想更聪明,还可以将 DataObject 替换为仅包含您想要支持的格式的 DataObject(而不是完全取消粘贴)。

Actually you dont need any hack like catching the KeyDown events (which wouldn't prevent pasting through the context menu or drag and drop anyway). There's a specific attached event for that: DataObject.Pasting.

XAML:

<RichTextBox DataObject.Pasting="RichTextBox1_Pasting" ... />

Code-behind:

    private void RichTextBox1_Pasting(object sender, DataObjectPastingEventArgs e)
    {
        if (e.FormatToApply == "Bitmap")
        {
            e.CancelCommand();
        }
    }

It prevents all forms of pasting (Ctrl-V, right-click -> Paste, drag and drop).

If you want to be smarter than that, you can also replace the DataObject with one that contains only the formats you want to support (rather than completely cancelling the paste).

没︽人懂的悲伤 2024-10-05 07:38:22

我认为如果您的目标是只允许粘贴纯文本,这可能是更好的方法:

private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.V)
        {
            if (Clipboard.GetData("Text") != null)
                Clipboard.SetText((string)Clipboard.GetData("Text"), TextDataFormat.Text);
            else
                e.Handled = true;
        }            
    }

I think this is probably a better way if your goal is to just allow the plain text to be pasted:

private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Control && e.KeyCode == Keys.V)
        {
            if (Clipboard.GetData("Text") != null)
                Clipboard.SetText((string)Clipboard.GetData("Text"), TextDataFormat.Text);
            else
                e.Handled = true;
        }            
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文