WindowsのShellAPIでサムネ取得

http://ja.stackoverflow.com/a/6237/8000について調べた結果を供養。

IDLIST

SHGetDesktopFolderで取得したIShellFolderでフルパスをParseDisplayNameさせると、IDLIST_RELATIVEが返ってくる。中身を軽く覗いた感じだと、「ドライブ名」「子名」「孫名」「ひ孫のno」みたいな。末端だけ数値という謎。
でこれをILFindLastIDしたり、デスクトップの代わりに親ディレクトリで取得したりすると末端ノードだけが手に入る。これがITEMID_CHILD。
http://pg-torch-ic.jugem.jp/?eid=31
アイテムIDリストとは?

GetUIObjectOf

UIObjectってあたりで薄々そんな気はしていたのだけど、どうもあるノードに関するインターフェイスは親ディレクトリが提供する物のようだ。ところでUIObjectに渡すのはIDLISTだと思っていたので、じゃあcidlはIDLISTの深さでも指定するんだろうと踏んでいた。IDLISTの一部だけ読めるようにとか。
改めてシグニチャを見ると、PCUITEMID_CHILD_ARRAYとなっている。

The address of an array of pointers to ITEMIDLIST structures, each of which uniquely identifies a file object or subfolder relative to the parent folder. Each item identifier list must contain exactly one SHITEMID structure followed by a terminating zero.

IShellFolder::GetUIObjectOf (shobjidl_core.h) | Microsoft Docs

つまり、ITEMID_CHILDの配列だったわけだ。その要素数を指定するためのcidl。
複数要素のUIObjectってなんだろう?というのも書いてあって、IContextMenuとかIDataObjectとか。なるほど。

ここまでをまとめると、なんとかして親ディレクトリのIShellFolderとITEMID_CHILDを手に入れて、そこからIExtractImageやらIExtractIconやらIThumbnailProviderを取り出し、サムネを生成することになる。ってのがIExtractIconのページに書いてあるし。
IExtractIconA (shlobj_core.h) | Microsoft Docs

サムネ生成色々

IExtractImage
2000で登場。GetLocationでパラメータを指定して、Extractを呼ぶという構成。GetLocationはパスも返すらしいが、特に使わないようで謎。
IExtractIcon
XPで登場。IExtractImage同様にGetLocation+Extractという構成だが、GetLocationの結果をExtractに指定することになっている。
IThumbnailProvider
Vistaで登場。IExtractImageを置き換えるものらしい。ただクライアントアプリでは後述するIShellItemImageFactoryを使えとある。

ちなみにIExtractImage2というインターフェイスもある。これはサムネの更新日時を取得するメソッドだけが入っていて、キャッシュに活用するんだそうな。一般市民が使うものじゃないよって書いてあるけども。
IExtractImage::GetLocationにはIEIFLAG_ASYNCというフラグがあり、これを使うと非同期にサムネを生成させられるらしい。が、この辺の情報がこれまた出てこないのなんの。

IThumbnailProvider

IThumbnailProviderはInitializeWith**というインターフェイスもいくつか実装していて、「何の」サムネを生成するかというのをこれで指定する。のだけれど、実際にはクライアントアプリでその初期化を行う必要はないらしい。
http://eternalwindows.jp/shell/shellname/shellname05.html
IThumbnailProviderを差し込みやすくなるとか、Preview周りと共通化を図れるとか、なんかそういう感じですかねえ。流行りの疎結合
実際には同じくVistaで増えたIThumbnailCache、さらにはIShellItemImageFactoryを使うとより簡単便利。

IShellItem

SHCreateItem系で得られるIShellItemとはなんなのか。
SHCreateShellItem function (shlobj_core.h) | Microsoft Docs
IShellItem (shobjidl_core.h) | Microsoft Docs
この辺を見た感じだと、IShellFolderとPIDLIST_CHILDを組み合わせた高レベルAPIに見える。
それからIShellItemImageFactoryも。
IShellItemImageFactory (shobjidl_core.h) | Microsoft Docs
今のところIShellItemImageFactory=(IThumbailCache(IThumbnailProvicer|IExtractImage)|IExtractIcon)ってところかな。