2012-11-29 2 views
3

델파이 7을 사용하여 OLEContainer에 Word 문서를로드하려고합니다. 이 프로그램은 터미널 서비스 (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

그것은 동시성 문제가 될 수 :

다음은 OLE 스트림을 createing 코드입니다. 모든 사용자가 동일한 문서를 사용해야하거나 각 사용자에게 사본을 제공 할 수 있습니까? – jachguate

+0

오류 메시지에 다른 정보 (오류 번호 일 수도 있음)가 있거나 _Invalid FORMATETC 구조체 _입니까? – jachguate

+0

어떤 델파이 버전을 사용합니까? XE3에있는 OleCreateFromFile 호출은 _lpFormatEtc_ 매개 변수에 nil (null)을 전달하고 _renderopt_에 OLERENDER_DRAW를 전달합니다. 그것은 나에게 실패 지점처럼 보이지 않는다. 방금 다시 시도 할 수 있습니까? 또는 StackTrace를 생성하여 실패 지점을 확인하십시오. – jachguate

답변

0

일부 테스트 후 TOleContainer.LoadFromStream 메서드가 항상 작동하는 것으로 나타났습니다. 문제는이 메서드는 워드 문서가 포함 된 스트림이 아니라 OLE 스트림을 필요로한다는 것입니다. OLE 스트림의 형식을 리버스 엔지니어링하고 머리글, 단어 문서 및 바닥 글을 수동으로 작성했습니다. 꼬리말은 256 바이트의 ASCII-0으로 구성됩니다.

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.

관련 문제