Why are there different TEXT like macros for the same thing in win32?

As it is often the case with "arcane" things, Raymond Chen gives some information (emphasis added):

So what's with all these different ways of saying the same thing? There's actually a method behind the madness.

The plain versions without the underscore affect the character set the Windows header files treat as default. So if you define UNICODE, then GetWindowText will map to GetWindowTextW instead of GetWindowTextA, for example. Similarly, the TEXT macro will map to L"..." instead of "...".

The versions with the underscore affect the character set the C runtime header files treat as default. So if you define _UNICODE, then _tcslen will map to wcslen instead of strlen, for example. Similarly, the _TEXT macro will map to L"..." instead of "...". What about _T? Okay, I don't know about that one. Maybe it was just to save somebody some typing.


For many macros, there is the Win32 one and the one for the C run-time library. That would explain TEXT (Win32) and _TEXT (C run-time library). The double-underscore versions are probably helper macros not intended for general use. The T is probably a convenience for those who think TEXT is too long.


The UNICODE symbol affects the declarations in Windows API headers (primarily <windows.h>), while the _UNICODE and _MBCS symbols affect the declarations in the C library.

Windows API example: with UNICODE defined MessageBox maps to MessageBoxW, in Windows terminology the Unicode version, while with UNICODE undefined MessageBox maps to MessageBoxA, the ANSI version.

A C library example is more involved.

In spite of two symbols _UNICODE and _MBCS there are just three cases that are distinguished:

  • None of them defined, and e.g. _tcslen maps to strlen, the narrow character version.

  • _MBCS defined and _UNICODE not defined, and e.g. _tcsclen maps to _mbslen, the multi-byte character version.

  • _UNICODE defined and _MBCS not defined, and e.g. _tcslen maps to wcslen, the wide character version.

It's worth noting that all this stuff was in support of Windows 9x, which did not have a wide character API.

However, in 2001 Microsoft introduced the Layer for Unicode, which essentially provided a wide character API for Windows 9x. And with that, the whole scheme above was obsoleted except for one case, that of using MFC as DLLs in Windows 9x, and being unable or unwilling to rebuild it. Well, also except that whoever maintains Visual Studio's code generation has, as of version 11, not yet caught on to that fact of ten years ago, and that this in turn misleads hordes of newbies, who then as professionals are seriously unwilling to stop using this non-productive time wasting scheme.