アイコン
IExtractIcon::Extractを使っていると、XPのエクスプローラと同じにはできない。
- xlsを48*48で描画しようとすると、32*32を引き伸ばしたものになる。
- またアイコンのないexeはダミーのアイコンを取得できない。
SHGetFileInfoならばダミーのアイコンを取得できるのに。
いろいろ調べているうちにSHGetImageListを発見した。
SHIL_EXTRALARGEは32x32より大きいイメージリストを扱えるらしい。
これまたXPからしか対応していない。
またIExtractIconは遅い気がするので調べてみた。
動作が違うので単純に比較するわけにはいけないけど、デスクトップの列挙を
100回繰り返した。
SHGetFileInfoは2515, 2422, 2484ms。
IExtractIconは6219, 6266,6219ms。
あと、SHMapPIDLToSystemImageListIndexというのを見つけて、2437, 2406, 2453ms。
成績はSHMapPIDLToSystemImageListIndexが最も良い。
IExtractIconはDestroyIconをしているので遅いのかと思い試したけど、
IExtractIconはどうもキャッシュが働いていないみたい。
おそらく、より低レベルな実装なのではないだろうか。
また、SHGetFileInfoは内部でSHMapPIDLToSystemImageListIndexを
単純に呼び出しているのではないだろうか。
時間の差はそれくらいの差に思える。
SHFILEINFO inf;
- SHGetFileInfo((LPCTSTR)il, 0, &inf, sizeof(SHFILEINFO),
SHGFI_PIDL|SHGFI_SYSICONINDEX|SHGFI_SMALLICON);
}
IExtractIcon* ie;
UINT reserved;
hr = sf->GetUIObjectOf(NULL, 1, &il, IID_IExtractIcon, &reserved, (LPVOID*)&ie);
TCHAR buf[MAX_PATH] = _T("");
UINT flags = 0;
int index = 0;
hr = ie->GetIconLocation(GIL_FORSHELL, buf, MAX_PATH, &index, &flags);
HICON smallIcon=NULL, largeIcon=NULL;
ie->Extract(buf, index, &largeIcon, &smallIcon, MAKELONG(32, 16));
- DestroyIcon(smallIcon);
- DestroyIcon(largeIcon);
int index = ::SHMapPIDLToSystemImageListIndex(sf, il, NULL);