はじめに
Internet Explorerバー(IEバー)はメインのエクスプローラウィンドウ内の子ウィンドウであり、デスクバンドはデスクトップ/タスクバー上のドッキング可能ウィンドウである。これらを使用して、ユーザーに情報を表示したり、ユーザーとインタラクションを行ったりできる。本稿では、これらのバンドオブジェクトの実装について説明する。
設計
IEバーやデスクバンドを作成するには、いくつかのインターフェイスと特殊な登録プロシージャを実装する必要がある。この手間を軽減するために、COMとWindows Shellランタイムで必要とされる細かい処理をすべてカプセル化するCDeskBand
というATLクラスを独自に開発してみた。さらに、COMオブジェクトの登録と登録解除を行うためのCShellModule
クラスを用意した。
新しいマクロ
BEGIN_TYPE_MAP(x)
バンドATLオブジェクトの型マップの始まりを表す。パラメータx
には、オブジェクトの型を表す_ATL_TYPEMAP_ENTRY
構造体を格納する配列を指定する。
END_TYPE_MAP()
バンドATLオブジェクトの型マップの終わりを表す。CShellModule::RegisterServer
が呼び出されると、この型マップ内の各オブジェクトがシステムレジストリに登録される。
TYPE_ENTRY(clsid, type)
型マップにバンドオブジェクトの型を挿入する。パラメータclsid
は、このマップに挿入するオブジェクトのCLSIDである。パラメータtype
には、次のいずれかの値を指定できる。
DeskBand
VerticalExplorerBar
HorizontalExplorerBar
これらのマクロの使い方は、ATLの標準のBEGIN_OBJECT_MAP
、OBJECT_ENTRY
、END_OBJECT_MAP
マクロとほぼ同じである。
DECLARE_MENU_MAP(x)
メニューマップの事前宣言である。パラメータxには、1つまたは複数のバンドオブジェクトに固有のマップの名前を指定する。
BEGIN_MENU_MAP(x)
メニューマップの始まりを表す。パラメータx
には、メニュー項目を表す_ATL_MENUMAP_ENTRY
構造体を格納する配列を指定する。これは、前のマクロで使用したものと同じでなければならない。
END_MENU_MAP()**
メニューマップの終わりを表す。
MENU_ENTRY(id,flags,item,help,verb)**
メニューマップにメニュー項目を挿入する。パラメータid
はマップ内で一意にする必要がある。flags
パラメータに指定する値については、MSDNドキュメントのInsertMenu
関数を参照のこと。item
パラメータには、メニュー項目の表示ラベルを指定する。help
パラメータには、メニュー項目のヘルプ文字列を指定する。verb
パラメータには、言語に依存しないコマンド名(open
、save
など)を指定する。
MENU_ENTRY_SEPARATOR()**
メニューマップに項目区切りを挿入する。
メニューマップを作成するのは、バンドオブジェクトに特殊なコマンドが必要な場合のみにすべきである(代表的な使用例は[設定...]コマンドなど)。なお、1つのメニューマップを複数のバンドオブジェクトに使用することが可能である。
CShellModule
class CShellModule :public CComModule
CShellModule
クラスは、Windows Shellで必要とされる登録/登録解除プロシージャを拡張したCOMサーバーモジュールを実装している。
HRESULT Init( _ATL_TYPEMAP_ENTRY *pdt, _ATL_OBJMAP_ENTRY *p, HINSTANCE h )
すべてのデータメンバを初期化する。パラメータpdt
は、マップ配列を指すポインタである。その他のパラメータは、CComModule::Init
メソッドのパラメータと同じである。
HRESULT RegisterServer( const CLSID *pCLSID = NULL )
pCLSID
パラメータの値に応じて、1つのクラスオブジェクトまたはオブジェクトマップ内のすべてのオブジェクトをシステムレジストリに登録する。
HRESULT UnregisterServer( const CLSID *pCLSID = NULL )
pCLSID
パラメータの値に応じて、1つのクラスオブジェクトまたはオブジェクトマップ内のすべてのオブジェクトを登録解除する。
CDeskBand
template < const CLSID *pclsid,const _ATL_MENUMAP_ENTRY *pMenu = NULL > class ATL_NO_VTABLE CDeskBand :public CComObjectRootEx<CComSingleThreadModel>, IObjectWithSite, IPersistStream, IDeskBand, IContextMenu
CDeskBand
は、シェルデスクバンドオブジェクトとIEバーオブジェクトを実装している。このクラスには、プロテクトされた5つの仮想メソッドが含まれていて、オーバーライドすることも可能。
LRESULT OnCreate( LPCREATESTRUCT lpCreateStruct )
― WM_CREATEメッセージハンドラLRESULT OnDestroy()
― WM_DESTROYメッセージハンドラLRESULT OnPaint()
― WM_PAINTメッセージハンドラLRESULT OnCommand( WPARAM wParam, LPARAM lParam )
― WM_COMMANDメッセージハンドラLRESULT OnMsg( HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam )
― 上記のメッセージを除く汎用メッセージハンドラ
独自のバンドオブジェクトを作成するときは、このCDeskBand
からクラスを派生させるとよい。次に例を示す。
DECLARE_MENU_MAP(DeskBandMenu) extern const CLSID CLSID_SampleDeskBand; class CSampleDeskBand : public CComCoClass<CSampleDeskBand, &CLSID_SampleDeskBand>, public CDeskBand<&CLSID_SampleDeskBand,DeskBandMenu> { public: CSampleDeskBand(); ~CSampleDeskBand(); DECLARE_REGISTRY_RESOURCEID(IDR_DESKBAND) DECLARE_PROTECT_FINAL_CONSTRUCT() protected: virtual LRESULT OnPaint(); private: // your data data members };