Borland C++ - 使用OLE使用Word打开RTF文件

Borland C++ - using OLE to open RTF file using Word

本文关键字:使用 打开 RTF 文件 Word OLE C++ Borland      更新时间:2023-10-16

我是Embarcadero的新手C++Builder,VCL和OLE。我正在尝试做的是使用 OLE 打开一个 RTF 文件,但我得到了一个例外:

错误的变量类型

执行此行时:

wordDoc = wordDoc.OleFunction( "open", file );

我不确定如何解决这个问题。这是我的代码:

//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
#include <System.hpp>
#include <oleauto.h>
#include <sysvari.h>
//---------------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
try
{
Application->Initialize();
UnicodeString file( "C:\TempFiles\Test.rtf" );
Variant wordApp = Variant::CreateObject( "word.application" );
wordApp.OlePropertySet( "Visible", Variant( false ) );
Variant wordDoc = wordApp.OlePropertyGet( "documents" );
wordDoc = wordDoc.OleFunction( "open", file );
//Application->MainFormOnTaskBar = true;
//Application->Run();
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
catch (...)
{
try
{
throw Exception("");
}
catch (Exception &exception)
{
Application->ShowException(&exception);
}
}
return 0;
}
//---------------------------------------------------------------------------

问题是您在调用 Word 的Open()函数时在Variant::OleFunction()的第二个参数中传递UnicodeString

在内部,OleFunction()将输入参数转换为Variant值(而不是OleVariant),然后按原样将它们传递给IDispatch::Invoke()

仅当 OLE 保存与 OLE 兼容的数据时,Variant才与 OLE 兼容。UnicodeString特定于 Delphi/C++Builder,并且对 OLE 未知,因此它与 OLE 不兼容。

当一个Variant被分配一个UnicodeString值时,它的VType字段被设置为varUString(0x0102),它的有效载荷是指向UnicodeString内部数据的指针,其refCnt字段递增(Variant在销毁时会递减refCnt)。

OLE 抱怨当您的UnicodeString- 转Variant传递给IDispatch::Invoke()时,该值不受支持的VType值。

要修复此错误,您需要改为将WideString传递给OleFunction()WideString是 OLEBSTR字符串的包装器。 为Variant分配WideString值时,其VType字段设置为varOleStr(0x0008,在 OLE 中也称为VT_BSTR),并且其有效负载是一个正确的BSTR指针,它是WideString数据的副本(Variant将在销毁时释放BSTR)。

因此,您需要:

  • file变量更改为WideString

    WideString file( L"C:\TempFiles\Test.rtf" );
    
  • file变量保留为UnicodeString,但在将其传递给OleFunction()时将其转换为WideString

    wordDoc = wordDoc.OleFunction( L"open", WideString(file) );