IExtractImage2のGetDateStampで嵌る
Windowsエクスプローラーの縮小表示を独自のファイル形式でも表示するCOMを作っていて、
WindowsXPで動作確認ができたからよっしゃ公開や。と思って、意気揚々とWindows2000でも
テストしたらことごとく動作がおかしく悩みまくりました。
最初サムネイルが全て同じになるので、排他処理を行わないといけない?
と思いつつ、デバッグすると、ちゃんとファイル単位でCOMのインスタンスは作成されているので
そういうことではなかった。サムネイルを作成する時にキャッシュ更新の処理を担う、(厳密には、以下が原因)で、助けて下さった、id:shiba-yanさんにも報告。
IExtractImage2を継承していないのが原因
んでこれでいいかな?と思ってたら、同じ作成日のファイルは、
同じサムネイルになることが発覚。でも、Windows側でデフォルトで対応している、
bmp,pngとかは、ちゃんと表示される。。。
んで、id:wraith13さんより指摘を受けまして。
GetLocationの第1引数返してないのではと。。。
よーく見てみる。
pszPathBuffer
[out] The buffer used to return the path description.
This value identifies the image so you can avoid loading the same one more than once.
あ!!同じ読み込みを避けるために、画像IDを返してね。実際には、MAXPATHのサイズが
渡されるので、そこにユニコードでパスを書き込めばいい。
というわけでCOMにwstringを持たせて、GetLocationにパスをコピーして、GetDateStampを元に戻して、実行!!
無事うまくいったのでした。
STDMETHOD(GetDateStamp)(FILETIME *pDateStamp) { FILETIME ftCreationTime,ftLastAccessTime,ftLastWriteTime; // open the file and get last write time HANDLE hFile = CreateFile( (LPSTR)filepath_.string().data(),GENERIC_READ,FILE_SHARE_READ,NULL, OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); if ( !hFile ) return E_FAIL; GetFileTime(hFile,&ftCreationTime,&ftLastAccessTime,&ftLastWriteTime); CloseHandle(hFile); *pDateStamp = ftLastWriteTime; return NOERROR; } // 一応,GetLocationの実装も乗せておきます。 HRESULT CThumbnailExtract::GetLocation(LPWSTR pszPathBuffer, DWORD cchMax, DWORD *pdwPriority, const SIZE *prgSize, DWORD dwRecClrDepth, DWORD *pdwFlags) { // ************************************************** // // 作成しているプログラムの都合で、必要なコードをここに書いてます。 // (ここでは割愛) // ************************************************** // // cchMax = 260(MAX_PATH) // filenameは、wstringで、メンバ変数に持たせている。Load関数でパスをコピーしておく。 wcscpy( pszPathBuffer , filename.data() ); if ( *pdwFlags & IEIFLAG_ASYNC ) { // WindowsXPとそれ以前は、ここに来る。 return E_PENDING; } else { // Windows Vista return S_OK; } }