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

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>
            欧美刺激午夜性久久久久久久| 国产小视频国产精品| 欧美成人午夜激情| 欧美专区第一页| 亚洲欧美伊人| 亚洲在线黄色| 久久精品一区二区国产| 亚洲欧美成人精品| 久久噜噜亚洲综合| 亚洲第一区在线| 国产精品高清网站| 国产精品久久久一区二区| 国产精品有限公司| 91久久在线| 亚洲欧美日韩在线观看a三区| 久久av红桃一区二区小说| 香蕉久久一区二区不卡无毒影院| 久久久福利视频| 日韩一级黄色av| 久久精品一区四区| 欧美婷婷久久| 国内精品久久久久影院 日本资源| 亚洲二区在线视频| 久久精品女人的天堂av| 日韩一级片网址| 欧美成人精品影院| 永久免费毛片在线播放不卡| 亚洲欧美在线一区二区| 夜夜嗨av一区二区三区网页| 美日韩丰满少妇在线观看| 国产精品久久国产精品99gif| 亚洲精品一区二区三区99| 欧美在线视频免费| 销魂美女一区二区三区视频在线| 欧美精品福利视频| 中日韩在线视频| 国产精品黄视频| 亚洲免费影院| 午夜精品一区二区三区在线| 国产日韩欧美二区| 免费看的黄色欧美网站| 欧美va亚洲va日韩∨a综合色| 亚洲高清久久久| 99精品福利视频| 国产精品久久久久久久久久久久| 一本色道久久综合狠狠躁篇的优点 | 国产精品久久久久久久9999| av成人毛片| 欧美一区二区久久久| 欧美激情一二区| 国产精品美女主播在线观看纯欲| 久久精品欧洲| 欧美视频不卡中文| 久久精品导航| 欧美性事在线| 久久av最新网址| 欧美电影在线播放| 久久精品一区二区三区不卡| 欧美国产精品专区| 久久综合久久久| 国产精品久久久久国产a级| 老司机67194精品线观看| 欧美视频在线看| 欧美激情一区二区三区| 狠狠综合久久av一区二区小说| 亚洲区一区二区三区| 国产精品日韩欧美一区| 亚洲精品久久在线| 亚洲日本va午夜在线影院| 亚洲视频电影在线| 一区二区不卡在线视频 午夜欧美不卡在 | 欧美日韩国产一级片| 久久久久久69| 国产视频精品网| 久久国产精品久久久久久电车| 亚洲欧美日韩国产中文| 一本一道久久综合狠狠老精东影业| 禁断一区二区三区在线 | 亚洲欧美在线网| 欧美黄色视屏| 亚洲精品国产精品国自产观看浪潮 | 亚洲综合色激情五月| 中文日韩在线| 国产乱码精品一区二区三区不卡 | 久久久久久久999精品视频| 久热这里只精品99re8久| 欧美成人免费全部| 一本色道久久加勒比88综合| 欧美另类人妖| 欧美综合77777色婷婷| 欧美激情女人20p| 欧美综合国产| 在线一区视频| 在线精品观看| 国产欧美日韩精品a在线观看| 久久久久久亚洲综合影院红桃| 亚洲精品乱码久久久久久| 久久精品国产视频| 午夜精品免费在线| 最新中文字幕一区二区三区| 国产精品免费视频xxxx| 欧美国产另类| 欧美精品国产一区| 欧美激情亚洲另类| 麻豆成人在线播放| 久久中文字幕一区二区三区| 亚洲视频观看| 亚洲美女淫视频| 很黄很黄激情成人| 国产一区二区0| 毛片基地黄久久久久久天堂| 久久久在线视频| 欧美.www| 91久久精品国产91久久| 久久婷婷久久一区二区三区| 亚洲专区一区| 欧美一区二区三区免费视频| 亚洲欧美一区二区精品久久久| 在线午夜精品自拍| 香蕉成人久久| 久久综合久久88| 亚洲精品资源| 欧美一区深夜视频| 老妇喷水一区二区三区| 欧美日韩大片| 国产日韩欧美综合一区| 在线看日韩av| 亚洲视频在线一区| 美女主播一区| 亚洲欧美视频在线| 欧美激情精品| 亚洲二区精品| 久久国产精品一区二区三区| 欧美不卡三区| 久久精品一区二区三区中文字幕| 欧美精品观看| 亚洲电影一级黄| 久久狠狠久久综合桃花| 一区二区黄色| 欧美精品日韩综合在线| 国一区二区在线观看| 羞羞色国产精品| 亚洲精品一区二区网址| 乱人伦精品视频在线观看| 国产亚洲一本大道中文在线| 亚洲精品孕妇| 亚洲另类在线一区| 欧美日韩激情小视频| 亚洲国产小视频在线观看| 欧美在线亚洲在线| 一区二区三区国产精品| 亚洲精品一区二区三区福利| 免费日韩av电影| 在线中文字幕一区| 亚洲欧美日韩国产| 伊人久久大香线| 亚洲福利视频在线| 欧美日韩综合一区| 久久电影一区| 亚洲欧洲另类| 亚洲欧美日韩精品在线| 国产一区二区三区高清| 美女久久一区| 欧美激情五月| 久久久久久免费| 欧美a一区二区| 校园春色国产精品| 久久久蜜桃一区二区人| 亚洲无线视频| 久久久久久久久伊人| 亚洲一区二区三区久久| 久久影视三级福利片| 亚洲自拍偷拍色片视频| 午夜性色一区二区三区免费视频| 亚洲国产精品久久精品怡红院| 中文国产一区| 一区二区三区高清在线观看| 久久精品盗摄| 欧美一区二区三区成人| 欧美日本不卡高清| 美女脱光内衣内裤视频久久网站| 欧美私人网站| 一区二区不卡在线视频 午夜欧美不卡在 | 亚洲精品国产精品乱码不99| 亚洲香蕉成视频在线观看| 9久re热视频在线精品| 亚洲免费在线视频| 亚洲第一二三四五区| 国产曰批免费观看久久久| 一区二区三区四区在线| 一区二区冒白浆视频| 欧美成人免费视频| 欧美高清在线| 亚洲丁香婷深爱综合| 欧美电影免费观看高清| 亚洲精品国产精品国自产观看浪潮 | 久久久久国产精品厨房| 久久综合久色欧美综合狠狠| 国产一区二区在线观看免费| 欧美在线观看www|