02 VB6はデスクトップテーマに対応できるか(決定版)
検証環境 自作ATX(Cerelon533/VT6X4/384MB) WindowsXPPro/IE6.00Jp/VS6
えー、先日VB6はデスクトップテーマに対応できるか(暫定版)を書いてから、あんまり悔しぃんで 連日のように世界中のWebサイトやらニュースグループやらを探しまくっておりました。
…どぅしても見つかんない。
無理もないです。日本ではまだ(建前上)発売が開始されていませんし、本家アメリカでも発売されたばかり。
英語圏の掲示板やニュースグループでも、「VB製プログラムをWinXPのテーマに対応させる方法はありませんか」との質問が一切レスが付かずにむなしく書き込まれている状態です。
唯一手法を提示していたページは、私の前項に記述したのと同じ方法でした…。
さて、そんな四苦八苦を続けていたら、面白いツールを見つけました。
PE Explorer。これ、簡単に言っちゃぅと、EXE/DLL/OCXなどのデバッガです。売り元が www.heaventools.com なんていかにもな名前なところがアレなんですが。
で、このPE Explorer。最新版(Ver1.50)の新機能のひとつに、XP Manifest Wizardってのがあったんです。
さっそく体験版をダウンロードしてみましたとも。インストールしてみましたとも。前項で提供した XPControls1.exe に適用してみましたとも。
いゃ、前項の最後と同じ表示でしかないので、改めてここで提示はしませんが。
これで私もばりばりWinXPのデスクトップテーマに対応したプログラムを書き放題!
って、別に結果オーライなんであれば前項の手法でもいっこうに構わないわけで。
私は自分のプログラミング作業だけでデスクトップテーマに対応させる手法を探していたはずなので、これではやはりいまいち収まりが悪いですね。むぅぅ。
しかもこのPE Explorer、できあがった実行ファイルに対してWizardかけるので、ソースレベルでどぅのといぅ話ではないんですね。
ってことで結局自力組み込みの方法はわからずじまい。だめじゃん。
泣きながら一晩寝たら、思いつきました。
元々manifestデータをリソースとして組み込むって基本ラインは Microsoftのコンテンツですでにわかっているわけで。
「リソースとしてどぅ用意するか」と「用意したリソースをどぅ使用するのか」がよくわからなくって断念していたんです。
ってことは、PE Explorerでデスクトップテーマに対応した実行ファイルのリソースを解析すれば、リソースの用意のしかたの正解はわかるはず。
実行ファイルの中のリソースを直接引っぱり出していじくる手法は、実はOutLookのカスタマイズの仕事をした時に知ってたんですね。いゃ、VC++で実行ファイルをリソースファイルとして読み込んじゃえばいいだけなんですけど。
たぶんPE ExplorerもVC++のそれと同じ手法でmanifestデータを実行ファイルに追加しているんではないのかしら、との推測も成り立ったりします。とすると、実際に実行するコード部はいじくってないはず。ならば、manifestデータをリソースとして用意さえすればおっけーなのか?
まぁ楽観的な推測は置いといて。
PE Explorerでデスクトップテーマ対応化したXPControls1.exeをXPControls1PE.exeと名前を変えて、対応前のXPControls1PE.exeと両方Visual Studioでリソースファイルとして読み込んでみました。

fig.7 Visual Studioでリソースファイルとして読み込んだXPControls1.exe(対応前/後)
そーかリソースタイプ=24/ID=1でmanifestデータを埋め込めばいいんだっ。
さっそくVBのリソースエディタで作ってみました。
…おかしいなぁ。
今作ってみたXPControls2.exeを先ほどの対応済プログラムとリソースを見比べてみると、

fig.8 PE Explorerでデスクトップテーマ対応させたXPControls1.exeと自作XPControls2.exe
…いゃ、別に私京都の人ではないんですが。
これがどーしてもだめ。VB付属のリソースエディタだと、リソースタイプが数値になりません。なにをどーやっても 絶対文字列になってしまいます。
なにか私が知らない方法があるんでしょうか。ご存じの方はご一報ください。
しかたがないのでVC++でリソースファイルを作成、でVBでリソースファイルとして読み込んで再度コンパイル。
これでどぅだっ!
fig.9 manifestリソース付きでコンパイルしたXPControls2.exeの実行結果
(クリックで拡大します)
リソースファイルは完璧なはずなんですが…。ほら。
fig.10 PE Explorerでデスクトップテーマ対応させたXPControls1.exeと自作XPControls2.exe(2)
(クリックで拡大します)
リソースの中身だって同じはずなんですが…あら?
fig.11 PE Explorerでデスクトップテーマ対応させたXPControls1.exeと
自作XPControls2.exeのリソースの中身
(クリックで拡大します)
(T-T)(T-T)(T-T)
リソースを埋め込む時に、お尻によけいなデータがくっつく。
manifestデータの文字列をいろいろ変えて試してみると、「00」が1~4バイト程度ランダムにくっつくことがわかりました。 もちろんくっつかない時もたまにあって、その場合は正常に動作します。
では、VC++で読み込んで直接リソース末尾の「00」を削除すると。うぅむ、ちゃんと起動します。
以上より、結論。
正確には、作れるときもあるが不安定で使い物になりません。ちくしょー。
VBでmanifestリソース込みでコンパイルしてから埋め込まれたりソースの末尾のゴミをVC++で取り除く、って手もありますが。
元々のリソースファイルをVC++で作らなければならないこともあり、なんのためにVBを経由してリソースを埋め込まなければならないのかまったく必然性のない状態ではあります。
ので、ここはひとつ単純にできあがったEXEファイルに後からmanifestリソースを埋め込むのがベスト、といぅ結論とします。
ってことで、以下具体的な手順です。
- ふつーにVBでコンパイル、EXEファイルを作成する。
- 作成したEXEファイルをVC++で、リソースファイルとして読み込む。
- 表示されたツリー構造の一番上、EXE名の部分を右クリック。
- [挿入(I)...]-[カスタム(C)...]と選択、リソースのタイプを 24 とする。
(ここまで操作すると、バイナリエディットウィンドウが新規作成の状態で開く。) - 前項で用意したmanifestファイルを バイナリエディタ で開き、VC++のバイナリエディットウィンドウへカット&ペーストする。
(これ以外の方法では文字列がバイナリレベルでUTF-8にならず、正常に動作しない。) - バイナリエディットウィンドウを閉じ、24フォルダの下にできたリソースデータを右クリック。
- [プロパティ(P)...]を選択、カスタムリソースプロパティで[ID(I):]を「1」に書き換えて閉じる。
- リソースを追加したEXEを保存終了し、VC++を終了する。
ちゃんと起動しましたよね。コントロールもそれぞれXPのデスクトップテーマを反映していることを確認してみましょう。
VC++を持っていない方は、VECTORあたりでバイナリエディタとリソースエディタを入手すれば同じことができますよ。
さて。
ここまで長々と説明してきておいてなんですが、実はこの方法、manifestデータに依存しているって点では前項で説明した方法と本質は変わっておりません。
要は動作形態をXMLとして記述するわけで、自分のEXEの機能ではなく、XMLパーサのお世話でデスクトップテーマに対応しているんです。
まぁXMLはXP以降のWindowsではプログラムを動作させる手法のひとつとして完全にOSに組み込まれているわけですから別に困るわけではないんですが。
外部機能として取り込むことを許容できるのはせいぜいDLL-APIまでだ。
なんて方には、別の手法をお教えしましょう。
ここで紹介されている方法はむっちゃくちゃ正攻法です。
具体的には、CommonControl6の全機能を扱うためのタイプライブラリを作成し、そこからコントロールをひとつずつがしがしフェイス適応させていくんですね。
パワーのある方は、ぜひお試しください。XPのデスクトップテーマ、といぅかビジュアルスタイルの仕組みが理解できまくりますよ。