大多数WinAPI调用都有Unicode
和ANSI
函数调用
例如:
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函数?
答案 0 :(得分:8)
与发布的评论/答案一样(罕见)例外......
在预期和支持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之后可用 - 为OutputDebugStringW启用真正的Unicode输出。)
然后有一些API,即使处理字符串,本身就是ANSI。例如,GetProcAddress仅存在于采用LPCSTR参数的ANSI变体中,因为导出表中的名称是窄字符串。
也就是说,大多数与字符串相关的API本身都是Unicode,鼓励使用“W”变体。并非所有较新的API都具有“A”变体(例如CommandLineToArgvW)。从马的嘴里https://msdn.microsoft.com/en-us/library/windows/desktop/ff381407.aspx:
Windows本身支持UI元素,文件名等的Unicode字符串。 Unicode是首选的字符编码,因为它支持所有字符集和语言。 Windows表示使用UTF-16编码的Unicode字符,其中每个字符都编码为16位值。 UTF-16字符称为宽字符,以区别于8位ANSI字符。
[...] 当Microsoft向Windows引入Unicode支持时,它通过提供两组并行的API来简化转换,一组用于ANSI字符串,另一组用于Unicode字符串。
[...] 在内部,ANSI版本将字符串转换为Unicode。 Windows标头还定义了一个宏,在定义预处理程序符号UNICODE时解析为Unicode版本,否则定义为ANSI版本。
[...] Windows中大多数较新的API只有一个Unicode版本,没有相应的ANSI版本。
[注意] 编辑帖子以添加最后两段。
答案 1 :(得分:4)
最简单的规则就是这样。仅在没有Unicode变体的系统上使用ANSI变体。这是在Windows 95,98和ME上,它们是实现Win32且不支持Unicode的Windows版本。
现在,您极不可能将这些版本作为目标,因此您应该始终使用Unicode变体。