[轉MSDN]虛擬列表(MFC)

虛擬列表控件
Visual C++ 概念:添加功能
虛擬列表控件

虛擬列表控件指具有 LVS_OWNERDATA 樣式的列表視圖 (ListView) 控件。該樣式啓用控件來支持項數達到 DWORD(默認的項數只擴展到 int)。然而,該樣式的最大便利是可以使內存中一次只有一個數據項子集。這使虛擬列表視圖 (ListView) 控件可以將自己借給大型信息數據庫使用,而在這類數據庫中已存在特定的數據訪問方法。

注意    MFC 除了在CListCtrl 中提供虛擬列表功能外,還在 CListView 類中提供相同的功能。

在開發虛擬列表控件時應注意一些兼容性問題。有關更多信息,請參見 Platform SDK 中“列表-視圖控件”主題的“兼容性問題”一節。

處理 LVN_GETDISPINFO 通知

虛擬列表控件維護非常少的項信息。除了項選擇和焦點信息,所有項信息都由控件的所有者管理。框架通過 LVN_GETDISPINFO 通知消息來請求信息。若要提供請求的信息,虛擬列表控件的所有者(或控件本身)必須處理該通知。使用“屬性”窗口可以很容易地完成此操作(請參見將消息映射到函數)。所得到的代碼應類似於下面的示例(其中CMyListCtrl 是虛擬列表控件對象,控件正在處理通知)。

複製代碼
BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
   ON_NOTIFY_REFLECT(LVN_GETDISPINFO, OnGetdispinfo)
END_MESSAGE_MAP()

LVN_GETDISPINFO 通知消息的處理程序中,必須檢查正在請求的信息的類型。可能值是:

  • LVIF_TEXT    必須填寫 pszText 成員。
  • LVIF_IMAGE    必須填寫 iImage 成員。
  • LVIF_INDENT    必須填寫 iIndent 成員。
  • LVIF_PARAM    必須填寫 lParam 成員。
  • LVIF_STATE    必須填寫 state 成員。

然後應將所有請求的信息提供給框架。

下面的示例摘自列表控件 (List Control) 對象的通知處理程序體,它通過爲文本緩衝區和項的圖像提供信息來說明一種可能的方法:

複製代碼
LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
LV_ITEM* pItem= &(pDispInfo)->item;

int iItemIndx= pItem->iItem;

if (pItem->mask & LVIF_TEXT) //valid text buffer?
{
    switch(pItem->iSubItem){
        case 0: //fill in main text
            lstrcpy(pItem->pszText, 
                m_Items[iItemIndx].m_strItemText);
            break;
        case 1: //fill in sub item 1 text
            lstrcpy(pItem->pszText,
                m_Items[iItemIndx].m_strSubItem1Text);
            break;
        case 2: //fill in sub item 2 text
            lstrcpy(pItem->pszText,
                m_Items[iItemIndx].m_strSubItem2Text);
            break;
    }
}

if pItem->mask & LVIF_IMAGE) //valid image?
        pItem->iImage= 
            m_Items[iItemIndx].m_iImageIndex;

緩存和虛擬列表控件

由於這種類型的列表控件 (List Control) 是提供給大的數據集的,因此建議您緩存請求的項數據以提高檢索性能。框架提供緩存提示機制,通過發送 LVN_ODCACHEHINT 通知消息來幫助優化緩存。但是,您必須使用一種稍有不同的方法來處理該通知。使用“屬性”窗口,重寫列表控件 (List Control) 對象的OnChildNotify 函數。在該示例的情況下爲 CMyListCtrl

在處理程序體中檢查 LVN_ODCACHEHINT 消息,如果找到,則準備緩存。

下面的示例(摘自 OnChildNotify 函數體)執行此檢查並調用CMyListCtrl 類的 PrepCache 成員函數。

複製代碼
NMLVCACHEHINT* pcachehint=NULL;

if (message == WM_NOTIFY)
    {
        NMHDR* phdr = (NMHDR*)lParam;

        switch(phdr->code)
        {
        case LVN_ODCACHEHINT:
            pcachehint= (NMLVCACHEHINT*) phdr;
// Load the cache with the recommended range.
            PrepCache(pcachehint->iFrom, pcachehint->iTo);
            break;
        default:
            return CListCtrl::OnChildNotify(message, wParam, lParam, pLResult);
        }
        return FALSE;
    }
    else
        return CListCtrl::OnChildNotify(message, wParam, lParam, pLResult);

注意,如果消息類型不是 LVN_ODCACHEHINT,則通知將傳遞給基類 (CListCtrl)。有關準備和維護緩存的更多信息,請參見 Platform SDK 中的“列表-視圖控件”主題的“緩存管理”一節。

查找特定的項

當需要查找特定的列表控件項時,虛擬列表控件發送 LVN_ODFINDITEM 通知消息。列表視圖 (ListView) 控件接收快捷鍵訪問或接收LVM_FINDITEM 消息時發送該通知消息。搜索信息以 LVFINDINFO 結構的格式發送,該結構是NMLVFINDITEM 結構的成員。通過重寫列表控件 (List Control) 對象的 OnChildNotify 函數來處理該消息,並在處理程序體中檢查LVN_ODFINDITEM 消息。如果找到此消息,則執行相應的操作。

您應該準備好搜索與列表視圖 (ListView) 控件給定的信息匹配的項。如果成功,則應返回項的索引;如果沒有找到匹配項,則返回 -1。

請參見

使用 CListCtrl |Windows 公共控件和 MFC 類

發佈了3 篇原創文章 · 獲贊 29 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章