Many C++ Windows programmers get confused over what bizarre identifiers like TCHAR, LPCTSTR are. Here, in brief, I would try to clear out the fog.
In general, a character can be 1 byte or 2 bytes. Lets say 1-byte character is ANSI, using which English characters are represented. And lets say 2-byte character is Unicode, which can represent ALL languages in the world.
VC++ support char and wchar_t as native datatypes for ANSI and Unicode characters respectively.
What if you want your C/C++ program to be Character-mode independent?
That means, instead of replacing:
char cResponse; // 'Y' or 'N'
char sUsername[64];
// str* functions
with
wchar_t cResponse; // 'Y' or 'N'
wchar_t sUsername[64];
// wcs* functions
You can simply code it:
#include<TCHAR.H> // Implicit or explicit include
TCHAR cResponse; // 'Y' or 'N'
TCHAR sUsername[64];
// _tcs* functions
Thus, when your project is being compiled as Unicode, the TCHAR would translate to wchar_t. If it is being compiled as ANSI/MBCS, it would translated to char. Likewise, instead of using strcpy, strlen, strcat (including the secure versions suffixed with _s); or wcscpy, wcslen, wcscat (including secure), you can simply use _tcscpy, _tcslen, _tcscat functions.
When you need to express hard-coded string, you can use:
"ANSI String"; // ANSI
L"Unicode String"; // Unicode
_T("Either string, depending on compilation"); // ANSI or Unicode
// or use TEXT macro, if you need more readability.
The non-prefixed string is ANSI string, the L prefixed string is Unicode, and string specified in _T or TEXT would be either, depending on compilation.
String classes, like MFC/ATL's CString implement two version using macro. There are two classes named CStringA for ANSI, CStringW for Unicode. When you use CString (which is a macro/typedef), it translates to either of two classes.
Okay. The TCHAR type-definition was for a single character. You can definitely declare an array of TCHAR.
What if you want to express a character-pointer, or a const-character-pointer - Which one of the following?
// ANSI characters
foo_ansi(char*);
foo_ansi(const char*);
/*const*/ char* pString;
// Unicode/wide-string
foo_uni(WCHAR*); // or wchar_t*
foo_uni(const WCHAR*);
/*const*/ WCHAR* pString;
// Independent
foo_char(TCHAR*);
foo_char(const TCHAR*);
/*const*/ TCHAR* pString;
After reading about TCHAR stuff, you'd definitely select the last one as your choice. But here is better alternative. Before that, note that TCHAR.H header file declares only TCHAR datatype and for the following stuff, you need to include Windows.h (defined in WinNT.h).
NOTE: If your project implicitly or explicitly includes Windows.h, you need not to include TCHAR.H
char* replacement: LPSTR
const char* replacement: LPCSTR
WCHAR* replacement: LPWSTR
const WCHAR* replacement: LPCWSTR (C before W, since const is before WCHAR)
TCHAR* replacement: LPTSTR
const TCHAR* replacement: LPCTSTR
Read more: Codeproject
In general, a character can be 1 byte or 2 bytes. Lets say 1-byte character is ANSI, using which English characters are represented. And lets say 2-byte character is Unicode, which can represent ALL languages in the world.
VC++ support char and wchar_t as native datatypes for ANSI and Unicode characters respectively.
What if you want your C/C++ program to be Character-mode independent?
That means, instead of replacing:
char cResponse; // 'Y' or 'N'
char sUsername[64];
// str* functions
with
wchar_t cResponse; // 'Y' or 'N'
wchar_t sUsername[64];
// wcs* functions
You can simply code it:
#include<TCHAR.H> // Implicit or explicit include
TCHAR cResponse; // 'Y' or 'N'
TCHAR sUsername[64];
// _tcs* functions
Thus, when your project is being compiled as Unicode, the TCHAR would translate to wchar_t. If it is being compiled as ANSI/MBCS, it would translated to char. Likewise, instead of using strcpy, strlen, strcat (including the secure versions suffixed with _s); or wcscpy, wcslen, wcscat (including secure), you can simply use _tcscpy, _tcslen, _tcscat functions.
When you need to express hard-coded string, you can use:
"ANSI String"; // ANSI
L"Unicode String"; // Unicode
_T("Either string, depending on compilation"); // ANSI or Unicode
// or use TEXT macro, if you need more readability.
The non-prefixed string is ANSI string, the L prefixed string is Unicode, and string specified in _T or TEXT would be either, depending on compilation.
String classes, like MFC/ATL's CString implement two version using macro. There are two classes named CStringA for ANSI, CStringW for Unicode. When you use CString (which is a macro/typedef), it translates to either of two classes.
Okay. The TCHAR type-definition was for a single character. You can definitely declare an array of TCHAR.
What if you want to express a character-pointer, or a const-character-pointer - Which one of the following?
// ANSI characters
foo_ansi(char*);
foo_ansi(const char*);
/*const*/ char* pString;
// Unicode/wide-string
foo_uni(WCHAR*); // or wchar_t*
foo_uni(const WCHAR*);
/*const*/ WCHAR* pString;
// Independent
foo_char(TCHAR*);
foo_char(const TCHAR*);
/*const*/ TCHAR* pString;
After reading about TCHAR stuff, you'd definitely select the last one as your choice. But here is better alternative. Before that, note that TCHAR.H header file declares only TCHAR datatype and for the following stuff, you need to include Windows.h (defined in WinNT.h).
NOTE: If your project implicitly or explicitly includes Windows.h, you need not to include TCHAR.H
char* replacement: LPSTR
const char* replacement: LPCSTR
WCHAR* replacement: LPWSTR
const WCHAR* replacement: LPCWSTR (C before W, since const is before WCHAR)
TCHAR* replacement: LPTSTR
const TCHAR* replacement: LPCTSTR
Read more: Codeproject