Windows 在 16 位时代(版本1.0,2.x)和 16 / 32 位混合的时代初期(3.x),是不存在 Unicode 这个东西的。因此,早期的 Windows API 中,所有字符串都视为 ANSI 编码。Windows 3.0 中 / 日 / 韩文版引入了双字节字符集的概念,使得 Windows 开发中 ANSI 编码被称为所谓本地字符,并出现了 Windows 多区域支持(NLS National Language Support)。从 Windows NT 3.1 和开始,Windows 内部开始使用 UTF-16 作为字符串编码方式 (wchar_t),但是为了保证和以往 API 的兼容性,大多数和字符串有关的 API 函数都有 A 和 W 两个后缀的不同版本,A 代表传统的本地字符编码处理,W 代表UTF-16处理。在使用 C 语言进行 Windows 编程的时候,一般不直接使用后缀来选择不同版本的 API,而是通过在 <windows.h> 相关文件中通过处理宏 UNICODE 来选择。同时,NLS 也扩展到可以在多种内码之间互相转换,而 Unicode 的几种存储形式(UTF-16、UTF-8、UTF-7)也被 NLS 所支持。
虽然微软早已提供了原生的 UTF-16 支持,但是早期此支持仅仅在 Windows NT 系列操作系统中完整存在,而当时的主流是 16 / 32 位混合的 Windows 9x 系统,大多数 W 后缀的 API 调用都是不支持的,仅仅支持通过 NLS API 进行内码之间的转换。另外,同样为了保持和以往 API 的兼容性, wchar_t 类型的字符串在微软的 C 运行库里采用了一套不符合 ANSI C 标准的新函数(比如 sprintf -> swprintf, strcpy -> wcscpy)等来处理,不符合绝大多数 C 程序员的习惯。因此,当时很大一部分程序,甚至包括微软自己的 Office 系列都没有使用 Windows NT 的原生字符集 UTF-16,需要处理 UTF-16 时只是通过 MultiByteToWideChar 之类的 NLS 相关 API 进行转换。而为了兼容在这个传统下写出来的老应用程序,之后所有的 Windows 系统都同时存在和使用两套原生支持的字符集,NT 原生字符集(UTF-16) 以及本地字符集。当然,在现代的 Windows 编程规范中,都是明确推荐使用原生 UTF-16 字符集的。