Windows アプリで UTF-8 コード ページを使用する
UTF-8 文字エンコードを使って Web アプリと他の *nix ベースのプラットフォーム (Unix、Linux など) との最適な互換性を確保し、ローカライズのバグを最小限に抑え、テストのオーバーヘッドを減らします。
UTF-8 は国際化のためのユニバーサル コード ページであり、Unicode 文字セット全体をエンコードすることができます。 Web では広く使われており、*nix ベースのプラットフォームではデフォルトとなっています。
プロセス コード ページを UTF-8 に設定する
Windows バージョン 1903 (2019 年 5 月の更新プログラム) 以降、パッケージ化されたアプリの場合は appx マニフェスト、パッケージ化されていないアプリの場合は fusion マニフェストの ActiveCodePage プロパティを使って、プロセスのコード ページとして UTF-8 を使うように強制できるようになりました。
Note
GDI は現在、プロセスごとの ActiveCodePage プロパティの設定をサポートしていません。 代わりに、GDI はデフォルトでアクティブなシステム コード ページに設定されます。 GDI 経由で UTF-8 テキストをレンダリングするようにアプリを構成するには、Windows の設定> 時刻と言語>言語と地域>管理言語設定>システム ロケールの変更 に移動し、 ベータ: 世界中の言語をサポートするには Unicode UTF-8 を使用します。 次に、変更を有効にするために PC を再起動します。
ActiveCodePage プロパティを宣言し、以前の Windows ビルドをターゲットにして実行することはできますが、レガシー コード ページの検出と変換は通常どおり処理する必要があります。 Windows バージョン 1903 の最小ターゲット バージョンの場合、プロセス コード ページは常に UTF-8 になるため、レガシ コード ページの検出と変換を回避することができます。
Note
エンコードされた文字は 1 から 4 バイトです。 UTF-8 では 6 バイトまでの長いバイト シーケンスをサポートしていますが、Unicode 6.0 の最大のコード ポイント (U+10FFFF) は 4 バイトしかありません。
例
パッケージ化されたアプリの場合は appx マニフェスト:
<?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>
パッケージ化されていない Win32 アプリの場合は fusion マニフェスト:
<?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>
Note
mt.exe -manifest <MANIFEST> -outputresource:<EXE>;#1
を使用して、コマンド ラインから既存の実行可能ファイルにマニフェストを追加します。
-A と -W API の比較
多くの場合、Win32 API は - A と - W の両方のバリアントをサポートしています。
-A バリアントの場合、システムに構成されている ANSI コード ページを認識することができ、char*
をサポートします。一方、-W バリアントの場合、UTF-16 で動作し、WCHAR
をサポートします。
最近まで、Windows では、-A API よりも「Unicode」の -W バリアントを重視してきました。 ただし、最近のリリースでは、アプリに UTF-8 サポートを導入する手段として、ANSI コード ページと -A API が使われています。 ANSI コード ページが UTF-8 用に構成されている場合、-A API は通常 UTF-8 で動作します。 このモデルには、-A API を使って構築した既存のコードを、コードを変更することなくサポートできるという利点があります。
コード ページ変換
Windows は UTF-16 (WCHAR
) でネイティブに動作するので、場合によっては、Windows API と相互運用するために UTF-8 データを UTF-16 (またはその逆) に変換する必要があります。
MultiByteToWideChar と WideCharToMultiByte を使うと、UTF-8 と UTF-16 (WCHAR
) (およびその他のコード ページ) の間で変換できます。 これは、レガシ Win32 API が WCHAR
しか理解しない場合に特に便利です。 これらの関数を使うと、UTF-8 の入力を WCHAR
に変換して -W API に渡し、必要に応じて結果を変換して戻すことができます。
dwFlags
を 0
に設定してこれらの機能を使用する場合は、MB_ERR_INVALID_CHARS
または CodePage
のいずれかの CP_UTF8
を使用します (そうでない場合は ERROR_INVALID_FLAGS
が発生します)。
Note
CP_ACP
が CP_UTF8
と同じになるのは、Windows バージョン 1903 (2019 年 5 月の更新プログラム) 以降で動作し、前述の ActiveCodePage プロパティが UTF-8 に設定されている場合のみです。 それ以外の場合は、レガシ システムのコード ページが使用されます。 CP_UTF8
を明示的に使うことをお勧めします。
関連トピック
Windows developer