Reputation: 11
I am porting over some code from a very old copy of Builder (> 15 years). In those days, the Text properties of various controls were of type AnsiString
. It appears that in the latest version of C++Builder, that is no longer the case. What is the data type?
All I can get from the help is TCaption
, is that a type?
My code compiles and runs, but in trying to work with simple edit boxes, the text is not what is typed in, usually a '0'. And c_str()
works but gives the wrong value.
Upvotes: 1
Views: 270
Reputation: 5841
[DISCLAIMER]
All "code examples" are from the top of my head and not actually compiled.
The String
type is just a macro selecting the AnsiString
or UnicodeString
class depending on the UNICODE
define.
Earlier, UNICODE
was not defined by default so char
was used, selecting the AnsiString
class. Today UNICODE
is defined by default so wchar_t
is used, selecting the UnicodeString
class. This is very convinient because Windows API are now by default Unicode.
There are several other types as WideString
, UTF8String
etc. They all have about the same interface (so they can be interchanged). Therefore .c_str()
returns a different type depending on the selected String
class.
To migrate you usually only have to put an L
in front of all constant strings, such as L"My unicode message"
There should only be some rare cases where you specifically need an 8bit char
. For these situations you can do a conversion with AnsiString()
.
String Foo = "This is Unicode";
Bar(AnsiString(Foo).c_str()); // AnsiString converts Foo into an 8bit char pointer.
Baz(Foo.c_str()); // Foo returns a wchar_t pointer.
Windows API usually have two versions of each function, xxxxA for Ansi and xxxxW for the wide version. If you omit the ending A
or W
, Windows will use the right version depending on the UNICODE
define. The W versions require you to use the L"My string"
where A versions doesn't. Microsoft solved this with the TEXT
macro: TEXT("Auto converted")
. The TEXT
macro will convert the constant string to either ansi or wide depending on the UNICODE
define. This line will work correctly with both UNICODE
defined or undefined by selecting the correct API function version.
MessageBox(TEXT("Auto converted string"),TEXT("TEXT MACRO"),0);
You can force Windows to use either the Ansi or Wide version by appending the A or W to the API function name.
MessageBoxA("This is the ansi version","MessageBoxA",0);
MessageBoxW(L"This is the wide version",L"MessageBoxW",0);
I would recommend you to migrate your project to only use String
if possible and convert to AnsiString
if it is absolutely required (such as calling a library function that only accepts 8bit char
). char
should be wchar_t
by default in your project (see "project->Options->C++ Shared Options->_TCHAR maps to")
Upvotes: 0
Reputation: 597941
The default string type used by C++Builder's RTL and VCL frameworks has always been whatever Delphi's native String
type was at the time. Things like TCaption
, TFileName
, etc were just aliases for String
(but with distinct RTTI attached to them so the IDE's Object Inspector could differentiate between them).
Delphi's String
type is a container for elements of Delphi's native Char
type.
C++Builder provides System::Char
and System::String
aliases to match Delphi's native Char
and String
types:
In C++Builder 2007 and earlier, Delphi's native Char
type was AnsiChar
, and so System::Char
was an alias for C/C++'s char
, and System::String
was an alias for System::AnsiString
. Thus, System::String
was an 8bit ANSI string, and String::c_str()
returned a null-terminated char*
pointer.
In C++Builder 2009 and later, Delphi's native Char
type is WideChar
, and so System::Char
is now an alias for wchar_t
on Windows and char16_t
on POSIX, and System::String
is now an alias for System::UnicodeString
. Thus, System::String
is a 16bit UTF-16 string, and String::c_str()
returns a null-terminated wchar_t*
/char16_t*
pointer, respectively.
So any code you have that operates on C-style string pointers, rather than using RTL features that operate on System::String
, will have to be updated accordingly to move from ANSI to UTF-16.
See Embarcadero's Unicode migration online resources. The transition is mostly transparent for Delphi users, but for C++ users it tends to require a bit more work.
Upvotes: 2
Reputation: 26
I think you have to migrate your code to Unicode. At first get acquainted with next resources:
Good luck
Upvotes: 1