本示例演示了列表控件的虚列表和自画功能,也演示了一些系统外壳的函数和接口的使用方法。 单击这里下载本文的代码。 预备性阅读 在阅读本文之前,建议先对列表视图控件和系统外壳有一个基本的了解。建议阅读以下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; } 文件图标的显示 默认情况下,列表项的图标就是其系统图标。首先获得系统图像列表 intCPicViewView::OnCreate(LPCREATESTRUCTlpCreateStruct) { if(CListView::OnCreate(lpCreateStruct)==-1) return-1; HRESULThr=SHGetMalloc(&m_pMalloc);if(FAILED(hr))return-1; hr=SHGetDesktopFolder(&m_psfDesktop);if(FAILED(hr))return-1; SHFILEINFOshfi; ZeroMemory(&shfi,sizeof(SHFILEINFO)); HIMAGELISThi=(HIMAGELIST)SHGetFileInfo(NULL,0,&shfi,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_SYSICONINDEX|SHGFI_SMALLICON); GetListCtrl().SetImageList(CImageList::FromHandle(hi),LVSIL_SMALL); hi=(HIMAGELIST)SHGetFileInfo(NULL,0,&shfi,sizeof (SHFILEINFO),SHGFI_ICON|SHGFI_SYSICONINDEX|SHGFI_LARGEICON); GetListCtrl().SetImageList(CImageList::FromHandle(hi),LVSIL_NORMAL); return0; } |