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
OLE2W Convert from OLE to WCHAR T2A Convert from TCHAR to ANSI T2BSTR Convert from TCHAR to BSTR T2OLE Convert from TCHAR to OLE T2W Convert from TCHAR to WCHAR W2A Convert from WCHAR to ANSI W2BSTR Convert from WCHAR to BSTR W2OLE Convert from WCHAR to OLE W2OLE Convert from WCHAR to OLE

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!
}