编写、映射和排序 EUDC 和 PUA 字符

应用程序使用 TextOutExtTextOut 等输出函数,将最终用户定义字符 (EUDC) 和专用区域 (PUA) 字符写入屏幕或打印机。 如果启用了 EUDC,这些函数会自动从 EUDC 或 PUA 字符字体中检索字符信息。 有关详细信息,请参阅 end-User_Defined 和 Private Use Area Characters

编写 EUDC 或 PUA 字符时,文本输出函数的操作取决于当前所选字体。 如果所选字体是集成的 EUDC 或 PUA 字符字体,则函数将从该字体中检索字符信息。 如果所选字体是双 字节字符集 , (DBCS) TrueType 字体具有关联的单独 EUDC 字体,则函数将从指定的 EUDC 字体中检索信息。 同样,如果所选字体是具有关联的单独 PUA 字符字体的 Unicode TrueType 字体,则函数将从 PUA 字符字体中检索信息。 如果所选字体没有关联的 EUDC 或 PUA 字符字体,则函数将从系统默认的 EUDC 字体中检索信息。 如果该字符不在系统默认的 EUDC 字体中,或者没有系统默认的 EUDC 字体,则函数将写入由所选字体定义的默认字符。

应用程序可以使用 MultiByteToWideCharWideCharToMultiByte 函数将 EUDC 映射到 Unicode 和 Unicode。 MultiByteToWideChar 函数将大多数 EUDC 映射到 Unicode PUA 中的字符。 但是,为了支持某些国家或地区标准,某些 EUDC 可以映射到非 PUA Unicode 码点。 WideCharToMultiByte 函数将 PUA 中的字符映射到其 EUDC 对应字符(如果此类映射存在并且代码点在 Unicode 中没有有效的非 PUA 映射)。 并非所有代码页都有 EUDC 范围。 调用 WideCharToMultiByte 中指定的代码页必须包含 EUDC 代码范围,才能映射到 EUDC 范围。 如果代码页不包含 EUDC 代码范围,则 函数将检索 Unicode PUA 中任何字符的默认字符。

MultiByteToWideCharWideCharToMultiByte 不保证往返映射。 换句话说,可以先从包含 EUDC 的特定多字节字符串开始,使用 MultiByteToWideChar 将字符串映射到 Unicode,并使用 WideCharToMultiByte 将其映射回原始 DBCS,最终得到的结果与原始字符串不同。 依赖于将 EUDC 映射到 Unicode 的应用程序应确保所有必需的字符都可以在相应的代码页 EUDC 区域和 Unicode PUA 之间往返。

应用程序不应尝试将 EUDC 从一个代码页映射到另一个代码页。 如果应用程序从一个代码页以 EUDC 开头,使用 MultiByteToWideChar 将其映射到 Unicode,并使用 WideCharToMultiByte 映射到其他 DBCS,则无法保证结果。 原始字符可能映射到目标代码页中的其他 EUDC,也可以映射为未定义的字符。 同样,将 Unicode 字符串映射到具有 EUDC 范围的代码页可能会产生意外结果。 如果 Unicode 字符串包含 PUA 码位,则代码点可能会映射到不表示相同字符的 EUDC。

应用程序可以使用 AnSI 版本的 CompareString 函数来比较包含 EUDC 的 DBCS 字符串。 函数在比较字符值之前有效地将字符映射到 Unicode。 应用程序可以使用 LCMapString 函数的 ANSI 版本和LCMAP_SORTKEY值为字符串创建排序键。 此函数首先有效地将字符映射到 Unicode。 PUA 中的所有字符都按所有其他 Unicode 字符排序。 在区域中,字符按数字顺序排序。 如果应用程序尝试使用 GetStringTypeA 函数检索 EUDC 的 CTYPE 信息,则该函数将检索每个字符的 NULL

使用 Unicode 和字符集