What is the correct text type for setting OleVariant text properties

45 Views Asked by At

The code below used to work when compiled on C++Builder 6.0:

    Variant xlApp, wBook, wSheet, vRange;

    String xlFile  = "C:\\Temp\\ExcelTestFile.xlsx",
           xlTitle = "Relatório de Geração";
    try{
        xlApp = CreateOleObject("Excel.Application");
        // Hide Excel
        xlApp.OlePropertySet("Visible", false);
        // Add new Workbook
        xlApp.OlePropertyGet("WorkBooks").OleFunction("Add", -4167);
        // Get WorkBook
        wBook = xlApp.OlePropertyGet("Workbooks").OlePropertyGet("Item", 1);

        // Get WorkSheet
        wSheet = wBook.OlePropertyGet("Worksheets").OlePropertyGet("Item", 1);
        wSheet.OlePropertySet("Name", xlTitle.c_str() ); // Raise Incorrect Type
    }
    catch(Exception &E){
         ShowMessage( E.Message );
         xlApp.OlePropertySet("DisplayAlerts",false);
         xlApp.OleProcedure("Quit");
    } 

What is the correct string type?

Thank you very much.

2

There are 2 best solutions below

0
On BEST ANSWER

The correct type when passing strings through COM is WideString.

The WideString type is actually a wrapper around the Windows BSTR type, which means behind the scenes it uses the functions:

You don't have to use WideString; but you do have to use SysAllocString and SysFreeString. You can call them manually, or you can use WideString to do it for you.

0
On

wSheet.OlePropertySet("Name", xlTitle.c_str() ); // Raise Incorrect Type

The C++Builer 6 code was using AnsiString and passed a const char* from it to OlePropertySet(). Now, in modern versions, the code would be using UnicodeString and passing its const wchar_t* instead.

However, the COM object expect a BSTR string instead (which is an alias for wchar_t*, but its memory is managed by the OS, not the RTL). The RTL should b converting from char*/wchar_t* to BSTR automatically for you, but to help it along you should use the WideString class instead (which wraps a BSTR), eg:

wSheet.OlePropertySet("Name", WideString(xlTitle).c_bstr() );

Alternatively:

wSheet.OlePropertySet("Name", WideString(xlTitle) );

Alternatively:

wSheet.OlePropertySet<WideString>("Name", xlTitle );

Alternatively:

WideString xlTitle;
....
wSheet.OlePropertySet("Name", xlTitle );

That being said, BSTR handling in TAutoArgs (which OlePropertySet() uses internally) seems to have broken somewhere between C++Builder 10.4.2 to 11.2, see this discussion:

WideString.c_bstr() operation in 11.2