検証環境 自作ATX(Cerelon533/VT6X4/384MB) WindowsXPPro/IE6.00Jp/VS6
2001.11.16の日本語版発売を待たずして何の拍子にか入手してしまいました、WindowsXP。ふっふっふ、うれしー。
WinXPとVS.netが手に入っちゃったわけですから、こりゃぁもぅ遊ぶしかないでしょう。
ってことでいろいろ遊ぶことにしました。
…身が持つのかしら。
しかしその前に。
VS.netが未だβ版であることを考えると、当然お仕事には使えません。ので、やはりここはひとまずWinXP+VB6でしばらく攻めてみたいと思います。
WinXPは来月には正式に発売が開始されちゃうわけですし、少なくとも来年の春まではVS6/VB6がメジャーな開発ツールになるんでしょうし。Microsoftも
正式に対応していると 表明していますしね。
で、とりあえず気になるのは画面のふちと各コントロールのデザインの違い。
全っ然変わっちゃっています。

fig.1 Windows2000で起動したWordPad(クリックで拡大します)

fig.2 WindowsXPで起動したWordPad(クリックで拡大します)
では、VB6で自分で作ったプログラムはどんなもんでしょうか。
基本的なコントロールを貼っつけて実行してみましょう。

fig.3 WindowsXPで起動した自作プログラム
…むちゃくちゃかっこ悪い。
WinXPのテーマに対応していないならしていないで統一してほしかったところです。
なんだTextBoxの中途半端なスクロールバーは。
WinXPのテーマに対応するしない以前に、せめてまずWin2000風のデザインをきちんとしないば恥ずかしすぎですね。
まず、今作ったプログラムを一度コンパイルしてEXEにしてみます。
で、WinXPにはプログラム互換性ウィザードのがありますので、こいつでWin2000風になるよぅに設定してみましょう。
(スタートメニューから[すべてのプログラム]→[アクセサリ]→[プログラム互換性ウィザード])
- [手動でプログラムを選択する]→先ほど作成したEXEを指定します。
- [プログラムの互換性モード]→とりあえず[Microsoft Windows 2000(2)]でいいでしょう。
- [プログラムのディスプレイの設定を選択]は、「視覚テーマを無効にする(D)」にチェックをつけます。

fig.4 WindowsXPで起動した自作プログラム(Win2000風)
…おぉ。何とかなったよぅな。
では、このプログラム互換性ウィザードは、このWin2000/視覚テーマ無効の情報をどこにセットしているんでしょう。
探してみたら、レジストリの中にありました。
[HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]→[WIN2000 DISABLETHEMES]
です。…ほんと?
試しに、レジストリエディタで手動設定をしてみましょう。
ターゲットはWordPad.exe(C:\Program Files\Windows NT\Accessories\wordpad.exe)。同じキー内にWordPad.exeのフルパスで文字列値として新規作成、値を[WIN2000 DISABLETHEMES]としてからWordPad.exeを起動してみます。
…おぉ。WordPadがWin2000風になったぞ。
ちょっと余談。
WinXPでは、ComCtl32.dllが2種類同梱されています。
ひとつは~Win2000までで使用していたものと互換のバージョン5.82.2600.0のもの(ちなみにWin2000に同梱されているComCtl32.dllはバージョン5.81.4704.1100)。C:\WINDOWS\system32に格納されています。
もぅひとつはWinXPのテーマに対応して表示を変えるバージョン6.0.2600.0。
これはWinXPの紹介記事などでコモンコントロール バージョン6として紹介していることも多いので、ご存じの方もわりといらっしゃるのではないかと思います。格納位置は、C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.0.0_x-ww_1382d70a。
…うわぁ。
実は私、この2つのComCtl32.dllがどぅ動き分けているのかよくわかっていません。
てゅうか、どぅもVer.5の方は動作していないよぅな気が。VB6が無条件にVer5を参照するのなら、TextBoxが中途半端にデスクトップテーマに対応するわけはないと思うんですね。何も設定しない素の時点で、すでにVer6を参照しているんではないでしょうか。で、デフォルトの動作がDISABLETHEMESではないために、ちょいとちぐはぐな反応をするのではないか、くらいの推測をしているのですが…。
この調査の浅さが暫定版、といぅことでお許しください。
さて、今度はばりばりWinXPのデスクトップテーマに対応させたい、といぅお話。
先ほどのレジストリ値を削除したってだめです。元の中途半端な表示に戻るだけですね。
デスクトップテーマに完全対応させる場合は、まずEXEと同じフォルダに、以下の内容を持つファイルをひとつ作成します。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1"
manifestVersion="1.0">
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="X86"
name="Salvage.VB SickHack04.XPControls1"
type="win32"
/>
<description>VB6でWinXPのデスクトップテーマに対応したいなぁ</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="X86"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
</assembly>
これを
、(プログラム名).exe.manifestといぅファイル名で保存します。しかもUTF-8で。
(UTF-8形式を扱えるテキストエディタを使いましょうね。私は秀丸ひとつでUTF-8もEUCも対応しています。超便利。)
あ。assemblyIdentityのnameは[会社名].[プロダクト名].[アプリケーション名]を、descriptionは説明文を、つど任意に記述してください。ここで提示しているのサンプルですので、こんなとぼけた文章をそのまま流用するとあとで恥ずかしいかもしれません。
準備はこれだけです。では実行してみましょう。

fig.5 WindowsXPで起動した自作プログラム(WinXPフル対応 - 失敗例)
…まだなんかやだなぁ。
CommandButtonとOptionの表示が変ですね。CommandButtonは妙にフチが黒いし、Optionなんか真っ黒です。
いろいろいじくってみると、どぅもFrameをコンテナとして置いた時に表示がおかしくなるよぅです。
ので、Frameコンテナから外して再度チャレンジ。

fig.6 WindowsXPで起動した自作プログラム(WinXPフル対応 - 成功例?)
まぁだいたいOKでしょう。でも、
Frameをコンテナに使えないと
Optionなどのグルーピングに困りゃしないか。
…困りますよね。
ので、上に提示したプログラムでは、CommandButton、Check、OptionをPinctureBoxをコンテナとして貼り付けてみました。 PictureBoxなら表示がバケないよぅです。
Frameの中にさらにPictureBoxを貼るのがちょっとアレで負けたよぅな気がしますが、とりあえずは妥協しておきましょう。
さらに。
Toolbar、Slider、StatudBarなんかはこれでもまだ元の表示のままです。
どぅもこれ、ComCtl32.dllで用意したコントロールではなく、MSComCtl.ocxが独自に用意した似非コントロールのよぅです。
これも極めればなんとかなるのかもしれませんが、現時点では私にはわかりません。
ここらへんもまぁ暫定版だといぅことでひとつ。
いちおぅ、まとめ。
- 従来どおりの表示をさせるなら、レジストリにその旨登録する。
- WinXPのデスクトップテーマの表示に準拠するなら、.manifestファイルをEXEファイルと同じフォルダに置く。
って感じでなんとかそれなりの効果はあげられるだろぅ、ってことですね。
しかしだ。
なんともかっちょ悪い手法ではあります。
前者は初回起動時にレジストリ登録してから再起動かけなきゃなりません。もしくはインストーラを加工して、インストール時に行うかですね。
どっちにしてもなぁ。
インストーラ不要なプログラムを作成配布したい需要は多いでしょうし(VBだって別途ランタイムを導入してあるマシンにならインストーラなしで組み込めます)、初回起動時にださださウィンドウがちらとでも出るのであればやっぱ不本意ですしねぇ。
後者はXMLを別ファイルとして同梱しなきゃならないところがいまいちアレ。
VC++6だとリソースとしてプログラム内に組み込む手法がすでに提供されているんですが(手順はこちら、サンプルはこちら、VBでの実装はDr.GUIが答えてくれていますが…肝心のXMLの組み込みについてはお茶を濁されてしまっています)、これをVBに流用できないのが今んとこの私の限界です。とほほ。
ってこともあって、本項はあちこち暫定版です。
も少しスマートな手法がわかった時点で随時書き換えていきますね。