Entering Passive Mode

カテゴリ 'COM' の記事
< 1 2 3 4 5 6 7 >

DllRegisterServer/DllUnregisterServer

さて、お膳立ては整ったので、DLL に
DllRegisterServer と DllUnregisterServer を実装しよう。

========== library.cpp ==========

// (…前略…)
// (…DllMain…)
// (…DllGetClassObject…)
// (…DllCanUnloadNow…)
// (…WriteRegistryStringValue…)
// (…DeleteRegistryValue…)
// (…RegisterIconOverlayHandler…)
// (…UnregisterIconOverlayHandler…)

COM クラスとエクステンションの登録処理

昨日作った 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 ==========

ClassObject テンプレートクラス

新しく作った 2 つのクラスにもクラスオブジェクトが必要だ。
これも HardLinkIconIDClass をコピーして作ることができる。

■HardLinkIconIDClass クラス
http://mixi.jp/view_diary.pl?id=277138945&owner_id=2300658

HardLinkIconIDClass を見てみると、実装のほとんどが、
IClassFactory のための一般的なもので、
クラス固有の部分は、新しい HardLinkIconID の
インスタンスを作成する部分だけだ。

FolderLinkIconID クラス

この勢いで、フォルダリンク(フォルダショートカット)の、
FolderLinkIconID クラスも作り上げてしまおう。

やはり似たようなソースになることが想定されるので、
HardLinkIconID からコピーして作ることにする。

========== FolderLinkIconID.hpp ==========

#ifndef folderlinkiconid_hpp_included
#define folderlinkiconid_hpp_included

MountPointIconID クラス

アイコンは 3 種類用意しているが、
まだ 1 つしかクラスを作っていなかった。
今日はマウントポイント用のクラスを作ることにする。

クラス名は「MountPointIconID」とする。
基本的な部分は HardLinkIconID と変わらないので、
HardLinkIconID をコピーして作ると速い。
まずは、クラスの定義を作成する。

========== MountPointIconID.hpp ==========

レジストリへの登録

ハードリンク

COM サーバをレジストリに登録し、
実際にアイコンが表示されるかどうか試してみよう。

レジストリへの登録内容は昨日書いたとおりだが、
登録は COM クラス単位で行うので、
複数の COM クラスを提供するサーバの場合、
その数だけ登録する必要がある。

本来はプログラムから登録を行うのだが、
この時点ではまだ動作確認だけでよいので、
レジストリへの登録や登録解除は、
レジストリファイルを使うことにしよう。

スレッディングモデル

インプロセスサーバの DLL が完成しても、
そのままでは COM 基盤はその存在を知る事ができない。
そこで、COM 基盤からサーバを呼び出せるように、
レジストリに情報を登録する必要がある。

COM クラスの情報は、HKEY_CLASSES_ROOT\CLSID の配下の、
{クラス ID} のキーに格納する。
キーのデフォルト値には、クラスの説明文字列を入れる。
これは人間が利用するための情報であり、必須ではない。

インプロセスサーバを登録する場合は、
更に InProcServer32 というサブキーを作成し
キーのデフォルト値に、DLL のファイル名を入れる。
これで、COM クラスと提供サーバの関連付けが行われるのだ。

< 1 2 3 4 5 6 7 >
このページのトップへ戻る
© 2008 Project Loafer/Project Fireball and all blog writers. Powered by Nucleus CMS