Your browser doesn't support JavaScript Data Types and Character Sets – Windows Programming

Data Types and Character Sets

Data Types in Win32 API

The Windows API does not rely primarily on the standard C/C++ data types. Instead, it defines its own collection of data types using typedef declarations in the windows.h header file. While many Win32 data types are available, only a relatively small number are used in most Windows applications. The most important of these are listed below.

Basic Integer Types:
BOOL – Boolean value (TRUE or FALSE)
INT – A 32-bit signed integer. Normal C-style integer. Declared as typedef int INT;
UINT – A 32-bit unsigned integer. Declared as typedef unsigned int UINT;
DWORD – A 32-bit unsigned integer. Windows system/hardware terminology
LONG – A 32-bit signed integer
BYTE – The same as unsigned char. Declared as typedef unsigned char BYTE;

Handles:
A handler is an identifier that refers to an internal Windows object.
HINSTANCE – A handle to the application instance.
HDC – A device context handle
HMENU – A handle to a menu.
HFONT – A handle to a font.
HBITMAP – A handle to a bitmap.
HBRUSH – A handle to a brush.

String Types (Modern Usage)
LPCWSTR – pointer to a constant null-terminated UTF-16 string.
LPWSTR – A 32-bit pointer to a string of 16-bit Unicode characters, which may be null-terminated.
LPCTSTR – An LPCWSTR if UNICODE is defined, or an LPCSTR otherwise. Now depreciated still exists for backward compatibility
LPTSTR – An LPWSTR if UNICODE is defined, or an LPSTR otherwise. Now depreciated still exists for backward compatibility.
TCHAR – A WCHAR if UNICODE is specified, or a CHAR otherwise. Now depreciated still exists for backward compatibility

For a full list of Windows data types
https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types

Identifier Constants

Windows programs make extensive use of named constants, often referred to as identifiers, to represent numerical values. These identifiers are usually written in uppercase and consist of a two- or three-letter prefix that identifies the category, followed by an underscore and a descriptive constant name. Some of the most common prefixes and their associated message types are listed below.

Prefix Description Example
CS Class style CS_HREDRAW | CS_VREDRAW
CW Create window CW_USEDEFAULT CW_USEDEFAULT
DT Draw text DT_CENTER DT_LEFT DT_RIGHT
IDI Icon identifier IDI_ASTERISK IDI_ERROR IDI_HAND
IDC Cursor identifier IDC_ARROW IDC_HAND
MB Message box options MB_HELP MB_OK MB_OKCANCEL
SND Sound option SND_ASYNC SND_NODEFAULT
WM Window message WM_NULL WM_CREATE WM_DESTROY
WS Window style WS_OVERLAPPED WS_SYSMENU WS_BORDER

Naming conventions

Microsoft traditionally used a naming convention known as Hungarian notation. In this convention, variables are prefixed with a short, lowercase abbreviation indicating their data type, followed by a descriptive name beginning with a capital letter. Function names do not use type prefixes and instead begin with a capital letter. Although modern C++ code often favours more descriptive naming conventions, Hungarian notation is still widely encountered in Win32 API programming and older Microsoft code.For further reading on MS coding style conventions

https://docs.microsoft.com/en-us/windows/win32/stg/coding-style-conventions

Character sets

Computers store text and numbers as patterns of binary digits called character codes. To ensure that information can be exchanged reliably between different computers and applications, a standard is required to define the code assigned to each character. A complete collection of characters and their corresponding codes is called a character set. The two most common character sets are ASCII and Unicode. While ASCII remains important for compatibility and legacy systems, Unicode has become the standard for modern software because it supports a vastly larger range of characters and writing systems.

ASCII

ASCII is a character encoding system that can represent 128 characters. It uses 7 bits to represent each character since the first bit of the byte is always 0. The code set allows 95 printable characters and 33 non-printable Control characters.

Extended ASCII

Standard ASCII uses 7 bits to represent 128 characters, which is sufficient for the English alphabet, digits, punctuation, and control characters. However, it cannot represent the accented letters and special symbols required by many other languages.

Extended ASCII uses 8 bits, allowing up to 256 characters. Various extended ASCII encodings were developed to include additional accented characters and symbols for different languages. However, because there was no single universal extended ASCII standard, different code pages assigned different characters to the same values, leading to compatibility problems.

Although extended ASCII doubled the number of available characters, it still could not represent all of the world’s writing systems. As a result, it has largely been superseded by Unicode, which provides a universal character encoding capable of representing virtually every written language.

UNICODE

The Unicode Standard is a universal character-encoding standard designed to represent the characters and symbols used in virtually every written language. Each character is assigned a unique numerical value known as a code point.

A Unicode Transformation Format (UTF) defines how Unicode code points are encoded as sequences of bytes for storage and transmission. The two most widely used Unicode encoding formats are UTF-8 and UTF-16.

UTF-8 is a variable-length encoding that uses between 1 and 4 bytes to represent each character. The first 128 Unicode code points are identical to those used by ASCII, making UTF-8 fully backward compatible with ASCII. This compatibility has contributed to UTF-8 becoming the dominant encoding for web pages, e-mail, and many modern applications.

UTF-16 is also a variable-length encoding, using either 2 or 4 bytes to represent a character. Unlike UTF-8, it is not directly compatible with ASCII because even ASCII characters are stored using 16-bit code units. Windows stores Unicode text internally using UTF-16 Little Endian (UTF-16LE), while older Windows applications may still use legacy ANSI code pages for non-Unicode text.

Unicode in the Windows API

Unicode has been the native character encoding used by Windows since Windows NT. Most Windows API functions that accept or return text are provided in three forms:

  • ANSI version, with an A suffix (for example, CreateWindowExA)
  • Unicode version, with a W suffix (for example, CreateWindowExW)
  • Generic version, with no suffix (for example, CreateWindowEx)

The generic function name is a macro defined in the Windows header files. At compile time, it is automatically mapped to either the ANSI or Unicode version, depending on whether the UNICODE preprocessor symbol is defined. In modern Windows applications, UNICODE is normally enabled by default, so generic function names are resolved to their Unicode (W) equivalents.

Working with Strings

C++ provides four built-in character types: char, wchar_t, char16_t, and char32_t.

The char type is an 8-bit character type commonly used to store ASCII text, UTF-8 encoded text, or characters from a system code page. The wchar_t type is intended for wide characters. Its size is implementation-dependent; on Windows it is 16 bits and is used to represent UTF-16 encoded text, whereas on many other platforms it is 32 bits.

C++11 introduced the fixed-width character types char16_t and char32_t to represent UTF-16 and UTF-32 code units respectively. Because these types have a fixed size on all platforms, they are preferable when writing portable Unicode code. However, when programming the Win32 API, wchar_t remains the standard character type used by Unicode functions.

String literals are prefixed to indicate the type of character string they contain:

char *ascii_example = "This is an ASCII string."; wchar_t *Unicode_example = L"This is a wide char string."; char16_t * char16_example = u"This is a char16_t Unicode string."; har32_t * char32_example = U"This is a char32_t Unicode string.";

TCHAR and the TEXT Macro

To simplify the development of applications that could be compiled for either ANSI or Unicode, Microsoft introduced the generic character type TCHAR. When the UNICODE preprocessor symbol is defined, TCHAR maps to wchar_t; otherwise, it maps to char. This allows the same source code to be compiled in either mode without modification.

To complement TCHAR, Microsoft also provides the TEXT() (or _T()) macro. This macro prefixes string literals appropriately so that they are treated as either ANSI or Unicode strings, depending on the compilation settings.

For example:

TCHAR* autoString = TEXT("This message can be either ANSI or Unicode!");

When compiled in Unicode mode, the statement above is equivalent to:

wchar_t* autoString = L"This message can be either ANSI or Unicode!";

When compiled in ANSI mode, it becomes:

char* autoString = "This message can be either ANSI or Unicode!";

Today, TCHAR and the TEXT() macro are generally regarded as legacy features. Modern Windows applications are developed using Unicode (UTF-16), and it is now common practice to use wchar_t and wide-character string literals (L"...") directly. Nevertheless, TCHAR and TEXT() remain fully supported and are still encountered in older Win32 codebases.

For further information on working with strings and character encoding in the Windows API, see:https://docs.microsoft.com/en-us/windows/win32/learnwin32/working-with-strings