VC PlusPlus:MUI(Multilingual User Interface)のリソースファイルの作り方 言語別リソース

提供:yonewiki

VC Cpp記事に戻る。

概要

 MUIに関する情報はMicrosoft公式の情報が詳しいです。このSiteでもわかりやすく記事にしようと思っていますが、記事の作成には時間がかかるだろうなと思います。


 まず、日本語と英語だけのMUIを作ってみたいと思います。以下のような形式になります。


 プロジェクトの中で言語別にリソースファイル・リソーススクリプトを所持します。ここではMultilingualApp(MultilingualApp.vcxproj)というプロジェクトにMultilingualApp.exeというアプリを作成するものに対して、日本語のリソーススクリプトMultilingualApp.ja-JP.rcと英語のリソーススクリプトMultilingualApp.en-US.rcが用意されているとして説明します。


 MUIを使うとMultilingualApp.exeという実行ファイルがある階層に作られるja-JPフォルダに日本語のリソースであるMultilingualApp.exe.muiやen-USフォルダに英語リソースであるMultilingualApp.exe.muiを配置します。


 通常VisualStudioでプロジェクトにリソースを参加させた場合、プロジェクト名と同じリソースが生成されるので手動でリソースファイルの名前を変更したり、コピーを作って、言語に関する部分の変更を加えたリソースファイルを作ったりして、MultilingualApp.ja-JP.rcとMultilingualApp.en-US.rcのようなものを作成する必要があります。


 そうして、MultilingualApp.vcxprojの中身を手動で以下のように書き換えます。リソースが複数できるので、リソースはMultilingualApp.vcxprojの階層にResourceっていうフォルダを作り、その中にいれて管理します。

 

.vcxprojにmuiResourceとしてリソースを定義する

 以下の通りに記述します。


元のMultilingualApp.vcxprojのリソース定義部分の例

  <ItemGroup>
    <ResourceCompile Include="MultilingualApp.rc" />
  </ItemGroup>


変更後のMultilingualApp.vcxprojのリソース定義部分の例

  <ItemGroup>
    <MuiResourceCompile Include="Resource\MultilingualApp.en-US.rc">
      <FileType>Document</FileType>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">en-US</MuiCulture>
      <GenerateLanguageNeutralResource Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateLanguageNeutralResource>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">en-US</MuiCulture>
      <GenerateLanguageNeutralResource Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</GenerateLanguageNeutralResource>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">en-US</MuiCulture>
      <GenerateLanguageNeutralResource Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</GenerateLanguageNeutralResource>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Release|x64'">en-US</MuiCulture>
      <GenerateLanguageNeutralResource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</GenerateLanguageNeutralResource>
    </MuiResourceCompile>
    <MuiResourceCompile Include="Resource\MultilingualApp.ja-JP.rc">
      <FileType>Document</FileType>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">ja-JP</MuiCulture>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ja-JP</MuiCulture>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">ja-JP</MuiCulture>
      <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ja-JP</MuiCulture>
    </MuiResourceCompile>
  </ItemGroup>


 と、このようにします。一気に定義が増えましたがResourceCompileタグがMuiResourceCompileタグに変わって、二つのリソースファイル用に


  • <MuiResourceCompile Include="Resource\MultilingualApp.en-US.rc">
  • <MuiResourceCompile Include="Resource\MultilingualApp.ja-JP.rc">


という二つを定義して、その中に子タグがぶら下がっている感じになっています。子タグは


  • <MuiCulture Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">en-US</MuiCulture>


 として、en-USなら、実行環境が英語圏の地域の設定になっていれば、MultilingualApp.en-US.rcを使うという意味を持ちます。


 さらに英語のリソースファイルの子タグにだけ


  • <GenerateLanguageNeutralResource Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</GenerateLanguageNeutralResource>


 という設定をしているので、他のリソースで定義されていないものがあれば、このGenerateLanguageNeutralResourceがTrueになっているリソースを参照しようとする宣言です。今回の場合は、リソース定義が当該地域に対して定義されていない場合、Resource\MultilingualApp.en-US.rcを参照しようとします。複数のリソース定義がされている中の一つにだけTrueを設定します。複数のリソースにこの子タグが設定されているとビルドエラーが発生します。こういうのが定義されているリソースファイルを言語中立のリソースファイルと呼びます。

 

.rcconfigで言語中立の対象となるリソースと地域設定をする対象となるリソースの種類を定義

 この部分の設定はまだMUIの序章に過ぎません。そうしたいと思った程度の領域です。


 vcxprojファイルにMUIのための*.rcconfigというリソース設定ファイルを各構成ファイルごとに作成、設置する作業をします。*.rcconfigには、リソースの種類ごとにどれが、言語中立のリソースファイルの対象にするか?リソースの種類のどれを地域ごと、言語ごとのリソースファイルにするかというのを指定します。例えば、リソースの種類の内、HTML、アイコン、カーソル、マニュフェストだけを言語中立の対象として、地域ごと、言語ごとはHTML、アイコン、カーソル、マニュフェスト、メニュー、ダイアログボックス、文字列テーブル、バージョン情報という種類を対象にするなら以下のようなファイルになります。


MultilingualApp.rcconfig

<?xml version="1.0" encoding="utf-8"?>
<localization>
  <resources>
    <win32Resources fileType="Application">
      <neutralResources>
        <resourceType typeNameId="#2"/><!--アイコン-->
        <resourceType typeNameId="#3"/><!--カーソル-->
        <resourceType typeNameId="#9"/><!--HTML-->
        <resourceType typeNameId="RT_MANIFEST"/><!--マニュフェスト-->
      </neutralResources>
      <localizedResources>
        <resourceType typeNameId="#2"/><!--アイコン-->
        <resourceType typeNameId="#3"/><!--カーソル-->
        <resourceType typeNameId="#9"/><!--HTML-->
        <resourceType typeNameId="RT_MANIFEST"/><!--マニュフェスト-->

        <resourceType typeNameId="#4"/><!--メニュー-->
        <resourceType typeNameId="#5"/><!--ダイアログ-->
        <resourceType typeNameId="#6"/><!--文字列-->
        <resourceType typeNameId="#241"/><!--バージョン情報-->
      </localizedResources>
    </win32Resources>
  </resources>
</localization>


 というファイルを作ったらMultilingualApp.vcxprojファイルの中のそれぞれの構成(32bit・64bit Debug・リリースの組み合わせで4種類くらいはあるのが普通)に対して、以下のような、ハイライトした部分のようなXMLを挿入します。


<!--省略-->
  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
    <ClCompile>
      <!--省略-->
    </ClCompile>
    <ResourceCompile>
      <!--省略-->
    </ResourceCompile>
    <Link>
      <!--省略-->
    </Link>
    <MuiResourceCompile>
      <RCConfigFileName>Resource\MultilingualApp.rcconfig</RCConfigFileName>
    </MuiResourceCompile>
<!--省略-->

 

.targetsでファイルをインポートしてMSBuildフォーマットで.exe.muiファイルを生成するように記述

 まだまだ、あります。.exe.muiファイルを生成するにはMSBuildフォーマットで処理を記載しますが、外だしにして管理した方がわかりやすいくらい複雑なので、インポートする形式を使います。仮にインポートするファイルの名前をMuiResourceCompile.targetsという名前として話を進めます。Multilingual.vcxprojファイルの中でMuiResourceCompile.targetsファイルをインポートします。MuiResourceCompile.targetsファイルにはMultilingualApp.exe.muiというファイルを生成するためのスクリプトを記述します。スクリプトの説明はかなりややこしいので、まずは、MultilingualApp.vcxprojファイルにインポートする記述から紹介します。他のimportタグの記述が既存であると思うので、最後に記述するとよいですね。


<!--省略-->
  <Import…省略
  <Import Project="$(MSBuildThisFileDirectory)MuiResourceCompile.targets" />
<!--省略-->

 

MSBuildフォーマットでリソースをコンパイルリンク

 MuiResourceCompile.targetsファイルの中でコンパイルリンク処理を設定します。実行したいコマンドは以下の流れですね。


 最初にStep1です。言語中立リソースでもある、英語版のリソースは


  • rc /l "0x0409" /nologo /fo "Debug\x64\(ProjectName).en-US.ln.res" /q Resource\(ProjectName).rcconfig /fm "Debug\x64\(ProjectName).en-US.res" "Resource\(ProjectName).en-US.rc"


という処理をして、日本語版のリソースは


  • rc /l "0x0409" /nologo /q Resource\(ProjectName).rcconfig /g1 /fm "Debug\x64\(ProjectName).ja-JP.res" "Resource\(ProjectName).ja-JP.rc"


という処理をします。これで、Resourceフォルダの中にある(ProjectName).rcconfigと(ProjectName).en-US.rcや(ProjectName).ja-JP.rcからDebug\x64\(ProjectName).en-US.resやDebug\x64\(ProjectName).en-US.ln.resとDebug\x64\(ProjectName).ja-JP.resを生成します。以下のrcコマンドで使ったオプションを解説します。*.rcファイルはコンパイルする対象のVisualStudioで編集可能なリソースファイルであり、必須の引数です。


  • /l "0x0409"でen-USの言語でコンパイル。


  • /nologoは大したことありません。コマンドを実行したときに表示されるリソースコンパイルのバージョンや著作権表示を隠すというそれだけの設定です。あっても気にならない。


  • /foのオプションの後に*.ln.resのような言語中立リソースを出力します。


  • /qのオプションの後にMUIリソース構築定義をした *.rcconfigファイルを指定します。


  • /g1で言語特有のリソースファイルを作ります。


  • /fmで出力するファイルのフォルダ名やファイル名を自動化せずに指定できます。自動だと*.rcファイルと同じ場所に *.resファイルが生成されてしまいます。


 次が、Step2です。英語版は以下のリンクコマンドです。


 プログラムファイルを生成する際のファイル群に言語中立リソース *.ln.resファイルを追加


  • link /ERRORREPO RT:QUEUE /OUT:"Debug\x64\(Project).exe" /INCREMENTAL /ILK:"Debug\x64\(Project).ilk"
 /NOLOGO (library).lib … (library).lib
 /DELAYLOAD:(Delayload).dll 
 …
 /DELAYLOAD:(Delayload).dll 
 /MANIFEST:NO /DEBUG:FULL /PDB:"Debug\x64\(Project).pdb" /SUBSYSTEM:WINDOWS /TLBID:1 /DYNAMICBASE /NXCOMPAT 
 /IMPLIB:"Debug\x64\(Project).lib" 
 /MACHINE:X64 
 Debug\x64\(ProgramFiles).obj
 …
 Debug\x64\(ProgramFiles).obj
 "Debug\x64\(Project).en-US.ln.res"


 英語版リソースのリンク処理


  • link /OUT:"C:\Users\(UserID)\source\repos\(ProjectName)\Debug\x64\en-US\(Project).exe.mui" /NOLOGO /NOENTRY /MACHINE:X64 /DLL "Debug\x64\(ProjectName).en-US.res"


 日本語版リソースのリンク処理


  • link /OUT:"C:\Users\(UserID)\source\repos\(ProjectName)\Debug\x64\ja-JP\(ProjectName).exe.mui" /NOLOGO /NOENTRY /MACHINE:X64 /DLL "Debug\x64\(ProjectName).ja-JP.res"

 

 MSBuildフォーマットというものを理解しなければなりませんが、ここでは使うものだけの役割に絞って話を進めていきます。

 

VC Cpp記事に戻る。