最近の記事
- 4/24 - 優先順位
- 3/17 - vbNullString と 空文字列 ""
- 3/15 - InputBox 関数の戻り値
- 3/13 - 紙と Excel と VBA
- 3/9 - 未だに Visual Basic 6
- 11/14 - ぼて閉鎖
- 11/9 - 関数オブジェクトの呼び出し
- 9/7 - メソッドとしての関数オブジェクト
- 8/18 - コンストラクタとしての関数オブジェクト
- 8/4 - オブジェクトの生成
Entering Passive Mode
さて、お膳立ては整ったので、DLL に
DllRegisterServer と DllUnregisterServer を実装しよう。
========== library.cpp ==========
// (…前略…)
// (…DllMain…)
// (…DllGetClassObject…)
// (…DllCanUnloadNow…)
// (…WriteRegistryStringValue…)
// (…DeleteRegistryValue…)
// (…RegisterIconOverlayHandler…)
// (…UnregisterIconOverlayHandler…)
昨日作った WriteRegistryStringValue を使うと、
COM クラスとエクステンションの登録処理を、
少しは見やすく書くことができる。
========== library.cpp ==========
// (…前略…)
// (…DllMain…)
// (…DllGetClassObject…)
// (…DllCanUnloadNow…)
// (…WriteRegistryStringValue…)
// (…DeleteRegistryValue…)
さて、必要な機能は全て実装したのだが、
一般的なインプロセスサーバとして完成させるには、
あともう少しやるべきことがある。
インプロセスサーバは、DLL をコピーするだけでは動作せず、
サーバに含まれる COM クラスを公開するために、
レジストリに登録する必要があった。
レジストリの登録情報は、DLL のパスに依存しているため、
インプロセスサーバをシステムにインストールする際に、
レジストリファイルを相手に配るのは現実的ではない。
新たに作成した 2 クラスの動作をテストしよう。
HardLinkIconID クラスの時と同じように、
まずはレジストリファイルを作成して登録することにする。
■レジストリへの登録
http://mixi.jp/view_diary.pl?id=281240938&owner_id=2300658
レジストリへの登録はクラス単位なので、
同じようなエントリが 3 つ並ぶことになる。
テンプレートクラスは、定義しただけでは何の効果もない。
テンプレートの引数に具体的なクラス型を与えることで、
テンプレートを元にしたクラスの実体が定義される。
これを、「テンプレートのインスタンス化」と呼ぶ。
では、DllGetClassObject を書き換えて、
他の 2 クラスも公開できるように修正する。
どうせなら、HardLinkIconID にもテンプレートを使おう。
=========== library.cpp ==========
新しく作った 2 つのクラスにもクラスオブジェクトが必要だ。
これも HardLinkIconIDClass をコピーして作ることができる。
■HardLinkIconIDClass クラス
http://mixi.jp/view_diary.pl?id=277138945&owner_id=2300658
HardLinkIconIDClass を見てみると、実装のほとんどが、
IClassFactory のための一般的なもので、
クラス固有の部分は、新しい HardLinkIconID の
インスタンスを作成する部分だけだ。
この勢いで、フォルダリンク(フォルダショートカット)の、
FolderLinkIconID クラスも作り上げてしまおう。
やはり似たようなソースになることが想定されるので、
HardLinkIconID からコピーして作ることにする。
========== FolderLinkIconID.hpp ==========
#ifndef folderlinkiconid_hpp_included
#define folderlinkiconid_hpp_included
アイコンは 3 種類用意しているが、
まだ 1 つしかクラスを作っていなかった。
今日はマウントポイント用のクラスを作ることにする。
クラス名は「MountPointIconID」とする。
基本的な部分は HardLinkIconID と変わらないので、
HardLinkIconID をコピーして作ると速い。
まずは、クラスの定義を作成する。
========== MountPointIconID.hpp ==========
COM サーバをレジストリに登録し、
実際にアイコンが表示されるかどうか試してみよう。
レジストリへの登録内容は昨日書いたとおりだが、
登録は COM クラス単位で行うので、
複数の COM クラスを提供するサーバの場合、
その数だけ登録する必要がある。
本来はプログラムから登録を行うのだが、
この時点ではまだ動作確認だけでよいので、
レジストリへの登録や登録解除は、
レジストリファイルを使うことにしよう。
インプロセスサーバの DLL が完成しても、
そのままでは COM 基盤はその存在を知る事ができない。
そこで、COM 基盤からサーバを呼び出せるように、
レジストリに情報を登録する必要がある。
COM クラスの情報は、HKEY_CLASSES_ROOT\CLSID の配下の、
{クラス ID} のキーに格納する。
キーのデフォルト値には、クラスの説明文字列を入れる。
これは人間が利用するための情報であり、必須ではない。
インプロセスサーバを登録する場合は、
更に InProcServer32 というサブキーを作成し
キーのデフォルト値に、DLL のファイル名を入れる。
これで、COM クラスと提供サーバの関連付けが行われるのだ。