|
アイテムに状態イメージをつける
今回はリストコントロールのアイテムに次のように状態イメージをつけてみます。状態イメージというのは、アイコンの隣に表示される、アイテムの状態をあらわすイメージです。使い道は自由ですが、独自のチェックボックスなどを作って使うこともできます。

ではまず、リソースエディタで状態イメージ用のビットマップを追加します。レポートビュー用に使うので、16x16の大きさのビットマップを横に並べて一枚のビットマップにします。今回は4つ用意して64x16の大きさのビットマップを作りました。また、背景は透過色で塗りつぶしておきます。透過色は何色にしてもいいですが、ここでは青色にしています。

状態イメージはCImageListクラスで管理します。これは複数のアイコンやビットマップを配列のように管理できるクラスです。状態イメージ用にダイアログクラスにCImageListクラスのメンバを追加しておきます。

では、コードの方を実装していきましょう。OnInitDialog()でリストコントロールを初期化します。長くなるので別関数にしています。
BOOL CListCtrl3Dlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // 大きいアイコンの設定
SetIcon(m_hIcon, FALSE); // 小さいアイコンの設定
// TODO: 初期化をここに追加します。
{
int err = 0;
if (!err) err = ListInit();
if (!err) err = ListAddItem();
}
return TRUE;
}
|
ではリストコントロールの初期化関数を見てみましょう。ここでイメージリストを初期化し、リストコントロールにセットします。
// リストコントロール初期化
int CListCtrl3Dlg::ListInit(void)
{
LVCOLUMN lvc;
int i;
TCHAR caption[][32] = {_T("商品名"), _T("単価")};
const int clmNum = sizeof caption /sizeof caption[0];
HICON hIcon = NULL;
int err = 0;
// アイコン用イメージリストの初期化
if (!err) if (!m_imageList.Create(16, 16, ILC_COLOR, 2, 1)) err = 1;
if (!err)
{
if ((hIcon = AfxGetApp()->LoadIcon(IDI_ICON_LIST1)) != NULL)
m_imageList.Add(hIcon);
if ((hIcon = AfxGetApp()->LoadIcon(IDI_ICON_LIST2)) != NULL)
m_imageList.Add(hIcon);
}
// 状態イメージ用イメージリストの初期化
if (!err) if (!m_imageListState.Create
(IDB_LIST_STATE, 16, 1, RGB(0, 0, 255))) err = 1;
// イメージリストをリストコントロールにセット
if (!err) m_xcList.SetImageList(&m_imageList, LVSIL_SMALL);
if (!err) m_xcList.SetImageList(&m_imageListState, LVSIL_STATE);
if (!err)
{
lvc.mask = LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
for (i = 0; i < clmNum; i++)
{
lvc.iSubItem = i;
lvc.pszText = caption[i];
lvc.cx = 150;
if (m_xcList.InsertColumn(i, &lvc) == -1) {err = 1; break;}
}
}
return err;
}
|
CImageList::Create()関数で状態イメージ用のイメージリストを初期化します。引数はビットマップリソースID、イメージの横幅、拡張単位、透過色です。次にCListCtrl::SetImageList()関数でイメージリストをリストコントロールにセットします。
| CImageList* CListCtrl::SetImageList(CImageList* pImageList, int nImageListType); |
| 説明: |
イメージリストをリストコントロールにセット |
| 引数: |
pImageList:CImageListクラスオブジェクトへのポインタ
nImageListType:イメージのタイプ。次のうちのいずれかを指定する。
LVSIL_NORMAL 大きなアイコンを持つイメージリスト
LVSIL_SMALL 小さなアイコンを持つイメージリスト
LVSIL_STATE 状態イメージを持つイメージリスト
|
| 戻り値: |
直前のイメージリストへのポインタ |
次はリストアイテムの追加関数です。
// リストコントロールアイテム追加
int CListCtrl3Dlg::ListAddItem(void)
{
struct
{
TCHAR name[32];
int price;
} item[] =
{
{_T("鉛筆"), 50},
{_T("消しゴム"), 100},
{_T("ボールペン"), 120},
{_T("万年筆"), 1000},
{_T("定規"), 150},
};
const int itemNum = sizeof item /sizeof item[0];
LVITEM lvi;
CString str;
int i, index = 0;
int err = 0;
for (i = 0; i < itemNum; i++)
{
// 商品名
if (!err)
{
lvi.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_STATE;
lvi.iItem = i;
lvi.iSubItem = 0;
lvi.pszText = item[i].name;
lvi.iImage = i %2;
lvi.stateMask = LVIS_STATEIMAGEMASK;
lvi.state = INDEXTOSTATEIMAGEMASK(i %5);
if ((index = m_xcList.InsertItem(&lvi)) == -1) err = 1;
}
// 単価
if (!err)
{
str.Format(_T("%d"), item[i].price);
lvi.mask = LVIF_TEXT;
lvi.iItem = index;
lvi.iSubItem = 1;
lvi.pszText = const_cast(static_cast(str));
if (!m_xcList.SetItem(&lvi)) err = 1;
}
if (err) break;
}
return err;
}
|
アイテムを追加する際に、LVITEM.maskメンバにLVIF_STATEを追加します。これでLVITEM.stateメンバが有効とみなされます。stateメンバは少し複雑で、状態イメージ以外にもいろいろな状態をセットできるようになっています。これらはビットごとに分かれています。状態イメージはビット12〜15を使います。4ビットあるので、イメージなしを含めて16種類まで状態イメージを使うことができるということになります。
stateメンバに状態イメージのインデックスをセットするときは、INDEXTOSTATEIMAGEMASKマクロを使うと便利です。このマクロの中身は、
#define INDEXTOSTATEIMAGEMASK(i) ((i) << 12)
となっていて、12ビットシフトしているだけです。インデックスは0を指定すると状態イメージは表示されません。1を指定すると最初の状態イメージ(ビットマップの左端のイメージ)が表示されます。
次はLVITEM.stateMaskメンバをセットします。これはstateメンバのどのビットが有効なのかを指定します。状態イメージはビット12〜15なので、0xF000をセットします。
#define LVIS_STATEIMAGEMASK 0xF000
という定義が用意されているので、これを使うとよいでしょう。
では、ビルドして実行してみましょう。リストアイテムの左側に状態イメージが表示されました。

|