3

我在剪贴板方面遇到问题,每次尝试从 Excel 文件进行复制/粘贴操作时都会收到此错误消息。

代码中断,Clipboard.GetDataObject()消息错误是这样的:

OpenClipboard Failed (Exception from HRESULT: 0x800401D0 (CLIPBRD_E_CANT_OPEN))

当我打开 Excel、编写一些文本然后尝试复制/粘贴时,我的 WPF 应用程序已经在运行。

我正在使用的代码是这样的:

private void SetClipboardData()
{
    IDataObject data = Clipboard.GetDataObject();
    IList result = GetDataForFileDropFormat( data );

    if ( ( result != null ) && ( result.Count > 0 ) )
    {
        this._elementsClipboard = result;
        this._sourceDrag = null;
        this._sourceClipboard = null;
    }
}

上面的函数在这个处理方法中被调用:

public void Handle_WM_DRAWCLIPBOARD( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
{
    SendMessage( this._nextClipboardViewer, msg, wParam, lParam );

    // get data from clipboard
    SetClipboardData();

    handled = true;
}

我一直在搜索 MSDN 和 .NET 论坛,但没有找到解决此问题的方法。

有人可以帮我解决这个问题或让我知道我应该尝试什么吗?

谢谢!

4

2 回答 2

3

这里有几个问题。拳头,虽然您确实需要将 WM_DrawClipboard 发送到链中的下一个应用程序,但您不需要首先执行此操作。您可以在运行自己的东西后执行此操作,然后传递消息。

接下来,不要期望 Excel 在一次操作中执行所有剪贴板更新。我已经看到 Excel 在复制复杂对象时连续执行多达 24 次更新。(特别是图表 - 他们会在添加每种单独的格式后打开/关闭剪贴板)。

此外,Excel 对纯文本以外的几乎所有内容都利用了延迟渲染。因此,当您的应用程序请求数据时,Excel 会呈现它。这可能需要时间。

您可能需要使用“while not success or 3-strikes loop”来实现延迟。您需要密切注意是否在处理之前或之后将 WM_DrawClipboard 发送到链中,因为您可能会与其他对 Excel 数据感兴趣的剪贴板查看器设置另一个冲突,并且不得不求助于此类欺骗自己。

你认为这很容易......

于 2012-02-03T19:56:37.480 回答
0

您不需要检查Clipboard对象是否包含正确类型的数据并请求该类型的对象吗?它可以容纳多个不同类型的对象,也许您会得到一个意外类型的项目。我使用类似下面的东西,虽然在你的情况下,你不会AddressClipboard.

if (System.Windows.Clipboard.ContainsData("Address"))
{
    try
    {
        return (SerializableAddress)System.Windows.Clipboard.GetData("Address");
    }
    catch (COMException)
    {
        return null; 
    }
}
return null;
于 2012-02-04T22:27:16.577 回答