2012-11-29 35 views
3

我正在使用Delphi 7嘗試將一個Word文檔加載到OLEContainer中。該程序正在終端服務(Windows 2003)環境中運行。調用CreateObjectFromFile時無效的FORMATETC結構

下面的代碼生成錯誤對於一些用戶:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
    OleContainer1.CreateObjectFromFile('c:\tmp\test.doc', false); 
end; 

它與一個和的OleContainer窗體上的一個按鈕,一個簡單的應用程序。 c:\ tmp \ test.doc是一個Word 2003文檔。

對於某些用戶來說,這代碼生成錯誤

無效FORMATETC結構。

對於其他人來說不。所有用戶在同一臺​​終端服務器上運行,從而運行訪問同一Word文檔的相同程序。而且,所有用戶都是使用腳本創建的,所以它們具有完全相同的設置,除了用戶名和類似的當然。

我試過讓所有的用戶管理員,但這並沒有改變行爲。

任何人都有什麼想法可以解決問題?

+0

這可能是併發問題。你所有的用戶都必須使用同一個文檔,或者你能爲每個用戶提供一份副本嗎? – jachguate

+0

錯誤消息包含其他信息(可能是錯誤編號),或者只是__無效的FORMATETC結構_? – jachguate

+0

你使用哪個Delphi版本?我在XE3中調用的OleCreateFromFile調用只是將_lpFormatEtc_參數和OLERENDER_DRAW的nil(null)傳遞給_renderopt_。它看起來不像我的失敗點。你可以重試嗎?或者生成一個StackTrace來查看它在哪一點上的失敗? – jachguate

回答

0

經過一番測試,我發現方法TOleContainer.LoadFromStream總是起作用。問題在於此方法需要OLE流,而不是包含單詞文檔的流。我反向設計了OLE流的格式,並通過編寫標題,單詞文檔和頁腳來手動創建一個。看起來,頁腳包含256個字節的ASCII-0。

以下是createing的OLE流代碼:

function OLEStreamFromDoc(const inDocFileName : String) : TMemoryStream; 
var 
    aFileStream : TMemoryStream; 
    aPadding : Array[1..256] of byte; 
    aHeader  : Array[1..12] of byte; 
    aSize  : int64; 
    i   : integer; 
begin 
    for i := low(aHeader) to High(aHeader) do 
    aHeader[i] := 0; 

    for i := low(aPadding) to High(aPadding) do 
    aPadding[i] := 0; 

    Result := TMemoryStream.Create; 
    aFileStream := TMemoryStream.Create; 
    try 
    aFileStream.LoadFromFile(inDocFileName); 
    aFileStream.Seek(0,0); 
    aSize := aFileStream.Size + SizeOf(aPadding); 

    aHeader[1] := Ord('B'); 
    aHeader[2] := Ord('D'); 
    aHeader[3] := Ord('O'); 
    aHeader[4] := Ord('C'); 
    aHeader[5] := 1; 
    aHeader[9] := aSize and 255; 
    aHeader[10] := (aSize shr 8) and 255; 
    aHeader[11] := (aSize shr 16) and 255; 
    aHeader[12] := (aSize shr 24) and 255; 
    Result.Write(aHeader, SizeOf(aHeader)); 
    aFileStream.SaveToStream(Result); 
    Result.Write(aPadding, sizeof(aPadding)); 
    Result.Seek(0,0); 
    finally 
    aFileStream.Free; 
    end; 
end; 
0

我相信Word自動化支持IPersistFile,這應該提供一種替代方式來加載文件。 See more here.