2012-02-01 170 views
3

我遇到剪貼板問題,每次嘗試從Excel文件進​​行復制/粘貼操作時都會收到此錯誤消息。剪貼板打開失敗

碼處斷裂Clipboard.GetDataObject()和消息的錯誤是這樣的:

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

我的WPF應用程序已經運行,當我打開Excel中,寫一些文字,然後嘗試複製/粘貼。

,我正在使用的代碼是這樣的:

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論壇,但沒找不到解決此問題的方法。

有人可以幫助我,或給我一個想法,我應該嘗試一下嗎?

謝謝!

回答

3

這裏有幾個問題。拳頭,雖然你一定需要將WM_DrawClipboard發送到鏈中的下一個應用程序,但你不需要先做。你可以在你運行自己的東西后做,然後傳遞信息。

接下來,不要期望Excel在一次操作中執行其所有剪貼板更新。在複製複雜對象時,我看到Excel在一行中執行多達24個更新。 (特別是圖表 - 他們會在添加每種格式後打開/關閉剪貼板)。

另外,Excel除了純文本之外,幾乎可以利用延遲渲染。所以,當您的應用程序請求數據時,Excel已經呈現它。這可能需要時間。

您可能需要用「while not success or 3-strikes loop」來實現延遲。您需要密切關注是否在處理之前或之後將WM_DrawClipboard發送到鏈中,因爲您可能與其他也對Excel數據感興趣的剪貼板查看器發生了另一次碰撞,並且不得不訴諸於此類欺騙自己。

你以爲這會很容易.....

+0

嗨,克里斯!感謝您的回答。最後我做了類似於你所說的,現在它工作正常:) – 2012-02-04 09:02:27

0

不要你需要檢查Clipboard對象包含正確的數據,並要求該類型的對象?它可以容納不同類型的多個對象,也許你會得到一個意想不到的類型。我使用類似以下內容的東西,雖然在你的情況下很明顯,你不會要求我的自定義Address對象Clipboard

if (System.Windows.Clipboard.ContainsData("Address")) 
{ 
    try 
    { 
     return (SerializableAddress)System.Windows.Clipboard.GetData("Address"); 
    } 
    catch (COMException) 
    { 
     return null; 
    } 
} 
return null;