Uso de páginas de códigos UTF-8 en aplicaciones de Windows

Use la codificación de caracteres UTF-8 para obtener una compatibilidad óptima entre las aplicaciones web y otras plataformas basadas en *nix (Unix, Linux y variantes), minimizar los errores de localización y reducir la sobrecarga de pruebas.

UTF-8 es la página de códigos universal para la internacionalización y puede cifrar todo el conjunto de caracteres Unicode. Se usa de manera generalizada en la web y es el valor predeterminado para las plataformas basadas en *nix.

Establecer una página de códigos de proceso en UTF-8

A partir de la versión 1903 de Windows (actualización de mayo de 2019), puede utilizar la propiedad ActiveCodePage en appxmanifest para las aplicaciones empaquetadas o el manifiesto de fusión para las aplicaciones sin empaquetar, para forzar un proceso a utilizar UTF-8 como página de códigos del proceso.

Nota:

GDI no admite actualmente la configuración de la propiedad ActiveCodePage por proceso. En su lugar, GDI tiene como valor predeterminado la página de códigos del sistema activa. Para configurar la aplicación para que represente texto UTF-8 a través de GDI, vaya a Windows Configuración>Hora e idioma>Idioma y región>Configuración administrativa de idioma>Cambiar configuración regional del sistema y active Beta: utilizar Unicode UTF-8 para la compatibilidad con idiomas en todo el mundo. Reinicie el PC para que el cambio surta efecto.

Puede declarar la propiedad ActiveCodePage y destinarla o ejecutarla en compilaciones anteriores de Windows, pero debe controlar la detección y la conversión de páginas de códigos heredadas de la forma habitual. Con una versión de destino mínima de la versión 1903 de Windows, la página de códigos de proceso siempre será UTF-8, por lo que se puede evitar la detección y conversión de páginas de códigos heredadas.

Nota:

Un carácter codificado toma entre 1 y 4 bytes. La codificación UTF-8 admite secuencias de bytes más largas, hasta 6 bytes, pero el punto de código más grande de Unicode 6.0 (U+10FFFF) solo utiliza 4 bytes.

Ejemplos

Manifiesto appx para una aplicación empaquetada:

<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
         ...
         xmlns:uap7="http://schemas.microsoft.com/appx/manifest/uap/windows10/7"
         xmlns:uap8="http://schemas.microsoft.com/appx/manifest/uap/windows10/8"
         ...
         IgnorableNamespaces="... uap7 uap8 ...">

  <Applications>
    <Application ...>
      <uap7:Properties>
        <uap8:ActiveCodePage>UTF-8</uap8:ActiveCodePage>
      </uap7:Properties>
    </Application>
  </Applications>
</Package>

Manifiesto de fusión para una aplicación de Win32 sin empaquetar:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
  <assemblyIdentity type="win32" name="..." version="6.0.0.0"/>
  <application>
    <windowsSettings>
      <activeCodePage xmlns="http://schemas.microsoft.com/SMI/2019/WindowsSettings">UTF-8</activeCodePage>
    </windowsSettings>
  </application>
</assembly>

Nota:

Agregue un manifiesto a un archivo ejecutable existente desde la línea de comandos con mt.exe -manifest <MANIFEST> -outputresource:<EXE>;#1.

API -A frente a -W

Las API Win32 a menudo admiten variantes -A y -W.

Las variantes -A reconocen la página de códigos ANSI configurada en el sistema y admite char*, mientras que las variantes -W funcionan en UTF-16 y admiten WCHAR.

Hasta hace poco, Windows ha resaltado las variantes "Unicode" -W en las API -A. Sin embargo, las versiones recientes han usado la página de códigos ANSI y las API -A como medio para introducir la compatibilidad con UTF-8 a las aplicaciones. Si la página de códigos ANSI está configurada para UTF-8, las API -A normalmente funcionan en UTF-8. Este modelo tiene la ventaja de admitir código existente creado con las API -A sin cambios en el código.

Conversión de páginas de códigos

Dado que Windows funciona de forma nativa en UTF-16 (WCHAR), es posible que deba convertir los datos UTF-8 a UTF-16 (o viceversa) para interoperar con las API de Windows.

MultiByteToWideChar y WideCharToMultiByte permiten convertir entre UTF-8 y UTF-16 (WCHAR) (otras páginas de códigos). Esto resulta especialmente útil cuando una API Win32 heredada solo puede comprender WCHAR. Estas funciones permiten convertir la entrada UTF-8 en WCHAR para pasar a una API -W y, luego, convertir los resultados de nuevo si es necesario.

Use dwFlags de 0 o MB_ERR_INVALID_CHARS cuando se usan estas funciones con CodePage establecido en CP_UTF8 (de lo contrario, se produce una excepción ERROR_INVALID_FLAGS).

Nota:

CP_ACP equivale a CP_UTF8 solo si se ejecuta en la versión 1903 de Windows (actualización de mayo de 2019) o posterior y la propiedad ActiveCodePage descrita anteriormente se establece en UTF-8. De lo contrario, respeta la página de códigos del sistema heredado. Se recomienda usar explícitamente CP_UTF8.