虛擬列表2

2021-06-17 22:15:25 字數 3329 閱讀 7196

虛擬列表控制項(clistctrl)

m_list.setitemcount(100);

3、處理它的通知訊息。

五、如何響應虛擬列表的訊息(

1、處理 lvn_getdispinfo 通知訊息

當虛擬列表控制項需要某個資料的時候,它給父視窗傳送乙個 lvn_getdispinfo通知訊息,表示請求某個資料。因此列表的所有者視窗(或者它自己)必須處理這個訊息。例如派生類的情況 (cmylistctrl是乙個虛擬列表類物件):

//這裡處理的是反射訊息

begin_message_map(cmylistctrl, clistctrl)

//}afx_msg_map

end_message_map()

在lvn_getdispinfo的處理函式中,必須首先檢查列表請求的是什麼資料,可能的值包括:

(1)lvif_text 

必須填充 psztext

(2)lvif_image 必須填充 iimage

(3)lvif_indent 必須填充 iindent

(4)lvif_param 必須填充 lparam

(5)lvif_state 必須填充 state

根據它的請求,填充所需的資料即可。

//***************== 例子*************************************==

下面的給出乙個例子,填充的是列表所需的某個資料項的文字以及影象資訊:

lv_dispinfo* pdispinfo = (lv_dispinfo*)pnmhdr;

lv_item* pitem= &(pdispinfo)->item;

int iitemindx= pitem->iitem;

if (pitem->mask & lvif_text) //字串緩衝區有效

}if (pitem->mask & lvif_image) //是否請求影象

pitem->iimage= m_items[iitemindx].m_iimageindex;

甚至連某行資料是否選中(當有checkbox的情況下)的資訊也需要由使用者自己來維護,例如:

//是否顯示該行的選擇資訊?

if(ischeckboxesvisible()) //自定義函式

else }

2、處理 lvn_odfinditem 訊息

在資源管理器裡面,定位到某個資料夾,會顯示很多檔案,如果按下鍵盤的'a',則資源管理器會自動找到名字以 'a'打頭的資料夾或者檔案, 並選擇該檔案。繼續按 a,如果還有其它名字以'a'打頭的檔案,則下乙個檔案被選中。如果輸入 "ab",則 'a''?頭的檔案被選中。這就是列表控制項的自動查詢功能。

當虛擬列表收到乙個lvm_finditem訊息,它也會傳送這個訊息通知父視窗查詢目標元素。要搜尋的資訊通過 lvfindinfo 結構給出。它是 nmlvfinditem 結構的乙個成員。當找到要搜尋的資料後,應該把該資料的索引(行號)返回,如果沒有找到,則返回-1。

以對話方塊為例,響應函式大致如下:

//***************== 例子*************************************==

void cvirtuallistdlg::onodfinditemlist(nmhdr* pnmhdr, lresult* presult)

//這是我們要找的字串

cstring searchstr = pfindinfo->lvfi.psz;

int startpos = pfindinfo->istart;//儲存起始位置

//判斷是否最後一行

if(startpos >= m_list.getitemcount())

startpos = 0;

int currentpos=startpos;

//開始查詢do 

currentpos++;

//從頭開始

if(currentpos >= m_list.getitemcount())

currentpos = 0;

}while(currentpos != startpos); 

}顯然,如果資料很多,必須實現乙個快速查詢的方法。

關於pfindinfo->lvfi裡面的資訊的詳細說明可以參考 msdn。

3、處理 lvn_odcachehint 訊息。

假如我們從資料庫或者其它地方讀取資料的速度比較慢,則可以利用這個訊息,批量讀取一些資料,然後根據請求,逐個提供給虛擬列表。lvn_odcachehint訊息的用途就是給程式乙個緩衝資料的機會。以提高程式的效能。

//***************== 例子*************************************==

使用 classwizard 過載 onchildnotify 函式,檢查是否 lvn_odcachehint 訊息,然後準備緩衝資料:

nmlvcachehint* pcachehint=null;

nmhdr* phdr = (nmhdr*)lparam;

if(phdr->code == lvn_odcachehint)

else ...

注意,如果訊息不是 lvn_odcachehint,則要傳遞給基類進行處理。

五、如何修改listctrl顯示的資料。

由於是程式自己維護資料,所以只需修改資料庫中的資料,然後呼叫clistctrl::redrawitems函式進行重畫即可。

六、資料的選擇狀態和選擇框

clistctrl可以顯示checkbox選擇框。有些情況下是很有用的。對於正常的listctrl,使用者可以用滑鼠來修改某個元素的選擇狀態,但是對於虛擬列表就不行了。必須自己處理一些訊息,然後自己儲存資料的選中狀態:

void cvirtuallistdlg::togglecheckbox(int item)

處理 lvn_keydown訊息,新增對空格鍵 的響應,用於切換選擇狀態:

void cvirtuallistdlg::onkeydownlist(nmhdr* pnmhdr, lresult* presult)

*presult = 0;

}然後處理 nm_click 訊息:

void cvirtuallistdlg::onclicklist(nmhdr* pnmhdr, lresult* presult)

} *presult = 0;

}七、備註:

1、虛擬列表無法進行排序。

2、虛表的乙個優點是容易保持和資料庫的同步。修改資料庫中的資料,然後重畫list十分容易而且高效。

3、虛表的另乙個優點是可以根據需要產生資料。比如在某一列加上行號。

本文引用於:

另外,國外的兩篇文章也值得參考:

文章**:

clistctrl 虛擬列表

一 什麼是虛擬列表控制項 虛擬列表控制項是指帶有lvs ownerdata風格的列表控制項。二 為什麼使用虛擬列表控制項 為此,mfc特別提供了虛擬列表的支援。乙個虛擬列表看起來和普通的listctrl一樣,但是不用通過insertitem來插入資料,它僅僅知道自己應該顯示多少資料。但是它如何知道要...

clistctrl 虛擬列表

一 什麼是虛擬列表控制項 虛擬列表控制項是指帶有lvs ownerdata風格的列表控制項。二 為什麼使用虛擬列表控制項 為此,mfc特別提供了虛擬列表的支援。乙個虛擬列表看起來和普通的listctrl一樣,但是不用通過insertitem來插入資料,它僅僅知道自己應該顯示多少資料。但是它如何知道要...

虛擬列表 LVN GETDISPINFO

lvn getdispinfo 當虛擬列表控制項需要某個資料的時候,它給父視窗傳送乙個 lvn getdispinfo通知訊息,表示請求某個資料。因此列表的所有者視窗 或者它自己 必須處理這個訊息。例如派生類的情況 cmylistctrl是乙個虛擬列表類物件 這裡處理的是反射訊息 begin mes...