仮想リスト コントロールは、LVS_OWNERDATA スタイルを持つリスト ビュー コントロールです。 このスタイルにより、コントロールは DWORD までの項目数をサポートできます (既定の項目数は int
にのみ拡張されます)。 ただし、このスタイルで提供される最大の利点は、一度にメモリ内のデータ項目のサブセットのみを持つことです。 これにより、仮想リスト ビュー コントロールは、データにアクセスする特定の方法が既に存在する大規模な情報データベースで使用できます。
注
MFC は、 CListCtrl
で仮想リスト機能を提供するだけでなく、 CListView クラスでも同じ機能を提供します。
仮想リスト コントロールを開発するときに注意する必要がある互換性の問題がいくつかあります。 詳細については、Windows SDK の「List-View コントロール」トピックの「互換性の問題」セクションを参照してください。
LVN_GETDISPINFO通知の処理
仮想リスト コントロールは、項目情報をほとんど保持します。 項目の選択とフォーカス情報を除き、すべての項目情報はコントロールの所有者によって管理されます。 情報は、LVN_GETDISPINFO通知メッセージを介してフレームワークによって要求されます。 要求された情報を提供するには、仮想リスト コントロール (またはコントロール自体) の所有者がこの通知を処理する必要があります。 これは 、クラス ウィザード を使用して簡単に実行できます ( 「関数へのメッセージのマッピング」を参照)。 結果のコードは次の例のようになります ( CMyDialog
が仮想リスト コントロール オブジェクトを所有し、ダイアログが通知を処理しています)。
ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST3, &CMyDialog::OnLvnGetdispinfoList3)
LVN_GETDISPINFO通知メッセージのハンドラーで、要求されている情報の種類を確認する必要があります。 指定できる値は次のとおりです。
LVIF_TEXT
pszText メンバーを入力する必要があります。LVIF_IMAGE
iImage メンバーを入力する必要があります。LVIF_INDENT
iIndent メンバーを入力する必要があります。LVIF_PARAM
lParam メンバーを入力する必要があります。 (サブ項目には存在しません。)LVIF_STATE
状態メンバーを入力する必要があります。
その後、フレームワークに要求された情報を指定する必要があります。
次の例 (リスト コントロール オブジェクトの通知ハンドラーの本文から取得) は、テキスト バッファーと項目の画像に関する情報を提供することで可能な 1 つの方法を示しています。
NMLVDISPINFO *pDispInfo = reinterpret_cast<NMLVDISPINFO *>(pNMHDR);
LVITEM *pItem = &(pDispInfo)->item;
int iItem = pItem->iItem;
if (pItem->mask & LVIF_TEXT) //valid text buffer?
{
switch (pItem->iSubItem)
{
case 0: //fill in main text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strItemText);
break;
case 1: //fill in sub item 1 text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strSubItem1Text);
break;
case 2: //fill in sub item 2 text
_tcscpy_s(pItem->pszText, pItem->cchTextMax,
m_Items[iItem].m_strSubItem2Text);
break;
}
}
if (pItem->mask & LVIF_IMAGE) //valid image?
{
pItem->iImage = m_Items[iItem].m_iImage;
}
キャッシュコントロールと仮想リストコントロール
この種類のリスト コントロールは大規模なデータ セットを対象としているため、取得パフォーマンスを向上させるために、要求された項目データをキャッシュすることをお勧めします。 フレームワークには、LVN_ODCACHEHINT通知メッセージを送信してキャッシュを最適化するためのキャッシュ ヒントメカニズムが用意されています。
次の例では、ハンドラー関数に渡された範囲でキャッシュを更新します。
void CMyDialog::OnLvnOdcachehintList3(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMLVCACHEHINT pCacheHint = reinterpret_cast<LPNMLVCACHEHINT>(pNMHDR);
// Update the cache with the recommended range.
for (int i = pCacheHint->iFrom; i <= pCacheHint->iTo; i++)
{
m_Items[i].m_iImage = i % 2;
m_Items[i].m_strItemText.Format(_T("Item %d"), i);
m_Items[i].m_strSubItem1Text = _T("Sub 1");
m_Items[i].m_strSubItem2Text = _T("Sub 2");
}
*pResult = 0;
}
キャッシュの準備と保守の詳細については、Windows SDK の「List-View コントロール」トピックの「キャッシュ管理」セクションを参照してください。
特定のアイテムの検索
LVN_ODFINDITEM通知メッセージは、特定のリスト コントロール項目が見つかる必要があるときに、仮想リスト コントロールによって送信されます。 通知メッセージは、リスト ビュー コントロールがクイック キー アクセスを受け取ったとき、またはLVM_FINDITEM メッセージを受信したときに送信されます。 検索情報は、NMLVFINDITEM 構造体のメンバーである LVFINDINFO 構造体の形式で送信されます。 このメッセージを処理するには、リスト コントロール オブジェクトの OnChildNotify
関数をオーバーライドし、ハンドラーの本文内で、LVN_ODFINDITEM メッセージを確認します。 見つかった場合は、適切なアクションを実行します。
リスト ビュー コントロールによって指定された情報と一致する項目を検索する準備が整っている必要があります。 成功した場合は項目のインデックスを返し、一致する項目が見つからない場合は -1 する必要があります。