WinXP+VC7.1+MFCです。
フォルダのアイコンをツリーアイコンとして設定しようとしているのですが、
アイテムを選択したときに、白抜きになってしまう部分があります。
【再現方法】
・ダイアログにツリーを貼り付け、変数の追加でツリーをm_tree1にします。
・Full Row Selectをtrueにします。
・ダイアログのOnInitDialog()に以下のコードを貼り付けます。
※ エラー判定など、いろいろ省いています
CImageList imgList;
imgList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 0, 0);
imgList.SetBkColor(RGB(255, 255, 255));
SHFILEINFO shfi;
HICON hIcon = (HICON)SHGetFileInfo(_T(C:\\WINDOWS), 0,
&shfi, sizeof(shfi), SHGFI_ICON | SHGFI_SMALLICON);
imgList.Add(shfi.hIcon);
DestroyIcon(shfi.hIcon);
m_tree1.SetImageList(&imgList, TVSIL_NORMAL);
imgList.Detach();
m_tree1.InsertItem(aaaa);
・実行してaaaaを選択すると、選択色とフォルダアイコンの隙間に
白抜きの部分が出来てしまいます。
何か足りない、または余計な処理があるのでしょうか?
ご教示、よろしくお願いいたします。
DestroyIcon(shfi.hIcon);をなくしてみたらどうなりますか?
愛飢え男さん、レスありがとうございます。
> DestroyIcon(shfi.hIcon);をなくしてみたらどうなりますか?
変わりませんでした。
いろいろ試してみてはいるのですが、
なかなかどうしてうまくいきません。。
> フォルダのアイコンをツリーアイコンとして設定しようとしているのですが、
> アイテムを選択したときに、白抜きになってしまう部分があります。
白抜きになっている部分は本来アルファチャンネルが適用され半透明化される部分なんだ
けど、このアルファチャンネルはWindows XP以降に対応したアプリでしか動作しないため
今回は×だった。という結論だと思われる。
> 何か足りない、
アプリを XP のビジュアルスタイル(マニフェストファイル)に対応させればokかと。
XPビジュアルスタイルに対応するのはイヤだ!
という場合はシステムが持っているイメージリストを借りる方法もある。
HIMAGELIST il = reinterpret_cast<HIMAGELIST>(
::SHGetFileInfo(_T(C:\\WINDOWS), 0, &shfi, sizeof(shfi),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON));
m_tree.SetImageList(CImageList::FromHandle(il), TVSIL_NORMAL);
m_tree.InsertItem(_T(aaaa), shfi.iIcon, shfi.iIcon);
> imgList.Detach();
TVM_SETIMAGELIST 等に載っている解説が正ならコレleakしちゃってるかも。
> The tree-view control will not destroy the image list specified with this
> message. Your application must destroy the image list when it is no longer
> needed.
gakさん、レスありがとうございます。
> アプリを XP のビジュアルスタイル(マニフェストファイル)に
> 対応させればokかと。
確認したところ、マニフェストを追加すれば直りました。
> TVM_SETIMAGELIST 等に載っている解説が正ならコレleakしちゃってるかも。
なるほど。
ツリーのDestroy時にGetImageList()->DeleteImageList();しておきます。
ありがとうございました。
>ツリーのDestroy時にGetImageList()->DeleteImageList();しておきます。
システムイメージリストは共有モノなので削除しちゃいけないんじゃなかったっけ?
Win9xで迂闊に削除したらエクスプローラまでアイコン表示しなくなっちゃたと思いま
す。
WinNT系ではプロセス別なのでそこまでひどくはならないけど、
同一プロセス内の他の個所ではそれ以後システムイメージが使えなくなるかと。
> システムイメージリストは共有モノなので削除しちゃいけないんじゃなかったっけ?
yes.
ただ、今回の質問者はシステムイメージリストではなく自作のイメージリストを
SetImageList() してるっぽい。
もし↑通りなら GetImageList()->DeleteImageList(); は有りかと。