WinAPI Unicode 和 ANSI 函数

WinAPI Unicode and ANSI functions

大多数 WinAPI 调用有 UnicodeANSI 函数调用

例如:

function MessageBoxA(hWnd: HWND; lpText, lpCaption: LPCSTR; uType: UINT): Integer; stdcall;external user32;

function MessageBoxW(hWnd: HWND; lpText, lpCaption: LPCWSTR; uType: UINT): Integer; stdcall; external user32;

我什么时候应该使用 ANSI 函数而不是调用 Unicode 函数?

要遵循的最简单规则是:仅在没有 Unicode 变体的系统上使用 ANSI 变体。那是在 Windows 95、98 和 ME 上,它们是不支持 Unicode 的 Windows 版本。

如今,您不太可能以此类版本为目标,因此您很可能始终只使用 Unicode 变体。

正如 posted comments/answers 的(罕见)例外...

在需要和支持 UTF-8 的情况下,可以选择使用 ANSI 调用。例如,WriteConsoleA'ing 控制台中的 UTF-8 字符串设置为使用 TT 字体和 chcp 65001 下的 运行。

另一个奇怪的例外是主要作为 ANSI 实现的函数,其中 Unicode "W" 变体简单地转换为活动代码页中的窄字符串并调用 "A" 对应物。对于这样的函数,当有窄字符串可用时,直接调用 "A" 变体可以省去多余的双重转换。典型的例子是 OutputDebugString,它在 Windows 10 之前属于此类(我刚刚注意到 https://msdn.microsoft.com/en-us/library/windows/desktop/aa363362.aspx 提到调用 WaitForDebugEventEx - 仅在 Windows 10 之后可用 - 启用真正的 Unicode 输出OutputDebugStringW).

还有一些 API,即使处理字符串,它们本身也是 ANSI。例如 GetProcAddress 仅存在于采用 LPCSTR 参数的 ANSI 变体中,因为导出表中的名称是窄字符串。

就是说,大部分与字符串相关的 API 本身都是 Unicode,并且鼓励使用 "W" 变体。并非所有较新的 API 甚至都不再具有 "A" 变体(例如 CommandLineToArgvW). From the horses's mouth https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407.aspx:

Windows natively supports Unicode strings for UI elements, file names, and so forth. Unicode is the preferred character encoding, because it supports all character sets and languages. Windows represents Unicode characters using UTF-16 encoding, in which each character is encoded as a 16-bit value. UTF-16 characters are called wide characters, to distinguish them from 8-bit ANSI characters.

[...] When Microsoft introduced Unicode support to Windows, it eased the transition by providing two parallel sets of APIs, one for ANSI strings and the other for Unicode strings.

[...] Internally, the ANSI version translates the string to Unicode. The Windows headers also define a macro that resolves to the Unicode version when the preprocessor symbol UNICODE is defined or the ANSI version otherwise.

[...] Most newer APIs in Windows have just a Unicode version, with no corresponding ANSI version.

[ 注意 ] post 已编辑以添加最后两段。