多くのGUIアプリケーションにとって有用になるものです。コンテキストメニューの表示やD&Dの機能を既定で実装しています。エクスプローラーのフォルダが行っている動作を簡単に真似することができます。Vistaから追加されたExplorerBrowserというオブジェクトを使用するのが最も簡単です。Vista以前のWindowsにおいても、フォルダビューを表示するためのオブジェクトは存在していました。したオブジェクトを使用せず、ExplorerBrowserを使用することにはどのような利点があるのでしょうか。各種オブジェクトの特徴を簡単に整理します。フォルダビューを表示することができるが、このオブジェクトはCoCreateInstanceで作成することができない。アプリケーションがIShellBrowserを実装したオブジェクトを自作することになる。ファイルのアイテムしか表示されなかったりする。フォルダビューを表示できることに加え、履歴機能やペインの表示もサポートする。Vistaから使用可能。実用性があるのはShellBrowserかExplorerBrowserかのどちらかになります。ExplorerBrowserの場合はこうした作業をアプリケーションが行う必要はありません。単純にオブジェクトを作成するだけで、必要な機能を利用することができます。Vistaより前の環境でShellBrowserを使用するのがよいと思われます。ExplorerBrowserを作成するには、CoCreateInstanceにCLSID_ExplorerBrowserを指定します。Initializeを呼び出してExplorerBrowserを初期化することになります。*pfs);hwndParentは、ExplorerBrowserを表示する親ウインドウのハンドルを指定します。prcは、ExplorerBrowserの位置を格納したRECT構造体のアドレスを指定します。pfsは、フォルダの表示情報を格納したFOLDERSETTINGS構造体のアドレスを指定します。ExplorerBrowserの初期化が完了すれば、特定のフォルダの中身を表示できるようになります。これには、BrowseToIDListを呼び出します。uFlags);pidlは、表示したいフォルダのPIDLを指定します。uFlagsは、PIDLの種類を表す定数を指定します。PIDLが完全PIDLである場合は、SBSP_ABSOLUTEを指定します。ExplorerBrowserは、エクスプローラーのフォルダで使用されているペインを完全に提供しています。次のようなペインを表示することができます。各種ペインは既定の実装を持っており、それはExplorerBrowserと正しく関連しています。その表示形式がExplorerBrowserへ実際に反映されます。これを検出することで任意のペインのみを表示することもできます。それを継承したクラスを定義し、オブジェクトのアドレスをExplorerBrowserに渡すようにします。これにより、ExplorerBrowserはオブジェクトのGetPaneStateを呼び出せるようになります。COMの標準的なインターフェースであるIObjectWithSiteを使用します。IObjectWithSite::SetSiteでオブジェクトのアドレスを渡すことになります。オブジェクトはIServiceProviderも実装しておく必要があります。今回のプログラムは、ExplorerBrowserを使用してフォルダビューを表示します。TRUE;}既に述べたように、ExplorerBrowserからの通知を受け取るためには、通知用のインターフェースを継承したクラスが必要になります。これを継承したCExplorerBrowserHostというクラスを定義しています。ExplorerBrowserを管理するということでクラス名にHostという単語を付けています。WinMainではCExplorerBrowserHost::Runを呼び出し、ウインドウの作成などが完了した後にメッセージループへ入ります。メッセージが送られるとWindowProcが呼ばれ、そこからさらにクラスのWindowProcが呼ばれることになっています。WM_CREATEではCreateという自作メソッドを呼び出し、IExplorerBrowserを取得しています。TRUE;}IExplorerBrowserを取得するには、CoCreateInstanceにCLSID_ExplorerBrowserを指定します。これに成功したら、Initializeを呼び出してExplorerBrowserを初期化することになります。FVM_DETAILSの場合は詳細表示されることになります。fFlagsは0で構いませんが、たとえばFWF_CHECKSELECTを指定するとチェックボックスが表示されるようになります。今回は表示されるペインを制限されることになります。理由は、IExplorerPaneVisibility(及びIServiceProvider)を実装したオブジェクトのアドレスをExplorerBrowserに渡しているからです。IUnknown_SetSiteを呼び出せばこの2つの作業を一度に行うことができます。BrowseToIDListで特定のフォルダの中身を表示することになります。今回はデスクトップにするということで、SHGetKnownFolderIDListでデスクトップのPIDLを取得しています。これはSHGetSpecialFolderLocationでも可能ですが、対象とする環境がVistaであるため、Vistaから登場したSHGetKnownFolderIDListを使用しています。WindowProcではWM_CREATEの他に、WM_SIZEとWM_DESTROYを処理しています。SetRectを呼び出しています。これにより、ExplorerBrowserのサイズは第2引数のRECT構造体を反映します。その前にDestroyを必ず呼び出すようにします。ExplorerBrowserはペインを表示する段階になると、オブジェクトのIServiceProvider::QueryServiceからIExplorerPaneVisibilityを取得しようとします。よって、QueryServiceではIID_IExplorerPaneVisibilityの際にオブジェクトのアドレスを返すようになっていなければなりません。}上記ではQueryServiceを呼び出しているだけですが、QueryServiceでIID_IExplorerPaneVisibilityを考慮するようになっていれば問題はありません。guidServiceにSID_ExplorerPaneVisibilityが格納されます。IExplorerPaneVisibilityを取得したExplorerBrowserは、GetPaneStateを呼び出すことで表示すべきペインを確認します。S_OK;}第1引数のepには、どのようなペインが表示されようとしているかを表す定数が格納されます。今回はEP_NavPaneで表されるペインを表示するということで、このときのみpepsにEPS_DEFAULT_ONを格納しています。それ以外のペインは表示しないということで、EPS_DEFAULT_OFFとEPS_FORCEを格納しています。戻り値はS_OKで問題ありません。アイテムのフィルタについてExplorerBrowserに表示されるアイテムをフィルタする方法は主に2つあります。特定のアイテムの際にS_FALSEを返すようにします。これにより、そのアイテムはExplorerBrowserに表示されなくなります。これを実装したオブジェクトをIUnknown_SetSiteで指定するだけで構いません。IncludeObjectを処理する例はシェル名前空間の章で取り上げています。これをIFolderFilterSiteでExplorerBrowserに渡す方法です。IFolderFilterSiteは、ExplorerBrowserに対してQueryInterfaceを呼び出せば取得できます。*>(this));IFolderFilterSiteを取得したら、SetFilterを呼び出してオブジェクトのアドレスを渡すようにします。これにより、アイテムが追加される段階になるとIFolderFilter::ShouldShowが呼ばれることになります。当然ながら、オブジェクトのQueryInterfaceではIID_IFolderFilterを処理しておく必要があります。次に、ShouldShowの例を示します。S_OK;}psfは表示対象となっているフォルダのIShellFolderであり、pidlItemは表示されようとしているアイテムのPIDLです。この名前の拡張子をPathFindExtensionで取得しています。一致する場合はS_FALSEを返してアイテムが表示されないようにしています。IFolderFilterにはGetEnumFlagsというメソッドがありますが、こちらの呼び出しについては確認することができませんでした。