虛擬列表控制項(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...