青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

S.l.e!ep.¢%

像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開心的工作
簡單、開放、平等的公司文化;尊重個(gè)性、自由與個(gè)人價(jià)值;
posts - 1098, comments - 335, trackbacks - 0, articles - 1
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

預(yù)備性閱讀
在閱讀本文之前,建議先對列表視圖控件和系統(tǒng)外殼有一個(gè)基本的了解。建議閱讀以下SDK文章

Shell FAQ
List-View Controls Overview
Using List-View Controls
Customizing a Control's Appearance Using Custom Draw
創(chuàng)建應(yīng)用程序
使用MFC應(yīng)用程序向?qū)?chuàng)建一個(gè)SDI應(yīng)用程序,在最后一步選擇視圖的基類為CListView。創(chuàng)建完成之后,在資源中去掉保存、編輯和打印等功能的菜單和工具欄按鈕(因?yàn)檫@些功能沒有實(shí)現(xiàn))。

虛列表的創(chuàng)建
本文采用虛列表技術(shù),使得顯示信息是在第一次顯示的時(shí)候才被獲取。為了創(chuàng)建虛列表,在創(chuàng)建之前需要指定列表的風(fēng)格

BOOL CPicViewView::PreCreateWindow(CREATESTRUCT& cs)
{
??? cs.style&=~LVS_TYPEMASK;
??? cs.style|=LVS_ICON|LVS_OWNERDATA;
??? return CListView::PreCreateWindow(cs);
}
同時(shí),因?yàn)榱斜眄?xiàng)的Overlay圖標(biāo)也是被動(dòng)態(tài)獲取的,所以需要設(shè)置動(dòng)態(tài)Overlay圖標(biāo)

void CPicViewView::OnInitialUpdate()
{
??? CListView::OnInitialUpdate();
??? GetListCtrl().SetCallbackMask(LVIS_OVERLAYMASK);
}

緩存顯示信息
在列表需要顯示一個(gè)范圍的項(xiàng)目之前,列表會(huì)發(fā)送LVN_ODCACHEHINT通知,應(yīng)用程序可以捕獲這個(gè)消息來緩存部分列表的顯示信息,以提高性能。

void CPicViewView::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;
}
在列表需要顯示一個(gè)項(xiàng)目之前,列表會(huì)發(fā)送LVN_GETDISPINFO通知,應(yīng)用程序可以捕獲這個(gè)消息來提供項(xiàng)目的顯示信息。如果顯示時(shí)需要顯示的列表項(xiàng)在緩存中,那么可以從緩存中獲取顯示信息。否則需要重新從文件獲得。

void CPicViewView::OnGetdispinfo(NMHDR* pNMHDR, LRESULT* pResult)
{
??? LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;
??? if(pDispInfo->item.iItem==-1)return;
??? HRESULT hr=S_OK;
??? LPCITEMIDLIST pidlItem=m_arpFolderItems[pDispInfo->item.iItem];
??? CFolderItemInfo* pFolderItemInfo=FindItemInCache(pidlItem);
??? BOOL bCached=TRUE;
??? if(pFolderItemInfo==NULL){
??????? bCached=FALSE;
??????? pFolderItemInfo=new CFolderItemInfo;
??????? 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)
??????? delete pFolderItemInfo;
??? *pResult = 0;
}


文件圖標(biāo)的顯示
默認(rèn)情況下,列表項(xiàng)的圖標(biāo)就是其系統(tǒng)圖標(biāo)。首先獲得系統(tǒng)圖像列表

int CPicViewView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
??? if (CListView::OnCreate(lpCreateStruct) == -1)
??????? return -1;
??? HRESULT hr = SHGetMalloc(&m_pMalloc); if(FAILED(hr)) return -1;
??? hr = SHGetDesktopFolder(&m_psfDesktop);if(FAILED(hr)) return -1;
??? SHFILEINFO shfi;
??? ZeroMemory(&shfi,sizeof(SHFILEINFO));
??? HIMAGELIST hi=(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);
??? return 0;
}

然后在獲取文件信息時(shí),從文件獲得其圖標(biāo)在系統(tǒng)圖像列表中的索引。

如果列表項(xiàng)是圖像文件,并且從文件成功載入圖像,那么使用自畫功能以替換默認(rèn)的圖標(biāo)。

void CPicViewView::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
??? LPNMLVCUSTOMDRAW lpNMCustomDraw = (LPNMLVCUSTOMDRAW) pNMHDR;
??? switch(lpNMCustomDraw ->nmcd.dwDrawStage) {
??????? case CDDS_PREPAINT : *pResult=CDRF_NOTIFYITEMDRAW;return;
??????? case CDDS_ITEMPREPAINT:*pResult=CDRF_NOTIFYPOSTPAINT;return;
??????? case CDDS_ITEMPOSTPAINT:
??????? {
??????????? int iItem=lpNMCustomDraw ->nmcd.dwItemSpec;
??????????? if(iItem==-1){
??????????????? *pResult=CDRF_DODEFAULT;return;
??????????? }
??????????? CFolderItemInfo* pItemInfo=FindItemInCache(m_arpFolderItems[iItem]);
??????????? if(pItemInfo==NULL||pItemInfo->bFailLoadPic||pItemInfo->pic.m_pPict==NULL){
??????????????? *pResult=CDRF_DODEFAULT;return;
??????????? }
??????????? CRect rectIcon;
??????????? GetListCtrl().GetItemRect(iItem,&rectIcon,LVIR_ICON);
??????????? CDC* pDC=CDC::FromHandle(lpNMCustomDraw->nmcd.hdc);
??????????? pItemInfo->pic.Render(pDC,rectIcon,rectIcon);
??????? }
??????? *pResult=CDRF_NEWFONT;return;
??? }
??? * pResult=0;
}

上面的代碼是使用獲取的文件顯示信息中的圖像,在列表項(xiàng)圖標(biāo)的區(qū)域畫圖。

獲取顯示信息
為了緩存列表項(xiàng)的顯示信息,或者顯示列表項(xiàng),需要獲取列表項(xiàng)的文字、圖標(biāo)、Overlay圖標(biāo)和縮略圖等信息。這里使用了ILCombine來把緩存中的相對PIDL轉(zhuǎn)化為完整的Pidl,再據(jù)此獲得文件的完整路徑,然后調(diào)用OleLoadPicturePath函數(shù)載入圖像。

void CPicViewView::GetItemInfo(LPCITEMIDLIST pidl,CFolderItemInfo* pItemInfo)
{
??? HRESULT hr = theApp.SHGetDisplayNameOf(pidl,pItemInfo->tszDisplayName);
??? IShellIcon* pShellIcon=NULL;
??? hr=m_psfFolder->QueryInterface(IID_IShellIcon,(LPVOID*)&pShellIcon);
??? if (SUCCEEDED(hr)&&pShellIcon){
??????? pShellIcon->GetIconOf(pidl,0,&pItemInfo->iIcon);
??????? pShellIcon->Release();
??? }
??? IShellIconOverlay* pShellIconOverlay =NULL;
??? hr=m_psfFolder->QueryInterface(IID_IShellIconOverlay,(LPVOID*)&pShellIconOverlay);
??? if (SUCCEEDED(hr)&&pShellIconOverlay){
??????? int nOverlay=0;
??????? pShellIconOverlay->GetOverlayIndex(pidl,&nOverlay);
??????? pItemInfo->state=INDEXTOOVERLAYMASK (nOverlay);
??????? pShellIconOverlay->Release();
??? }
??? LPITEMIDLIST pidlItemFull=ILCombine(m_pidlFolder,pidl);
??????? if(pidlItemFull){
??????????? if(SHGetPathFromIDList(pidlItemFull,pItemInfo->tszPath)){
??????????????? USES_CONVERSION;
??????????????? hr=OleLoadPicturePath(
??????????????????? T2OLE(pItemInfo->tszPath)
??????????????????? ,NULL,0,RGB(255,255,255)
??????????????????? ,IID_IPicture,(LPVOID*)&pItemInfo->pic.m_pPict);
??????????? if(FAILED(hr)){
??????????????????? pItemInfo->bFailLoadPic=TRUE;
??????????????????? TRACE("OleLoadPicturePath failed %s\r\n",pItemInfo->tszPath);
??????????????? }
??????????? }
??????? }
??????? m_pMalloc->Free(pidlItemFull);
??? }
}

緩存目錄的數(shù)據(jù)
在更改目錄時(shí),需要重建目錄內(nèi)容的緩存。這包括目錄的pidl和IShellFolder接口指針,目錄內(nèi)容的相對pidl,以及列表項(xiàng)的顯示信息(基于性能上的考慮,列表項(xiàng)的顯示信息是在接收到LVN_ODCACHEHINT通知的時(shí)候緩存的)。

LPITEMIDLIST m_pidlFolder;
IShellFolder * m_psfFolder;
CTypedPtrArray<CPtrArray,LPITEMIDLIST> m_arpFolderItems;
CTypedPtrMap<CMapPtrToPtr,LPITEMIDLIST,CFolderItemInfo*> m_mapCache;
?

void CPicViewView::EnterFolder(LPCITEMIDLIST pidl)
{
??? USES_CONVERSION;
??? m_pidlFolder=ILClone(pidl);
??? if(m_pidlFolder){
??????? LPENUMIDLIST ppenum = NULL;
??????? LPITEMIDLIST pidlItems = NULL;
??????? ULONG celtFetched;
??????? HRESULT hr;
??????? hr = m_psfDesktop->BindToObject(m_pidlFolder, NULL, IID_IShellFolder, (LPVOID *) &m_psfFolder);
??????? if(SUCCEEDED(hr)){
??????????? hr = m_psfFolder->EnumObjects(NULL,SHCONTF_FOLDERS | SHCONTF_NONFOLDERS, &ppenum);
??????????? if(SUCCEEDED(hr)){
??????????????? while( hr = ppenum->Next(1,&pidlItems, &celtFetched) == S_OK && (celtFetched) == 1){
??????????????????? m_arpFolderItems.Add(pidlItems);
??????????????????? }
??????????? }
??????? }
??????? GetListCtrl().SetItemCount(m_arpFolderItems.GetSize());
??? }
}

?

打開文件夾
本應(yīng)用程序顯示文件夾的內(nèi)容而不是顯示文檔的內(nèi)容,所以我重載了打開文件時(shí)的處理,顯示目錄選擇對話框而不是文件打開對話框。

void CPicViewApp::OnFileOpen()
{
??? TCHAR tszDisplayName[_MAX_PATH];
??? TCHAR tszPathSelected[_MAX_PATH];
??? LPITEMIDLIST pidlSelected=PidlBrowse(m_pMainWnd->GetSafeHwnd(),0,tszDisplayName);
??? if(pidlSelected){
??????? if(SHGetPathFromIDList(pidlSelected,tszPathSelected)){
??????????? CDocument* pDocument=OpenDocumentFile(tszPathSelected);
??????????? pDocument->SetTitle(tszDisplayName);
??????????? ILFree(pidlSelected);
??????? }
??? }
}

注意從外殼調(diào)用獲得的PIDL一般都需要調(diào)用ILFree或者IMalloc::Free釋放。一個(gè)例外是調(diào)用函數(shù)SHBindToParent獲得的相對pidl,因?yàn)樗禽斎氲膮?shù)完整pidl的一部分,所以不必另外釋放。

在新建或者打開“文件”時(shí)候,文檔需要通知視圖當(dāng)前文件夾的更改,這是通過調(diào)用CDocument::UpdateAllViews和重載CView::OnUpdate實(shí)現(xiàn)的。視圖對這個(gè)通知的處理是清除上一個(gè)目錄的緩存數(shù)據(jù),緩存新目錄的數(shù)據(jù),以及更新文檔標(biāo)題。
?

打開文件或者目錄
為了使用方便,雙擊列表項(xiàng)時(shí)可以在同一窗口打開子目錄,或者調(diào)用系統(tǒng)的默認(rèn)處理程序打開文件。如果文件是快捷方式,那么打開快捷方式的目標(biāo)。

void CPicViewView::OnDblclk(NMHDR* pNMHDR, LRESULT* pResult)
{
??? LPNMLISTVIEW lpnm=(LPNMLISTVIEW)pNMHDR;
??? if(lpnm->iItem==-1)return;
??? *pResult = 0;
??? HRESULT hr=S_OK;
??? LPCITEMIDLIST pidlItem=m_arpFolderItems[lpnm->iItem];
??? LPITEMIDLIST pidlItemFull=ILCombine(m_pidlFolder,pidlItem);
??? LPITEMIDLIST pidlItemTarget=NULL;
??? hr=theApp.SHGetTargetFolderIDList(pidlItemFull,&pidlItemTarget);
??? if(pidlItemTarget){
??????? if(theApp.ILIsFolder(pidlItemTarget)){
??????????? CFolderChange FolderChange;
??????????? FolderChange.m_pidlFolder=pidlItemTarget;
??????????? OnFolderChange(&FolderChange);
??????? }
??????? else{
??????????? SHELLEXECUTEINFO ShExecInfo;
??????????? ShExecInfo.cbSize = sizeof(SHELLEXECUTEINFO);
??????????? ShExecInfo.fMask = SEE_MASK_IDLIST;
??????????? ShExecInfo.hwnd = NULL;
??????????? ShExecInfo.lpVerb = NULL;
??????????? ShExecInfo.lpFile = NULL;
??????????? ShExecInfo.lpIDList= pidlItemTarget;
??????????? ShExecInfo.lpParameters = NULL;
??????????? ShExecInfo.lpDirectory = NULL;
??????????? ShExecInfo.nShow = SW_MAXIMIZE;
??????????? ShExecInfo.hInstApp = NULL;
??????????? ShellExecuteEx(&ShExecInfo);
??????? }
??????? m_pMalloc->Free(pidlItemTarget);
??????? m_pMalloc->Free(pidlItemFull);
??? }
}
?

性能的優(yōu)化
為了更好的用戶體驗(yàn),可以使用自定義的圖標(biāo)大小(這需要完全自行繪制列表項(xiàng)的圖標(biāo)區(qū)域),用單獨(dú)的線程來載入圖像,或者使用調(diào)整到圖標(biāo)大小的縮略圖緩沖(這樣每次繪制時(shí)不必拉伸圖像)。但是這超出了本文的范圍。有興趣的讀者可以自己試一下。

參考
需要更多信息的話,可以參考

Shell FAQ
List-View Controls Overview
Using List-View Controls
Customizing a Control's Appearance Using Custom Draw
本文來自焦點(diǎn)核(X)軟件安全技術(shù)網(wǎng),原文地址:http://www.xfocusx.com

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲国产精品欧美一二99| 国产日产欧产精品推荐色| 亚洲黄色成人网| 欧美成人精品一区二区| 久久综合网色—综合色88| 亚洲国产毛片完整版 | 美女网站久久| 欧美成人国产一区二区| 在线性视频日韩欧美| 宅男在线国产精品| 国产一区自拍视频| 亚洲高清成人| 国产精品欧美日韩一区| 久久久久久久久综合| 欧美成人在线影院| 香蕉精品999视频一区二区| 久久国产福利| 亚洲视频免费| 久久精品国产999大香线蕉| 日韩视频久久| 欧美一区二区黄色| 亚洲乱码国产乱码精品精天堂 | 亚洲视频一区在线观看| 国产一区在线播放| 亚洲精品自在在线观看| 国产亚洲欧美日韩在线一区| 亚洲国产精品嫩草影院| 国产欧美一区二区三区久久人妖| 欧美成人蜜桃| 国产精品网红福利| 亚洲国产精品高清久久久| 国产欧美日韩精品丝袜高跟鞋 | 久久婷婷麻豆| 国产精品大片wwwwww| 欧美成人69av| 国产一区二区三区免费观看| 亚洲激情偷拍| 在线观看欧美精品| 欧美一区二视频| 亚洲亚洲精品在线观看 | 亚洲午夜久久久久久久久电影网| 亚洲第一在线综合在线| 欧美亚洲免费在线| 欧美国产日韩免费| 母乳一区在线观看| 国产亚洲日本欧美韩国| 亚洲一区在线播放| 亚洲性xxxx| 欧美精品www在线观看| 欧美成人免费va影院高清| 国内精品久久国产| 欧美亚洲免费高清在线观看| 亚洲欧美日韩在线| 国产精品国产a| 99国产精品国产精品毛片| 亚洲精品一区二区三区在线观看| 久久精品国产亚洲a| 久久精品视频在线| 国产一级一区二区| 欧美一级二区| 久热re这里精品视频在线6| 国产欧美精品va在线观看| 亚洲无玛一区| 性xx色xx综合久久久xx| 国产精品视频网| 亚洲欧美日韩精品久久| 久久国产成人| 国产在线乱码一区二区三区| 性做久久久久久久免费看| 欧美中文字幕在线视频| 韩国一区二区在线观看| 久久久国产91| 亚洲国产欧美久久| 一区二区三区四区五区精品| 欧美日韩中字| 亚洲欧美在线磁力| 久久夜色精品亚洲噜噜国产mv| 在线观看不卡av| 米奇777超碰欧美日韩亚洲| 亚洲国产欧美国产综合一区| 中文av一区特黄| 国产精品一区二区你懂得| 欧美夜福利tv在线| 久久综合福利| 99亚洲一区二区| 国产精品区免费视频| 欧美一级艳片视频免费观看| 欧美成人性网| 亚洲一区影音先锋| 影音先锋另类| 欧美日韩精品二区| 欧美一级久久| 亚洲国产天堂久久综合网| 亚洲自拍都市欧美小说| 黄色亚洲网站| 欧美日韩影院| 久久中文字幕导航| 一区二区高清| 欧美好骚综合网| 亚洲欧美一区在线| 亚洲福利视频在线| 国产欧美日韩亚洲精品| 蜜桃精品一区二区三区 | 91久久国产综合久久| 欧美亚洲一级片| 亚洲精品欧美专区| 国产欧美日韩免费| 欧美精品日韩一区| 欧美在线高清| 亚洲一区二区三区乱码aⅴ蜜桃女| 久久一区二区三区四区| 亚洲一区二区在线免费观看| 亚洲第一主播视频| 久久精彩视频| 亚洲一区二区3| 亚洲伦伦在线| 欧美国产一区二区| 久久久久久成人| 亚洲欧美卡通另类91av| 99视频一区二区| 亚洲国产高潮在线观看| 国产综合18久久久久久| 国产精品美女| 国产精品久久二区二区| 欧美激情综合在线| 久久亚洲欧美国产精品乐播| 亚洲自拍三区| 亚洲一区二区三区精品动漫| 日韩视频一区| 亚洲精品在线观| 亚洲国产日韩欧美在线动漫| 欧美.日韩.国产.一区.二区| 久久精品视频在线观看| 欧美一区二区性| 欧美专区在线| 久久国产免费| 久久精品国产96久久久香蕉| 香蕉免费一区二区三区在线观看 | 久久精品国产一区二区三| 午夜一区二区三视频在线观看| 亚洲性感激情| 午夜精品成人在线| 欧美在线欧美在线| 欧美中文字幕在线播放| 久久国产精品亚洲va麻豆| 午夜伦理片一区| 欧美在线视频网站| 久久久999成人| 欧美成人精品h版在线观看| 欧美激情精品久久久久久蜜臀| 欧美顶级艳妇交换群宴| 亚洲国产精品久久91精品| 亚洲国产天堂久久综合网| 91久久中文字幕| 国产精品99久久久久久久久久久久| 亚洲精品视频一区| 亚洲男同1069视频| 久久久久国产一区二区| 久久人人97超碰人人澡爱香蕉| 久久久夜夜夜| 欧美精品在线免费观看| 欧美性理论片在线观看片免费| 国产欧美日本| 亚洲激情精品| 亚洲综合精品自拍| 久久激情综合| 亚洲高清视频一区二区| 亚洲午夜电影网| 久久激情综合网| 欧美精品在线视频| 国产亚洲欧美日韩日本| 日韩视频一区二区三区在线播放免费观看| 亚洲乱码国产乱码精品精 | 在线免费观看日韩欧美| 一区二区三区免费网站| 欧美中文在线观看| 亚洲福利在线看| 欧美一级久久久| 欧美精品1区| 国内精品久久久久久 | 一本色道久久综合亚洲精品按摩| 亚洲欧美三级在线| 欧美chengren| 亚洲在线日韩| 欧美激情国产日韩| 国产深夜精品| 一区二区三区av| 美女精品国产| 亚洲欧美美女| 亚洲亚洲精品在线观看| 久久躁日日躁aaaaxxxx| 国产美女精品视频| 99在线精品免费视频九九视| 久久久www| 亚洲与欧洲av电影| 欧美日韩成人综合在线一区二区| 国内精品久久国产| 欧美专区中文字幕| 亚洲视频精选| 欧美体内she精视频在线观看|