📄 ieshelllistctrl.cpp
字号:
CUIODListCtrl::Init();
InitShellSettings();
InitImageLists();
m_bInitiliazed = true;
}
BOOL CIEShellListCtrl::InitItems(LPTVITEMDATA lptvid, bool bCallBack)
{
CWaitCursor w;
Init();
ASSERT(m_psfSubFolder);
if (m_psfSubFolder == NULL)
return FALSE;
// Try to initialize columns from shell
m_ShellDetails.SetShellDetails(NULL);
IShellFolder2 *pShellFolder2=NULL;
HRESULT hr=m_psfSubFolder->QueryInterface(IID_IShellFolder2,(LPVOID*)&pShellFolder2);
if (SUCCEEDED(hr))
{
LPUNKNOWN pUnk=NULL;
if (SUCCEEDED(pShellFolder2->QueryInterface(IID_IUnknown,(LPVOID*)&pUnk)))
{
m_ShellDetails.SetShellDetails(pUnk);
pUnk->Release();
}
m_ShellDetails.SetShellDetails((LPUNKNOWN)pShellFolder2);
pShellFolder2->Release();
}
else
{
IShellDetails *pShellDetails=NULL;
HRESULT hr = m_psfSubFolder->CreateViewObject(GetSafeHwnd(), IID_IShellDetails, (LPVOID*)&pShellDetails);
if (SUCCEEDED(hr))
{
LPUNKNOWN pUnk=NULL;
if (SUCCEEDED(pShellDetails->QueryInterface(IID_IUnknown,(LPVOID*)&pUnk)))
{
m_ShellDetails.SetShellDetails(pUnk);
pUnk->Release();
}
pShellDetails->Release();
}
}
InitColumns();
DWORD dwExStyle = GetExStyle();
if(!m_ShellSettings.DoubleClickInWebView())
{
dwExStyle |= LVS_EX_ONECLICKACTIVATE | LVS_EX_TRACKSELECT | LVS_EX_UNDERLINEHOT;
}
else
{
dwExStyle &= ~LVS_EX_ONECLICKACTIVATE;
dwExStyle &= ~LVS_EX_TRACKSELECT;
dwExStyle &= ~LVS_EX_UNDERLINEHOT;
}
SetExStyle(dwExStyle);
LPITEMIDLIST lpi=NULL;
LPENUMIDLIST lpe=NULL;
LPLVITEMDATA lplvid=NULL;
LPSHELLFOLDER lpsf=m_psfSubFolder;
ULONG ulFetched, ulAttrs;
HWND hwnd=::GetParent(m_hWnd);
DWORD dwFlags = SHCONTF_NONFOLDERS;
if (GetShellSettings().ShowAllObjects() && !GetShellSettings().ShowSysFiles())
dwFlags |= SHCONTF_INCLUDEHIDDEN;
hr=lpsf->EnumObjects(hwnd,dwFlags, &lpe);
if (FAILED(hr))
return FALSE;
bool bEndPopulate=false;
if (m_bPopulateInit == false)
{
StartPopulate();
bEndPopulate = true;
}
while (NO_ERROR==lpe->Next(1, &lpi, &ulFetched))
{
ulAttrs = SFGAO_HASSUBFOLDER | SFGAO_FOLDER | SFGAO_DISPLAYATTRMASK | SFGAO_CONTENTSMASK | SFGAO_REMOVABLE;
lpsf->GetAttributesOf(1, (LPCITEMIDLIST*)&lpi, &ulAttrs);
if (!FilterItem(lpsf,lpi,ulAttrs))
{
m_pMalloc->Free(lpi); // free PIDL the shell gave you
lpi=NULL;
continue;
}
lplvid = (LPLVITEMDATA)m_pMalloc->Alloc(sizeof(LVITEMDATA));
if (!lplvid)
break;
ZeroMemory(lplvid,sizeof(LVITEMDATA));
m_vecItemData.push_back(lplvid);
lplvid->ulAttribs=ulAttrs;
lplvid->lpifq=m_ShellPidl.ConcatPidl(lptvid->lpifq, lpi);
lplvid->lpsfParent=lpsf;
lplvid->lpsfParent->AddRef();
// Now make a copy of the ITEMIDLIST.
lplvid->lpi=m_ShellPidl.CopyItemID(lpi);
// Add the item to the list view control.
int nRow=-1;
if (bCallBack)
{
nRow = AddCallBackItem((DWORD)lplvid,I_IMAGECALLBACK);
if ((ulAttrs & SFGAO_COMPRESSED) && m_ShellSettings.ShowCompColor())
SetTextColor(nRow,0,RGB(0,0,255));
else
SetDefaultTextColor(nRow,-1);
}
else
{
nRow = AddTextItem();
if (nRow != -1)
{
TCHAR szText[MAX_PATH+1];
SetItemData(nRow,(DWORD)lplvid);
LV_DISPINFO dsp;
ZeroMemory(&dsp,sizeof(LV_DISPINFO));
dsp.item.mask |= (LVIF_TEXT | LVIF_IMAGE);
for(int i=0; i < GetColumnCount();i++)
{
szText[0] = 0;
dsp.item.iItem = nRow;
dsp.item.iSubItem = i;
dsp.item.cchTextMax = MAX_PATH;
dsp.item.pszText = szText;
if (i > 0)
dsp.item.mask &= ~LVIF_IMAGE;
m_bCallBack = true;
GetDispInfo(&dsp);
m_bCallBack = false;
SetIcon(nRow,dsp.item.iImage);
AddString(nRow,i,szText);
}
}
}
m_pMalloc->Free(lpi); // free PIDL the shell gave you
lpi=NULL;
}
if (lpe)
lpe->Release();
// The following two if statements will be TRUE only if you got here
// on an error condition from the goto statement. Otherwise, free
// this memory at the end of the while loop above.
if (lpi)
m_pMalloc->Free(lpi);
if (bEndPopulate)
EndPopulate();
return TRUE;
}
bool CIEShellListCtrl::FilterItem(LPSHELLFOLDER pFolder,LPCITEMIDLIST pidl,UINT ulAttrs)
{
if ((m_sFileFilter.IsEmpty() || m_sFileFilter == _T("*.*") || m_sFileFilter == _T("*"))
&& m_ExcludedLookup.IsEmpty())
return true;
bool bRet=false;
if (m_sFileFilter == _T("*.*") || m_sFileFilter == _T("*"))
{
bRet=true;
}
else if (!m_sFileFilter.IsEmpty())
{
CString sPath;
GetShellPidl().SHPidlToPathEx(pidl,sPath,pFolder);
if (m_FilterLookup.Find(sPath))
bRet = true;
}
if (bRet == false)
return bRet;
if (!m_ExcludedLookup.IsEmpty())
{
SHFILEINFO fileInfo;
ZeroMemory(&fileInfo,sizeof(fileInfo));
SHGetFileInfo((LPCTSTR)pidl, NULL, &fileInfo, sizeof(fileInfo), SHGFI_PIDL|SHGFI_TYPENAME);
if (m_ExcludedLookup.Find(fileInfo.szTypeName))
{
bRet = false;
}
}
return bRet;
}
void CIEShellListCtrl::InitShellSettings()
{
m_ShellSettings.GetSettings();
}
BOOL CIEShellListCtrl::InitImageLists()
{
HIMAGELIST himlSmall;
HIMAGELIST himlLarge;
SHFILEINFO sfi;
BOOL bSuccess=TRUE;
himlSmall = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T("C:\\"),
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
himlLarge = (HIMAGELIST)SHGetFileInfo((LPCTSTR)_T("C:\\"),
0,
&sfi,
sizeof(SHFILEINFO),
SHGFI_SYSICONINDEX | SHGFI_LARGEICON);
if (himlSmall && himlLarge)
{
::SendMessage(GetSafeHwnd(), LVM_SETIMAGELIST, (WPARAM)LVSIL_SMALL,
(LPARAM)himlSmall);
::SendMessage(GetSafeHwnd(), LVM_SETIMAGELIST, (WPARAM)LVSIL_NORMAL,
(LPARAM)himlLarge);
}
else
bSuccess = FALSE;
return bSuccess;
}
BEGIN_MESSAGE_MAP(CIEShellListCtrl, CUIODListCtrl)
//{{AFX_MSG_MAP(CIEShellListCtrl)
ON_MESSAGE(WM_SETMESSAGESTRING,OnSetmessagestring)
ON_MESSAGE(WM_SETTINGCHANGE,OnSettingChange)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_WM_DESTROY()
ON_WM_MENUSELECT()
//}}AFX_MSG_MAP
ON_MESSAGE(WM_APP_ON_DELETE_KEY,OnAppDeleteKey)
ON_MESSAGE(WM_APP_ON_PROPERTIES_KEY,OnAppPropertiesKey)
ON_MESSAGE(WM_APP_UPDATE_ALL_VIEWS,OnAppUpdateAllViews)
ON_MESSAGE(WM_APP_FILE_CHANGE_NEW_PATH,OnAppFileChangeNewPath)
ON_MESSAGE(WM_APP_FILE_CHANGE_EVENT,OnAppFileChangeEvent)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CIEShellListCtrl message handlers
void CIEShellListCtrl::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
{
CUIODListCtrl::OnMenuSelect(nItemID,nFlags,hSysMenu);
}
void CIEShellListCtrl::ShowPopupMenu(int nRow,int nCol,CPoint point)
{
if ((nCol > 0 || nRow == -1) || (m_PopupID || m_MultiPopupID))
{
CUIODListCtrl::ShowPopupMenu(nRow,nCol,point);
return;
}
PopupTheMenu(nRow,point);
}
void CIEShellListCtrl::OnDestroy()
{
SetImageList(NULL,LVSIL_SMALL);
SetImageList(NULL,LVSIL_NORMAL);
DestroyThreads();
CUIODListCtrl::OnDestroy();
}
bool CIEShellListCtrl::UseShellColumns()
{
return m_ShellDetails.IsValidDetails();
}
BOOL CIEShellListCtrl::GetDispInfo(LV_DISPINFO *pDispInfo)
{
// TODO: Add your specialized code here and/or call the base class
if (m_psfSubFolder == NULL || m_bCallBack == false)
return CUIODListCtrl::GetDispInfo(pDispInfo);
LPLVITEMDATA lplvid = (LPLVITEMDATA)GetItemData(pDispInfo->item.iItem);
ASSERT(lplvid);
if (lplvid == NULL)
return FALSE;
PSLC_COLUMN_DATA pColData=(PSLC_COLUMN_DATA)lplvid->lParam;
if (pColData == NULL)
{
pColData = new SLC_COLUMN_DATA;
pColData->sItems.SetSize(GetColumnCount());
lplvid->lParam = (LPARAM)pColData;
}
if (pColData->pidl == NULL)
pColData->pidl = m_ShellPidl.ConcatPidl(m_tvid.lpifq, lplvid->lpi);
if (pDispInfo->item.mask & LVIF_IMAGE)
{
if (pColData->iImage == -1)
{
pColData->iImage = m_ShellPidl.GetIcon(pColData->pidl,SHGFI_PIDL | SHGFI_SYSICONINDEX | SHGFI_SMALLICON);
}
pDispInfo->item.iImage = pColData->iImage;
if (lplvid->ulAttribs & SFGAO_GHOSTED)
{
pDispInfo->item.mask |= LVIF_STATE;
pDispInfo->item.stateMask = LVIS_CUT;
pDispInfo->item.state = LVIS_CUT;
}
if (lplvid->ulAttribs & SFGAO_LINK)
{
pDispInfo->item.mask |= LVIF_STATE;
pDispInfo->item.stateMask = LVIS_OVERLAYMASK;
pDispInfo->item.state = INDEXTOOVERLAYMASK(2);
}
if (lplvid->ulAttribs & SFGAO_SHARE)
{
pDispInfo->item.mask |= LVIF_STATE;
pDispInfo->item.stateMask = LVIS_OVERLAYMASK;
pDispInfo->item.state = INDEXTOOVERLAYMASK(1);
}
}
if (pDispInfo->item.mask & LVIF_TEXT)
{
if (UseShellColumns())
{
if (pDispInfo->item.iSubItem == COL_NAME)
{
if (pColData->sItems[pDispInfo->item.iSubItem].IsEmpty())
m_ShellPidl.GetName(lplvid->lpsfParent, lplvid->lpi, SHGDN_NORMAL, pColData->sItems[pDispInfo->item.iSubItem]);
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
if (m_bNoExt)
RemoveExt(pDispInfo->item.pszText);
}
else
{
if (pColData->sItems[pDispInfo->item.iSubItem].IsEmpty())
{
SHELLDETAILS sd;
ZeroMemory(&sd,sizeof(sd));
HRESULT hr = m_ShellDetails.GetDetailsOf(lplvid->lpi,pDispInfo->item.iSubItem,&sd);
LPTSTR pszText=NULL;
GetShellPidl().StrRetToStr(sd.str,&pszText,lplvid->lpi);
if (pszText)
{
_tcscpy(pDispInfo->item.pszText,pszText);
GetShellPidl().Free(pszText);
}
}
else
{
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
}
}
}
else
{
GetText(pColData,pDispInfo,lplvid);
}
}
return TRUE;
}
bool CIEShellListCtrl::GetColText(int nCol,LPCITEMIDLIST pidlAbs,LPLVITEMDATA lplvid,CString &sText)
{
return false;
}
void CIEShellListCtrl::GetText(PSLC_COLUMN_DATA pColData,LV_DISPINFO *pDispInfo,LPLVITEMDATA lplvid)
{
if (!pColData->sItems[pDispInfo->item.iSubItem].IsEmpty())
{
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
return;
}
LPITEMIDLIST pidlAbs = pColData->pidl;
CString sText;
if (GetColText(pDispInfo->item.iSubItem,pidlAbs,lplvid,sText))
{
pColData->sItems[pDispInfo->item.iSubItem] = sText;
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
return;
}
if (pDispInfo->item.iSubItem == COL_NAME)
{
if (pColData->sItems[pDispInfo->item.iSubItem].IsEmpty())
m_ShellPidl.GetName(lplvid->lpsfParent, lplvid->lpi, SHGDN_NORMAL,pColData->sItems[pDispInfo->item.iSubItem]);
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
if (m_bNoExt)
RemoveExt(pDispInfo->item.pszText);
}
else if (pDispInfo->item.iSubItem == COL_TYPE)
{
if (pColData->sItems[pDispInfo->item.iSubItem].IsEmpty())
{
SHFILEINFO fileInfo;
if (SHGetFileInfo((LPCTSTR)lplvid->lpi, NULL, &fileInfo, sizeof(fileInfo), SHGFI_PIDL|SHGFI_TYPENAME))
{
pColData->sItems[pDispInfo->item.iSubItem] = fileInfo.szTypeName;
}
}
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
}
else if (pDispInfo->item.iSubItem == COL_SIZE || pDispInfo->item.iSubItem == COL_MODIFIED)
{
if (pColData->sItems[COL_SIZE].IsEmpty() || (pColData->sItems[COL_MODIFIED].IsEmpty()))
{
CString sSize;
CString sDateTime;
GetFileDetails(pidlAbs,sSize,sDateTime);
if (pDispInfo->item.iSubItem == COL_SIZE)
pColData->sItems[pDispInfo->item.iSubItem] = sSize;
else if (pDispInfo->item.iSubItem == COL_MODIFIED)
pColData->sItems[pDispInfo->item.iSubItem] = sDateTime;
}
if (pDispInfo->item.iSubItem == COL_SIZE)
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
else if (pDispInfo->item.iSubItem == COL_MODIFIED)
_tcscpy(pDispInfo->item.pszText,pColData->sItems[pDispInfo->item.iSubItem]);
}
}
void CIEShellListCtrl::GetFileDetails(LPCITEMIDLIST pidl, CString &sSize, CString &sDateTime)
{
CString sPath;
GetShellPidl().SHPidlToPathEx((LPITEMIDLIST)pidl,sPath,NULL);
if (sPath.GetLength() <= 3)
return;
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile(sPath,&FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
unsigned __int64 fs = UMAKEINT64(FindFileData.nFileSizeLow, FindFileData.nFileSizeHigh);
unsigned __int64 kb=1;
TCHAR szText[1024];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -