仮想リスト コントロール

仮想リスト コントロールは、LVS_OWNERDATA スタイルを持つリスト ビュー コントロールです。 このスタイルを使用すると、コントロールは DWORD (既定の項目数を拡張できるのは int のみまで) までの項目数をサポートできるようになります。 ただし、このスタイルによって提供される最大の利点は、どの時点においても、メモリ内のデータ項目のサブセットのみを持つことができる点です。 これにより、仮想リスト ビュー コントロールは、データにアクセスする特定の方法が既に用意されている大規模な情報データベースで使用できるようになります。

Note

CListCtrl で仮想リスト機能を提供できるほか、MFC は CListView クラスでも同じ機能を提供します。

仮想リスト コントロールを開発するときに注意する必要があるいくつかの互換性の問題があります。 詳細については、Windows SDK の「リスト ビュー コントロール」トピックの「互換性の問題」に関するセクションを参照してください。

LVN_GETDISPINFO 通知の処理

仮想リスト コントロールでは、項目情報はほとんど保持されません。 項目の選択とフォーカス情報を除き、すべての項目情報はコントロールの所有者によって管理されます。 情報は、LVN_GETDISPINFO 通知メッセージを介してフレームワークによって要求されます。 要求された情報を提供するには、仮想リスト コントロールの所有者 (またはコントロール自体) が、この通知を処理する必要があります。 これは、クラス ウィザード を使用して簡単に行えます (「関数へのメッセージの割り当て」を参照)。 結果のコードは次の例のようになります (CMyDialog は仮想リスト コントロール オブジェクトを所有し、ダイアログで通知を処理しています)。

ON_NOTIFY(LVN_GETDISPINFO, IDC_LIST3, &CMyDialog::OnLvnGetdispinfoList3)

LVN_GETDISPINFO 通知メッセージのハンドラーで、要求されている情報の種類を確認する必要があります。 指定できる値は、

  • LVIF_TEXTpszText メンバーに入力する必要があります。

  • LVIF_IMAGEiImage メンバーに入力する必要があります。

  • LVIF_INDENTiIndent メンバーに入力する必要があります。

  • LVIF_PARAMlParam メンバーに入力する必要があります (サブ項目については存在しない)。

  • LVIF_STATEstate メンバーに入力する必要があります。

その後、要求された情報をフレームワークに提供する必要があります。

次の例 (リスト コントロール オブジェクトの通知ハンドラーの本文から取得) は、項目のテキスト バッファーと画像に関する情報を提供することで、考えられるメソッドの 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 の「リスト ビュー コントロール」トピックの「キャッシュ管理」に関するセクションを参照してください。

特定の項目の検索

特定のリスト コントロール項目を検索する必要がある場合、LVN_ODFINDITEM 通知メッセージが仮想リスト コントロールによって送信されます。 この通知メッセージは、リスト ビュー コントロールがクイック キー アクセスを受け取った場合、または LVM_FINDITEM メッセージを受け取った場合に送信されます。 検索情報は、NMLVFINDITEM 構造体のメンバーである LVFINDINFO 構造体の形式で送信されます。 このメッセージを処理するには、リスト コントロール オブジェクトの OnChildNotify 関数をオーバーライドし、ハンドラーの本体内で LVN_ODFINDITEM メッセージを確認します。 見つかったら、適切なアクションを実行します。

リスト ビュー コントロールによって指定された情報と一致する項目を検索しておく必要があります。 成功した場合は項目のインデックスを返し、一致する項目が見つからない場合は -1 を返す必要があります。

関連項目

CListCtrl の使い方
コントロール