虛擬列表控制項(CListCtrl)

2021-06-03 19:41:12 字數 3429 閱讀 3198

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) //字串緩衝區有效

}/*注意,多數情況下要使用lstrcpyn ,因為最多複製字元的個數由pitem->cchtextmax給出:

lstrcpyn(pitem->psztext, text, pitem->cchtextmax);

*/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;

//開始查詢

docurrentpos++;

//從頭開始

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)

虛擬列表控制項 clistctrl 2011年02月16日 星期三 下午 02 02 m list.setitemcount 100 3 處理它的通知訊息。五 如何響應虛擬列表的訊息 http www.pudn.com downloads72 sourcecode windows control l...

虛擬列表控制項(CListCtrl)

m list.setitemcount 100 3 處理它的通知訊息。五 如何響應虛擬列表的訊息 http www.pudn.com downloads72 sourcecode windows control listview detail261310.html 1 處理 lvn getdispi...

虛擬列表控制項(CListCtrl)

m list.setitemcount 100 3 處理它的通知訊息。五 如何響應虛擬列表的訊息 1 處理 lvn getdispinfo 通知訊息 當虛擬列表控制項需要某個資料的時候,它給父視窗傳送乙個 lvn getdispinfo通知訊息,表示請求某個資料。因此列表的所有者視窗 或者它自己 必...