syghの新フラグメント置き場

プログラミングTipsやコード断片の保管場所です。お絵描きもときどき載せます。

HTMLヘルプ作成でハマったこと

(これは2012-02-05に書いた故OCNブログの記事を移植したものです)

Visual StudioMFCアプリケーション プロジェクト ウィザードで、「高度な機能」の「コンテキスト ヘルプ(HTML)」ってのにチェックを入れておくと、HTMLヘルプ(コンパイル済みヘルプ、CHMファイル)をプロジェクト ビルド時に自動生成できるようにビルド アクションが自動設定されて便利なんですが、これでちょっとハマったのでTips。

アプリケーションのUI要素に応じたHTMLヘルプを作ってコンテキストヘルプ(状況依存のヘルプ)機能を活用する場合、各UI要素に割り当てられているリソースIDに応じたヘルプID(HID)というのを生成する必要があります。ヘルプ コマンド*1を機能させるためには、各HIDに対応したHTMLソースを作って、その関連付けを記述したHHPファイル*2をもとにヘルプ ファイルをビルドする必要があるわけですが、makehm.exe というコマンドライン ツールを使うと、リソースIDの定義が記述されたC/C++ヘッダーファイル(通常はresource.h)をもとにHIDが#define定義された別のヘッダーファイル*3を自動生成できます。このmakehmはVisual Studioに付いてくるんですが*4、どうもこのツールはANSIエンコード(日本語環境だとShift_JIS)のテキスト ファイルにしか対応してないようで、UTF-8/UTF-16LEとかのUnicodeエンコードされたファイルは解析不可能の模様。

VC++ではWindows SDKのリソース コンパイラrc.exe)を使ってリソース スクリプト(.rcファイル)をコンパイルして、結果をリンカ(link.exe)に渡すわけなんですが、このリソース スクリプトは国際化対応させる場合、普通 UTF-16LE を使います。rc.exeはANSIエンコードとUTF-16LEのみに対応してるんですが、ANSIエンコードだと複数の言語の混在やUnicode文字が使えないので、国際化対応させる場合は使うべきではありません。ここで、.rcファイルをUTF-16LEで保存して、VCのリソース エディタでシンボルを追加したりすると、対応する resource.h が自動的に同じUTF-16LEエンコードで保存されるようになっている模様。MFCプロジェクト ウィザードがresource.hに対して自動生成したカスタム ビルド コマンドライン アクションにはmakehmを使ったコマンドが登録されてるんですが、前述のようにmakehmはUTF-16LEに対応してないわけで、このままHTMLファイルを自動生成しようとするとハマるわけです。

これを回避するには、resource.h自体のエンコードをいちいちANSIに直すのではなく、resource.hのカスタム ビルド コマンドライン アクションを、まずtype.exeを使って一旦resource.hのエンコードANSIに変更して適当な別ファイル(例えばresource_h_ansi.hとか)に出力させて、resource.hの代わりにその別ファイルをmakehmに食わせるように変更するのが一番楽です。

これに気付くのに1時間くらい悩んでたんですが、テキスト エンコードの知識が多少なりともあったおかげで比較的早期に解決できました。例えいかなるプログラム言語を使おうとも、プログラマはやっぱりテキスト エンコードの知識は必須だと思います。これをきちんと知ってないと痛い目にあうどころか、国際化対応が重要視される今後はテキスト エンコードの知識くらい持ってないと、飯を食っていくことすら危うくなると思います。プロジェクトにINI形式なんか使ってるHTMLヘルプも相当時代遅れといえば時代遅れなんですけど……

Windows NT系列ではUTF-16が標準の文字コードで、C/C++のwchar_tもデフォルトでUTF-16として扱われるようになっています。また、Visual C#の文字列も最初からUTF-16のワイド文字列なので、WindowsプログラマーであればUTF-16の知識は必須と言っても過言ではありません。

ちなみに、Windows SDK付属のメッセージ コンパイラ(mc.exe)も、リソース コンパイラ同様にANSIとUTF-16LEに対応しているので、こいつに関してはビルド アクションに組み込むのは楽です。できればMSには全ツールをUTF-16LEに対応させて欲しいところです(さらにBOM付きUTF-8にも対応して欲しいところですが)。

HTMLヘルプについて

CHMファイルはヘルプを1パッケージとして配布するのに便利なんですが、いまどきCHMファイルを使うのは旧HLPファイル(WinHelp)と同じくらいナンセンスだと思います。普通に標準のHTMLやPDFを使えばいいんじゃないでしょうか。また、オンラインのほうが情報を更新しやすいので、最近はオフラインではなくオンラインでアプリケーションマニュアルを公開するのが主流になっています*5
ちなみにCHMファイルはIE専用*6ですが、生のHTMLだと任意のブラウザーで閲覧できるので、ブラウザー固有機能は使わないようにするか、複数のブラウザーできちんとテストしましょう。
なお、共有フォルダーなどのリモートコンピューター上のCHMファイルは、セキュリティ上の理由から既定では直接表示できないようになっています。ローカルにいったんコピーしてから閲覧する必要があります。

*1:コマンド ボタンを押すとカーソルが「?」になって、次に押したUI要素のHTMLヘルプ項目が表示されるようなコマンド。

*2:HTMLヘルプ プロジェクト ファイル、INI形式。

*3:慣例的に.hm拡張子が使われることが多いらしいが、中身は完全にC/C++ヘッダーファイル。

*4:%ProgramFiles(x86)%\Microsoft Visual Studio 10.0\Common7\Tools\とかにあります。

*5:AdobeやAutodeskなどは最新版だけでなく古いバージョンのソフトウェアに対するヘルプもオンラインで公開しています。

*6:Windowsに搭載されているIEコンポーネントがヘルプビューアーの内部でそのまま使われます。