• 締切済み

WinAPI SHGetFileInfoでICONファイル名の取得方法?

SHGetFileInfoでExplorerに表示されるICONのファイル名を取得したいのですが うまくいきません。 int main(int argc, char* argv[]) { SHFILEINFO sfi; ::CoInitialize(NULL); if(0 == ::SHGetFileInfo("C:\\hogehoge.txt", FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICONLOCATION)) return -1; printf("Icon location file = %s\n", sfi.szDisplayName); return 0; } SHGFI_TYPENAMEを指定するとsfi.szTypeNameファイルタイプ名が入るのは確認できたのですが、SHGFI_ICONLOCATIONを指定してもsfi.szDisplayNameにアイコンファイル名が入ってくれません。(sfi.szDisplayName[0]='\0'で終わりになっている...) MSDNを見る限りはこれであっているようなのですが、正しい使い方を教えてください。

みんなの回答

  • cocky
  • ベストアンサー率57% (232/402)
回答No.4

正直うちの環境(Win98 + VC++ 6.0SP4)でもうまく行かないときはあります。 ただし、SHGFI_ICONを指定しておけばとりあえずアイコンハンドルが手に入るため、それをそのままMFCのCImageListとかに保存してListViewに渡してやればアイコンは表示できてしまうので、実際問題としてあまり不都合は感じてません。 WindowsCEを引き合いに出したのは、一応ターゲットとなっているOSプラットフォームが書かれていなかったため、念のため、と思ったまでのことです。 一応MSDN Knowledge Baseで検索をかけた結果でも、特にWin32環境で制限やバグがあるような報告は上がってなかったので、SHGFI_ICONLOCATIONがうまく働かない原因はいまだ謎のままです。

seata
質問者

お礼

解決になりませんでしたが、お付き合いくださいましてありがとうございました。

  • cocky
  • ベストアンサー率57% (232/402)
回答No.3

ひょっとすると、SHGFI_ICONLOCATIONだけではだめで、SHGFI_ICONも一緒に指定しないとだめなのではないでしょうか。MSDNのドキュメントには記載がありませんが。 あと気になるのは、WindowsCE Ver.2.10以降ではSHGFI_ICONLOCATIONはサポートされない、とMSDNドキュメントにも書かれているので、環境によってはSHGFI_ICONLOCATIONが使えなくなっている可能性も考えられます。

seata
質問者

補足

たびたびお付き合いありがとうございます。 SHGFI_ICONも指定しましたが、だめでした。 CEとWin32を関連付ける意味が良く解かりませんが、 となるとCEでサポートされない多くのWin32APIも使用不能の可能性がありますね。 環境によりというのはありえるかもしれませんが、 cockyさんの環境では、あのコードで問題なく取得出来るのでしょうか?

  • cocky
  • ベストアンサー率57% (232/402)
回答No.2

一つ確認ですが、「c:\hogehoge.txt」というファイルはHDD上に実在しますか? もし実在しないのであれば、SHGFI_USEFILEATTRIBUTESも一緒に指定しないと、Windowsが実際に「c:\hogehoge.txt」の情報を読みに行ってしまい、ファイルが存在しないためにエラーになってしまいますから、szDisplayNameに情報が入らないのも当たり前だと思いますが。

seata
質問者

補足

たびたびすみません。 ファイルは実在します。SHGFI_USEFILEATTRIBUTESを指定しても同じでした。 パラメータに問題があるのかと思い、ファイルの種類も取得するように 改良してみました。 #include <windows.h> #include <shellapi.h> #include <stdio.h> int main(int argc, char* argv[]) { SHFILEINFO sfi; ::CoInitialize(NULL); if(0 == ::SHGetFileInfo(".pdf", FILE_ATTRIBUTE_NORMAL, &sfi, sizeof(sfi), SHGFI_ICONLOCATION | SHGFI_TYPENAME | SHGFI_USEFILEATTRIBUTES)) return -1; printf("Icon location file = %s\n", sfi.szDisplayName); printf("Type name = %s\n", sfi.szTypeName); return 0; } 結果、 Icon location file = Type name = Adobe Acrobat文書 となりました。ファイルの種類は問題なく取得できるのですが、アイコンファイル名だけなぜかできないです。

  • cocky
  • ベストアンサー率57% (232/402)
回答No.1

他の拡張子のファイルでは試してみましたか? .txtのような拡張子だとアイコン情報がSystemImageListの中に入っていて、SHGFI_ICONLOCATIONを指定してもアイコンファイル名が出てこなかったように記憶してるんですが。

seata
質問者

補足

早速の回答ありがとうございます。 .txtではなく、.pdfにしてみましたAcrobatReaderの実行ファイルあたりが 返ってきてよさそうなのですが、結果は同じです。 SHGetFileInfo APIのドキュメントにも出てきますが、 SystemImageListというのが具体的にどのようなImageListなのか (シェルにキャッシュされているアイコンを集めたものか、shell32.dllあたり に格納されているシェル標準で持っているアイコンを集めたものか) よくわかっていません。 いろいろ検索して調べてみましたが、うまく行く例が見当たりません。 もし「こうすればうまく行く」みたいな例があると助かります。 すみません。

関連するQ&A