DrawItemのLV_ITEMについて

[戻る]
Nezu 2008/04/22(火) 16:59:52
すみません、以前「DrawItemでBitmap表示」の質問の途中で解決をつけてしまったので
質問し直します。

環境:MFC(ダイアログ) VS2005

ListCtrlのサブアイテムに、DrawItemを使ってBitmapを表示させているのですが、
DrawItem内のLV_ITEMのiImageメンバの値が常に0になってしまいます。
このため、常にイメージリストの0番目の画像が表示されてしまいます。

Dlgクラスにイメージのインデックスを渡す関数を追加し、表示の際にインデックスを渡
すようにしましたが、再描画の際におかしくなります。

原因は、一列目のカラムを
InsertItem(0, ""); ←CheckBoxを表示させています。
このため、InsertItemの3番目のパラメータがデフォルトの0になっているためだと考え
ています。
しかし、解決の仕方が分かりません。
InsertItem以外でCheckBoxを表示させるしかないのでしょうか?
ご教授願います。

PATIO 2008/04/23(水) 15:34:39
えーと、DrawItemはどの単位で呼ばれているかの確認はしましたか?

DrawItemがアイテム単位で呼ばれていてサブアイテム毎には呼ばれていないなら
サブアイテムに関する描画については自分で情報を取得して描画しないといけない
と思います。どうも書かれているなようだけを見るとアイテム単位で呼ばれている
ような気がするので処理が足りないのでは無いかと言う気がします。

例えば、
一回DrawItemが呼ばれたら、まず、アイテム(並べ替えていないなら左端)の
描画を行い、存在するサブアイテムの情報を一つずつ取り出して各々を適切に
描画していくという話です。
サブアイテムにイメージを割り当てる時にどのようにしているのか解りませんが、
サブアイテムの部分にビットマップを描画したいのであれば、どのビットマップを
描画すれば良いかをどのようにリストコントロールに設定しているかによって
取り出す側の話が変わると思います。

Nezu 2008/04/23(水) 17:31:40
PATIOさん、お世話になってます。

>えーと、DrawItemはどの単位で呼ばれているかの確認はしましたか?
おっしゃる通り、アイテムごとに呼ばれていました。

>サブアイテムの部分にビットマップを描画したいのであれば、どのビットマップを
>描画すれば良いかをどのようにリストコントロールに設定しているかによって
>取り出す側の話が変わると思います。

Dlgクラス側ではCImageListに画像を追加し、SetImageListでListCtrlにイメージを設定
し、

m_listCtrl.SetItem(Index, 4, LVIF_IMAGE, _T(""), Image,0,0,0);
Index : 表示させたいリストの行
Image : 表示させたいイメージのインデックス

を呼んで表示させています。

CRect rcIcon;
GetItemRect(nItem, rcIcon, LVIR_ICON);

DrawItem()内

pImageList = this->GetImageList(LVSIL_SMALL);
if (pImageList)
{
    UINT nOvlImageMask=lvi.state & LVIS_OVERLAYMASK;
    if (rcItem.left<rcItem.right-1)
    {
    //サブアイテムの情報を取得
    ListView_GetSubItemRect(hList, lpDrawItemStruct->itemID
                           ,4, LVIR_ICON, &rcIcon);
    int ImageIndex = Dlgクラス側からイメージのインデックスを取得    
    //サブアイテムに表示
    ImageList_Draw(pImageList->m_hImageList,
            ImageIndex, 
            pDC->m_hDC,
            rcIcon.left, 
            rcIcon.top,
            uiFlags | nOvlImageMask);
     }
}

※最初にも書きましたが、ImageList_Draw()の第2引数をLV_ITEMのiImageにすると、常
に0番目のイメージが表示されてしまうので、Dlgクラス側でインデックスを渡していま
す。

取り出す側はどのようになるのでしょう?

gak 2008/04/24(木) 17:54:46
LVS_EX_SUBITEMIMAGES を未設定なのでimageのindexを取得できないってオチなのか、単
に GetItem() の存在を知らなかったのか詰まっている状況が今一掴めないが…
とりあえず普通にやっているなら下記の感じでいけると思われ。

LVITEM item;
item.mask = LVIF_IMAGE;
item.iItem = lpDrawItemStruct->itemID;
item.iSubItem = 4;
m_listCtrl.GetItem(&item);
pImageList->Draw(pDC, item.iImage, rcIcon.TopLeft(), uiFlags | nOvlImageMask);

Nezu 2008/04/24(木) 18:55:30
gakさん、ありがとうございます。

DrawItem内に記述してみたのですが、やはりLVITEMのiImageのインデックスが
意図したものになっていません。

DrawItemは、CListCtrlの派生クラスに記述しているのですが、
DrawItemを呼び出す側(Dlgクラス側)ではどのようにすればよいのでしょうか?

>LVS_EX_SUBITEMIMAGES を未設定なのでimageのindexを取得できないってオチなのか、
>単に GetItem() の存在を知らなかったのか詰まっている状況が今一掴めないが…

LVS_EX_SUBITEMIMAGESは設定してあります。

Nezu 2008/04/24(木) 19:46:01
[[解決]]
すいません、記述が少し間違っていました。
無事、gakさんの方法でできました。
再描画されても大丈夫です。

gakさん、PATIOさん、ありがとうございました!

古いスレッドには追加発言できません。