こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

SHGetFileInfoでアイコンが取得できない場合がある

VC++にてエクスプローラもどきを作成しています。

ListViewへファイルアイコンを表示するために、
SHGetFileInfoを使用し、

// 大きいアイコンのハンドル取得
// fnameは拡張子だけの文字列です
SHGetFileInfo( fname, NULL, &shfInfo, sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES );
licon = shfInfo.hIcon;

上記のようにしてファイルアイコンを取得し、
CImageListへ追加した上で、描画しています。
そして、ダイアログのサイズが変更された際に、
OnSize関数にて、ListView内のアイコンを再度取得し、
再描画しているのですが、
何度もOnSizeで再描画を行っているうちに、
SHGetFileInfoにて取得したshfInfo.hIconが
NULLになってしまいます。
一度、shfInfo.hIconがNULLになると、
何度、SHGetFileInfoを呼んでも、返ってくるhIconは
毎回NULLになってしまい、ListView内に
アイコンが表示されません。

SHGetFileInfo関数を呼ぶ際の制約等があるのでしょうか?

投稿日時 - 2009-03-11 16:21:03

QNo.4787832

困ってます

質問者が選んだベストアンサー

 こんにちは。
 リソースリークしているのではないでしょうか。
 取り敢えず、使い終わったアイコンのハンドルを削除して見て下さい。
 因みに以下で再現出来しました。

SHFILEINFO shfInfo;
//取り敢えずノートパッド(メモ帳)のアイコンを取って来る
TCHAR szPath[] = _T("C:\\WINNT\\notepad.exe");
for(int i = 0; i < 100000; ++i)
{
SHGetFileInfo( szPath, NULL, &shfInfo, sizeof(SHFILEINFO),SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES );
HICON hicon = shfInfo.hIcon;

//此れを呼べば大丈夫
//::DestroyIcon(hicon);
if(hicon == NULL)
{
//いずれココに来る
}
}

投稿日時 - 2009-03-11 17:16:20

お礼

直りました。ありがとうございます。
SHGetFileInfoでも内部でアイコンを作成しているんですね。
とはいえ、CImageListにAddした直後にDestroyIconしても
キチンと表示されているのは不可解な気もしますが。。。
Addしているんだから、描画はAddされたアイコンを使うのでは???
Destroyしちゃったら、何を使って描画させてるんだろう???

投稿日時 - 2009-03-11 17:58:41

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(1)

あなたにオススメの質問