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

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

我是 Embarcadero C++Builder、VCL 和 OLE 的新手。我正在尝试做的是使用 OLE 打开一个 RTF 文件,但出现异常:

Bad variable type

执行此行时:

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;
}
//---------------------------------------------------------------------------

问题是您正在传递 UnicodeString in the 2nd parameter of Variant::OleFunction() when calling Word's Open() 函数。

在内部,OleFunction() 将输入参数转换为 Variant values (rather than OleVariant), and then passes them as-is to IDispatch::Invoke()

Variant 只有在包含 OLE-compatible 数据时才与 OLE 兼容。 UnicodeString 特定于 Delphi/C++Builder 而 OLE 未知,因此它不是 OLE-compatible.

当一个 Variant 被赋予一个 UnicodeString 值时,它的 VType 字段被设置为 varUString (0x0102),它的负载是一个指向 UnicodeString 的内部数据及其 refCnt 字段递增(Variant 将在销毁时递减 refCnt)。

当您的 UnicodeString-turned-Variant 传递给 IDispatch::Invoke().

时,

OLE 抱怨 VType 值不受支持

要修复错误,您需要将 WideString 传递给 OleFunction()WideStringOLE BSTR string 的包装器。当 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) );