Shell Extensionメモ
Shell Extension(シェル拡張)のプログラミング時のちょっとした注意事項をメモしておきます。
・SHShellFolderView_Messageの第1引数「hwnd」に指定するウィンドウはIShellViewのウィンドウではなくIShellBrowserのウィンドウ
内部で「hwnd」に対し「WM_USER+7」(WM_GETISHELLBROWSERなどと呼ばれてるメッセージ)を送り、戻り値に対して「IShellBrowser::QueryActiveShellView」を呼び出しています。SFVM_WINDOWCREATEDなどでビューのハンドルを保持している場合は、ほとんどの場合ビューの親ウィンドウがIShellBrowserのウィンドウになっているため、GetParent関数を使って戻り値を渡すと良いと思います。
・SHShellFolderView_Messageの多くのメッセージで指定するITEMIDLISTは「PCUITEMID_CHILD」
SFVM_ADDOBJECTやSFVM_UPDATEOBJECTのLPARAMで必要なITEMIDLIST(※SFVM_UPDATEOBJECTのLPARAMはLPITEMIDLISTの配列)は、絶対パスの「PCIDLIST_ABSOLUTE」ではなくビューの子要素に当たる「PCUITEMID_CHILD」(PCITEMID_CHILD、ITEMID_CHILDのポインタ)を指定します。また、メッセージを送るために新たにメモリを割り当てる必要はない模様です。(内部でCoTaskMemFreeが呼ばれることがない模様)SFVM_ADDOBJECTに指定する要素や、SFVM_UPDATEOBJECTの2番目の要素( ((LPITEMIDLIST)lParam)[1] に当たる値)などに対しては、内部でILFree関数やCoTaskMemFree関数が呼び出されるため、指定する際は必ず新たなメモリを割り当てて指定してください。(2011/06/30追記)
・Windows Vista以降のCDefViewで詳細表示にした時の、カラムからのグループ化表示のポイント
「詳細表示」(Details、FVM_DETAILS)モードで、カラムヘッダーの端にある下矢印をクリックすると、グループ化するためのチェックリストが表示されます。
詳細表示の項目数はIShellFolder2のMapColumnToSCIDで列挙した分だけになりますが、このときに返すSHCOLUMNIDをWindows標準のPROPERTYKEYにすると、画像のように対応するグループ化方法が提示されます(画像の例はEasySFTPでPKEY_DateModifiedを利用)。逆に独自のグループ化を行いたい場合は、返すSHCOLUMNID(PROPERTYKEY)をオリジナルにし、ICategoryProviderを実装後CreateViewObjectで「IID_ICategoryProvider」をトラップする必要があります。
参考: 仮想フォルダサンプル(カテゴリ) - EternalWindows
※Windows標準のPROPERTYKEYを使うとGetDetailsOfの代わりにGetDetailsExが呼ばれるようになり、文字列へのフォーマット方法がWindows標準になってしまいます。
ファイルの種類ごとに対応付けられているIThumbnailProviderを取得
レジストリからShellExを参照し、「{e357fccd-a995-4576-b01f-234630154e96}」(IID_IThumbnailProvider)に設定されているCLSIDからインスタンスを作成すると取得できます。具体的なコード例はEasySFTPのShellDLL.cpp内の「MyCreateThumbnailProviderFromFileName」関数を参照してください。