本示例演示了列表控件的虛列表和自畫功能,也演示了一些系統外殼的函數和接口的使用方法。
單擊這裡下載本文的代碼。
預備性閱讀
在閱讀本文之前,建議先對列表視圖控件和系統外殼有一個基本的了解。建議閱讀以下SDK文章
ShellFAQ
List-ViewControlsOverview
UsingList-ViewControls
CustomizingaControl'sAppearanceUsingCustomDraw
創建應用程序
使用MFC應用程序向導創建一個SDI應用程序,在最後一步選擇視圖的基類為CListView。創建完成之後,在資源中去掉保存、編輯和打印等功能的菜單和工具欄按鈕(因為這些功能沒有實現)。
虛列表的創建
本文采用虛列表技術,使得顯示信息是在第一次顯示的時候才被獲取。為了創建虛列表,在創建之前需要指定列表的風格
BOOLCPicViewView::PreCreateWindow(CREATESTRUCT&cs)
{
cs.style&=~LVS_TYPEMASK;
cs.style|=LVS_ICON|LVS_OWNERDATA;
returnCListView::PreCreateWindow(cs);
}
同時,因為列表項的Overlay圖標也是被動態獲取的,所以需要設置動態Overlay圖標
voidCPicViewView::OnInitialUpdate()
{
CListView::OnInitialUpdate();
GetListCtrl().SetCallbackMask(LVIS_OVERLAYMASK);
}
緩存顯示信息
在列表需要顯示一個范圍的項目之前,列表會發送LVN_ODCACHEHINT通知,應用程序可以捕獲這個消息來緩存部分列表的顯示信息,以提高性能。
voidCPicViewView::OnOdcachehint(NMHDR*pNMHDR,LRESULT*pResult)
{
NMLVCACHEHINT*pCacheHint=(NMLVCACHEHINT*)pNMHDR;
PrepCache(0,min(5,m_arpFolderItems.GetSize()));
PrepCache(pCacheHint->iFrom,pCacheHint->iTo);
PrepCache(max(0,m_arpFolderItems.GetSize()-5),m_arpFolderItems.GetSize());
*pResult=0;
}
在列表需要顯示一個項目之前,列表會發送LVN_GETDISPINFO通知,應用程序可以捕獲這個消息來提供項目的顯示信息。如果顯示時需要顯示的列表項在緩存中,那麼可以從緩存中獲取顯示信息。否則需要重新從文件獲得。
voidCPicViewView::OnGetdispinfo(NMHDR*pNMHDR,LRESULT*pResult)
{
LV_DISPINFO*pDispInfo=(LV_DISPINFO*)pNMHDR;
if(pDispInfo->item.iItem==-1)return;
HRESULThr=S_OK;
LPCITEMIDLISTpidlItem=m_arpFolderItems[pDispInfo->item.iItem];
CFolderItemInfo*pFolderItemInfo=FindItemInCache(pidlItem);
BOOLbCached=TRUE;
if(pFolderItemInfo==NULL){
bCached=FALSE;
pFolderItemInfo=newCFolderItemInfo;
GetItemInfo(pidlItem,pFolderItemInfo);
}
if(pDispInfo->item.mask&LVIF_TEXT){
lstrcpyn(pDispInfo->item.pszText,pFolderItemInfo->tszDisplayName,pDispInfo- >item.cchTextMax);
}
if(pDispInfo->item.mask&LVIF_IMAGE){
pDispInfo->item.iImage=pFolderItemInfo->iIcon;
}
if(pDispInfo->item.mask&LVIF_STATE){
pDispInfo->item.state=pFolderItemInfo->state;
}
if(!bCached)
deletepFolderItemInfo;
*pResult=0;
}