Text Conversions
From Win32++
|
Text Conversion |
Introduction
There are several different types of text strings used in windows programming. These include:
ANSI
ANSI is an acronym for the American National Standards Institute. In windows programming, the term ANSI usually refers to single-byte ISO-8859 encodings. ANSI text strings are stored as an array of single byte char (or CHAR).
BSTR
BSTR is an abbreviation of Basic String (or perhaps Binary String). It was originally used in Visual Basic, and is often used in COM programming today. A BSTR string is a specialized Unicode string. It begins with a length field, which is followed by a string of Unicode characters. A BSTR is always NULL terminated, but can also contain NULL characters within the string.
OLE
Microsoft introduced a number of macros with "OLE" in the name, such as LPOLESTR. The term as it relates to text strings is largely superseded by Unicode (i.e. Wide) strings, however there are still a few Windows API functions that take LPOLESTR arguments. In modern Windows programming, OLE strings are Unicode strings.
TCHAR
TCHAR text strings are Unicode if the UNICODE macro is defined, otherwise they are ANSI. TCHAR is the type of text string used in most Windows API functions. It helps developers to produce code capable of supporting both ANSI and Unicode text strings.
Wide or Unicode
Unicode is an international standard for the representation of text characters. Unlike ANSI which uses a single byte for each character, Unicode (in Windows) uses two bytes for each character. Unicode text strings are stored as an array of wchar (or WCHAR). Modern Microsoft Windows operating systems (since Windows ME) have standardised on Unicode.
String Conversion Functions in Win32++
Win32++ contains the following functions to convert from one string type to another.
| A2BSTR | Convert from ANSI to BSTR |
| A2OLE | Convert from ANSI to OLE |
| A2T | Convert from ANSI to TCHAR |
| A2W | Convert from ANSI to WCHAR |
| OLE2A | Convert from OLE to ANSI |
| OLE2T | Convert from OLE to TCHAR |
Using the Text Conversion Functions
Each of the text conversion functions described above are actually typedefs of text conversion classes such as CA2W and CW2A. They each return a pointer to the appropriate text string type. These text conversions can be used as either classes or functions. When using them as functions it is important to remember that the returned pointer goes out of scope immediately. This means the returned pointer cannot be saved for later use. The following examples illustrate this.
Example 1 - Using the text converter as a class
In this example W2A is used as a class. A W2A object is created using its constructor, and this object remains in scope until the example function ends.
void ExampleFunctionW( LPCWSTR pWide )
{
// Use the converion class as a class.
W2A MyAnsiString( pWide );
// MyAnsiString works like an LPCSTR (pointer to const CHAR), and can be used like this:
SetWindowTextA( MyAnsiString ); // The ANSI version of SetWindowText
// Note: MyAnsiString remains in scope until the function ends.
}
Example 2 - Using the text converter as as a function.
In this example the result of the W2A text conversion is used immediately. The destructor of W2A is called after the call to SetWindowTextA.
void ExampleFunctionW( LPCWSTR pWide)
{
// Convert from Wide (Unicode) to ANSI and use the result.
SetWindowTextA( W2A( pWide ) ); // The ANSI version of SetWindowText
}
Example 3 - Storing a result for later use.
This examples demonstrates some correct techniques for storing our text conversion result for later use. Note that we cannot simply store the pointer because it goes out of scope immediately.
void ExampleFunctionW( LPCWSTR pWide )
{
// Store the result in a std::string
std::string str = W2A( pWide ); // or std::string str = (LPCTSTR)W2A( pWide ); for some compilers
// Store the result in an array
char szArray[80];
strcpy( szArray, W2A( pWide ) );
// Store the result in a vector
std::vector<char> MyAnsiVector(strlen(W2A(pWide))+1, '\0');
strcpy(&MyAnsiVector.front(), W2A(pWide);
// Do something with our stored string conversion
// ...
}
Example 4 - Incorrect use of the text conversion function.
In this example the destructor for W2A is called before the call to SetWindowTextA. As a result, the contents of pAnsi are destroyed and the pointer no longer points to a valid character array.
void ExampleFunctionW( LPCWSTR pWide )
{
// THIS IS INCORRECT!
LPCSTR pAnsi = W2A( pWide );
// W2A's destructor has already been called, so pAnsi is no longer points to a valid value.
SetWindowTextA( pAnsi ); // Behaviour of this line is undefined!
}