Reputation: 53
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.
Upvotes: 0
Views: 56
Reputation: 597896
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
Upvotes: 1
Reputation: 257001
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.
Upvotes: 1