FWE1
FWE1

Reputation: 11

What is the data type used for text properties?

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

Answers (3)

Max Kielland
Max Kielland

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

Remy Lebeau
Remy Lebeau

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

milphaser
milphaser

Reputation: 26

I think you have to migrate your code to Unicode. At first get acquainted with next resources:

  1. C++ Builder and Unicode https://community.embarcadero.com/index.php/blogs/entry/cbuilder-and-unicode-43342
  2. Migrating your C++Builder Projects to Unicode: https://www.youtube.com/watch?v=H-KFq5M0z0A&feature=emb_logo
  3. Migration and Upgrade Center: https://www.embarcadero.com/rad-in-action/migration-upgrade-center

Good luck

Upvotes: 1

Related Questions