使用Windows剪贴板

伊斯塔尼翁

我正在维护WPF .NET应用程序,并且用户在尝试从DataGrid控件进行复制时遇到了崩溃。我搜索了一下,发现原因是他正在使用的其他应用程序可能未调用CloseClipboard()在相同情况下,Excel也会显示错误消息,消息为“我们无法释放剪贴板上的空间。另一个程序可能正在使用它。”

然后,我编写了另一个具有打开/关闭剪贴板按钮的程序,然后可以重现此行为,并且仅通过一条错误消息实现了相同的“修复”。

但是,出于好奇,我想看看Google Chrome浏览器是如何处理此问题的。我使用程序锁定了剪贴板,并确认Excel在抱怨。但是,Chrome仍然可以优雅地处理复制/粘贴操作。我可以从Chrome复制到记事本,但不能从记事本和Excel复制。有趣的是,我实际上可以从记事本复制到Chrome。

我一直在浏览Chromium的源代码,但找不到复制/粘贴逻辑的实现。有人知道Chrome如何处理吗?

怎么可能无法在记事本中复制/粘贴,但是从记事本到Chrome正常工作?

在网上可以找到的所有实现中,解决方案似乎都与我现在得到的解决方案相同:在放弃之前,尝试进行一秒钟左右的尝试。

供参考,这是我的剪贴板储物柜后面的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace ClipboardLocker
{
    public partial class MainWindow : Window
    {
        [System.Runtime.InteropServices.DllImport("user32.dll")]
        static extern IntPtr GetOpenClipboardWindow();

        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern bool OpenClipboard(IntPtr hWndNewOwner);

        [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
        static extern bool CloseClipboard();

        bool clipboardLocked = false;

        public MainWindow()
        {
            InitializeComponent();

            double screenWidth = System.Windows.SystemParameters.PrimaryScreenWidth;
            double screenHeight = System.Windows.SystemParameters.PrimaryScreenHeight;
            double windowWidth = this.Width;
            double windowHeight = this.Height;
            this.Left = (screenWidth / 2) - (windowWidth / 2);
            this.Top = (screenHeight / 2) - (windowHeight / 2);
        }

        private void LockButton_Click(object sender, RoutedEventArgs e)
        {
            if (!clipboardLocked)
            {
                IntPtr handle = GetOpenClipboardWindow();
                OpenClipboard(handle);
                clipboardLocked = true;
                LockButton.Content = "Unlock";
            }
            else
            {
                CloseClipboard();
                clipboardLocked = false;
                LockButton.Content = "Lock";
            }
        }
    }
}

[更新]

经过更多实验后,Chrome似乎能够以某种方式解锁剪贴板。在Chrome中完成复制/粘贴后,它也可以在其他应用程序中使用。Chromw如何从我的储物柜程序中“窃取”剪贴板?MSDN指导思想ChangeClipboardChain我将尝试和尝试。

伊斯塔尼翁

要接管剪贴板,我首先调用OpenClipboard一个NULL参数。这将从当前保存剪贴板的任何窗口“窃取”剪贴板。然后,我通过致电将其关闭CloseClipboard现在这将起作用,因为剪贴板将是MSDN所说的“打开的剪贴板与当前任务相关联”。

现在剪贴板已正确关闭,可以调用WPF或Windows Forms的Clipboard.SetText()作品。

这当然不是一个很好的解决方案,但我相信这是Windows在这种情况下为我们提供的最佳选择。

这是我的ClipboardHelper,如果其他人遇到此问题。

static class ClipboardHelper
{
    [System.Runtime.InteropServices.DllImport("user32.dll")]
    static extern IntPtr GetOpenClipboardWindow();

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern bool OpenClipboard(IntPtr hWndNewOwner);

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern bool CloseClipboard();

    [System.Runtime.InteropServices.DllImport("user32.dll", SetLastError = true)]
    static extern bool ChangeClipboardChain(IntPtr hWndRemove, IntPtr hWndNewNext);

    public static bool SetText(string text)
    {
        IntPtr hWnd = GetOpenClipboardWindow(); // Gets the HWND of the window that currently owns the clipboard

        if (hWnd == null)   // If no window currently owns the clipboard, just go ahead and set the text.
        {
            System.Windows.Forms.Clipboard.SetText(text);
        }
        else
        {
            OpenClipboard(IntPtr.Zero);
            CloseClipboard();
            System.Windows.Forms.Clipboard.SetText(text);
        }
        return true;
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何使用VNC在Windows剪贴板和OpenSuse剪贴板之间复制/粘贴数据?

来自分类Dev

如何使用剪贴板

来自分类Dev

Windows剪贴板读取通知

来自分类Dev

如何从Windows剪贴板读取位图

来自分类Dev

在Firefox OS中使用剪贴板

来自分类Dev

使用数据剪贴板目标

来自分类Dev

在TypeScript中使用剪贴板数据

来自分类Dev

剪贴板插件的xfreerdp使用示例

来自分类Dev

在Firefox OS中使用剪贴板

来自分类Dev

使用 WIC 读取剪贴板

来自分类Dev

通过 WSL 使用剪贴板?

来自分类Dev

转到剪贴板

来自分类Dev

如何使用Windows剪贴板中复制的文件加载流

来自分类Dev

使用Windows截图并在cmd中草绘剪贴板临时图像

来自分类Dev

如何使用单线将RTF文件的内容写入Windows剪贴板?

来自分类Dev

如何仅使用键盘将Windows剪贴板粘贴到PuTTY会话中?

来自分类Dev

C#Windows Phone 8.1剪贴板支持

来自分类Dev

用剪贴板数据填充Windows共享魅力

来自分类Dev

VBA Windows 10问题中的文本到剪贴板

来自分类Dev

C#Windows Phone 8.1剪贴板支持

来自分类Dev

Windows剪贴板的安全性如何?

来自分类Dev

如何在Windows上访问原始剪贴板数据?

来自分类Dev

如何在Windows上访问原始剪贴板数据?

来自分类Dev

Windows 10自动更改剪贴板数据

来自分类Dev

如何将剪贴板配置为Windows?

来自分类Dev

如何在Windows 8中查看剪贴板的内容?

来自分类Dev

用剪贴板数据填充Windows Share的魅力

来自分类Dev

用剪贴板数据填充Windows Share的魅力

来自分类Dev

将任意文本设置为Windows剪贴板