⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ieshelllistctrl.cpp

📁 vc座的资源管理器源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//*******************************************************************************
// COPYRIGHT NOTES
// ---------------
// You may use this source code, compile or redistribute it as part of your application 
// for free. You cannot redistribute it as a part of a software development 
// library without the agreement of the author. If the sources are 
// distributed along with the application, you should leave the original 
// copyright notes in the source code without any changes.
// This code can be used WITHOUT ANY WARRANTIES at your own risk.
// 
// For the latest updates to this code, check this site:
// http://www.masmex.com 
// after Sept 2000
// 
// Copyright(C) 2000 Philip Oldaker <email: philip@masmex.com>
//*******************************************************************************

// IEShellListCtrl.cpp : implementation file
#include "stdafx.h"
#include "IEShellListCtrl.h"
#include "UIMessages.h"
#include "dirwalk.h"
#include "cbformats.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define UMAKEINT64(low,high) ((unsigned __int64)(((DWORD)(low)) | ((unsigned __int64)((DWORD)(high))) << 32))
/////////////////////////////////////////////////////////////////////////////
// CIEShellListCtrl

CIEShellListCtrl::CIEShellListCtrl()
{
	SetEditSubItems(false);
	SetDropFiles(false);
	ZeroMemory(&m_tvid,sizeof(m_tvid));
	m_psfSubFolder = NULL;
	m_pMalloc = NULL;
	m_bCallBack = false;
	m_bNoExt = false;
	m_nThreadCount = 0;
	m_bRefreshAllowed = true;
	m_bPopulateInit = false;
	m_bInitiliazed = false;
	m_bNotifyParent = false;
	m_pidlInternet = NULL;
	SHGetMalloc(&m_pMalloc);
	SHGetSpecialFolderLocation(NULL,CSIDL_INTERNET,&m_pidlInternet);
	m_sColumns = _T("Name|Size|Type|Modified");
}

CIEShellListCtrl::~CIEShellListCtrl()
{
	FreeTVID();
	AllItemsDeleted();
	if (m_pidlInternet)
		m_pMalloc->Release();
	if (m_pMalloc)
		m_pMalloc->Release();
}

void CIEShellListCtrl::PopupTheMenu(int nRow,CPoint point)
{
	if (!GetSelectedCount())
		return;
	int nSel=-1;
	LPLVITEMDATA lplvid=NULL;
	LPITEMIDLIST *pidls=(LPITEMIDLIST*)GetShellPidl().GetMalloc()->Alloc(GetSelectedCount()*sizeof(LPITEMIDLIST));
	int i=0;
	while ((nSel = GetNextSel(nSel)) != -1)
	{
		lplvid=(LPLVITEMDATA)GetItemData(nSel);
		pidls[i] = lplvid->lpi;
		i++;
	}
	// at least one
	if (pidls && i)
	{
		GetShellPidl().PopupTheMenu(m_hWnd, lplvid->lpsfParent, pidls, i, &point);
	}
	GetShellPidl().Free(pidls);
}

void CIEShellListCtrl::ShellExecute(int nRow,LPCTSTR pszVerb)
{
	SHELLEXECUTEINFO si;
	ZeroMemory(&si,sizeof(si));
	si.cbSize = sizeof(si);
	si.hwnd = GetSafeHwnd();
	si.nShow = SW_SHOW;
	si.lpIDList = (LPVOID)GetPathPidl(nRow);
	si.fMask  = SEE_MASK_INVOKEIDLIST;
	if (pszVerb)
		si.lpVerb = pszVerb;
	ShellExecuteEx(&si);
}

void CIEShellListCtrl::SetNotificationObject(bool bNotify)
{
	if (bNotify)
		CreateFileChangeThread(GetSafeHwnd());
	else
		DestroyThreads();
}

void CIEShellListCtrl::FreeInterface(IUnknown *pInterface)
{
	if (pInterface)
		pInterface->Release();
}

void CIEShellListCtrl::DestroyThreads()
{
    if (m_nThreadCount == 0) 
		return;
    for (UINT i=0; i<m_nThreadCount; i++)
	    m_event[i].SetEvent();
    ::WaitForMultipleObjects (m_nThreadCount, m_hThreads, TRUE, INFINITE);
    for (i=0; i<m_nThreadCount; i++)
        delete m_pThreads[i];
    m_nThreadCount = 0;
}

void CIEShellListCtrl::FreeTVID()
{
	if (m_tvid.lpsfParent)
		m_tvid.lpsfParent->Release();
	if (m_tvid.lpi)
		m_pMalloc->Free(m_tvid.lpi);
	if (m_tvid.lpifq)
		m_pMalloc->Free(m_tvid.lpifq);
	ZeroMemory(&m_tvid,sizeof(m_tvid));
	if (m_psfSubFolder)
		m_psfSubFolder->Release();
	m_psfSubFolder = NULL;
}

CString CIEShellListCtrl::GetCurrPathName()
{
	return GetPathName(GetCurSel());
}

CString CIEShellListCtrl::GetPathName(int nRow)
{
	if (nRow == -1)
		nRow = GetCurSel();
	CString sPath;
	if (nRow == -1)
		return sPath;
	LPLVITEMDATA plvit = (LPLVITEMDATA)GetItemData(nRow);
	ASSERT(plvit);
	if (plvit == NULL)
		return sPath;
	SHGetPathFromIDList(plvit->lpifq,sPath.GetBuffer(MAX_PATH));
	sPath.ReleaseBuffer();
	return sPath;
}

LPCITEMIDLIST CIEShellListCtrl::GetPathPidl(int nRow)
{
	if (nRow == -1)
		return NULL;
	LPLVITEMDATA plvit = (LPLVITEMDATA)GetItemData(nRow);
	ASSERT(plvit);
	if (plvit == NULL)
		return NULL;
	return plvit->lpifq;
}

void CIEShellListCtrl::FillExcludedFileTypes(CComboBox &cb)
{
	cb.ResetContent();
	for(POSITION pos=m_ExcludedLookup.GetHeadPosition();pos != NULL;m_ExcludedLookup.GetNext(pos))
	{
		cb.AddString(m_ExcludedLookup.GetAt(pos));
	}
}

void CIEShellListCtrl::SetExcludedFileTypes(CComboBox &cb)
{
	m_ExcludedLookup.RemoveAll();
	CString sText;
	for(int i=0;i < cb.GetCount();i++)
	{
		cb.GetLBText(i,sText);
		m_ExcludedLookup.AddHead(sText);
	}
}

void CIEShellListCtrl::LoadFilterFiles(const CString &sFileFilter)
{
	m_FilterLookup.RemoveAll();
	CFileFind ff;
	CString sPath;
	if (FAILED(GetShellPidl().SHPidlToPathEx(m_tvid.lpifq,sPath)))
		return;
	if (sPath.Right(1) != _T('\\'))
		sPath += _T('\\');
	CString sFindPath;
	CString sMask;
	LPCTSTR pszFilter=sFileFilter;
	pszFilter = GetFilterMask(pszFilter,sMask);
	while (pszFilter != NULL)
	{
		sFindPath = sPath;
		sFindPath += sMask;
		BOOL bFind = ff.FindFile(sFindPath);  
		while (bFind)
		{
			bFind = ff.FindNextFile();
			m_FilterLookup.AddHead(ff.GetFilePath());
		}
		pszFilter = GetFilterMask(pszFilter,sMask);
	}
}

LPCTSTR CIEShellListCtrl::GetFilterMask(LPCTSTR pszFilter,CString &sMask)
{
	if (*pszFilter == '\0')
		return NULL;
	TCHAR szMask[MAX_PATH];
	szMask[0] = 0;
	for(int i=0;*pszFilter != '\0';i++)
	{
		if (*pszFilter == _T(';') || *pszFilter == _T(','))
		{
			pszFilter = _tcsinc(pszFilter);
			break;
		}
		szMask[i] = *pszFilter;
		pszFilter = _tcsinc(pszFilter);
	}
	szMask[i] = 0;
	sMask = szMask;
	return pszFilter;
}

void CIEShellListCtrl::AllItemsDeleted()
{
	LPLVITEMDATA pItemData=NULL;
	for(vecListItemData::iterator it=m_vecItemData.begin();it != m_vecItemData.end();it++)
	{
		pItemData = *it;
		if (pItemData)
		{
			if (pItemData->lpsfParent)
				pItemData->lpsfParent->Release();
			if (pItemData->lpi)
				m_pMalloc->Free(pItemData->lpi);  
			if (pItemData->lpifq)
				m_pMalloc->Free(pItemData->lpifq);  
			if (pItemData->lParam)
			{
				PSLC_COLUMN_DATA pColData = (PSLC_COLUMN_DATA)pItemData->lParam;
				if (pColData->pidl)
					GetShellPidl().FreePidl(pColData->pidl);
				delete pColData;
			}
			m_pMalloc->Free(pItemData);
		}
	}
	m_vecItemData.erase(m_vecItemData.begin(),m_vecItemData.end());
}

void CIEShellListCtrl::StartPopulate()
{
	m_bPopulateInit = true;
	DeleteAllItems();
	for(UINT i=0;i < m_nThreadCount;i++)
		m_MonitorEvent[i].SetEvent();
	if (m_sFileFilter.IsEmpty() || m_sFileFilter == _T("*.*") || m_sFileFilter == _T("*"))
		return;
	LoadFilterFiles(m_sFileFilter);
}

void CIEShellListCtrl::EndPopulate()
{
	m_bPopulateInit = false;
	Sort();
	SetColumnWidths();
}

BOOL CIEShellListCtrl::Populate(LPTVITEMDATA lptvid)
{
	IShellFolder *pFolder=NULL;
	BOOL bRet=FALSE;
	HRESULT hr=E_FAIL;
	if (lptvid->lpsfParent)
	{
		hr=lptvid->lpsfParent->BindToObject(lptvid->lpi,0,IID_IShellFolder,(LPVOID*)&pFolder);
	}
	else
	{
		LPSHELLFOLDER psfDesktop;
		LPITEMIDLIST pidlDesktop=NULL;
		hr=SHGetDesktopFolder(&psfDesktop);
		SHGetSpecialFolderLocation(NULL,CSIDL_DESKTOP,&pidlDesktop);
		if (GetShellPidl().ComparePidls(NULL,lptvid->lpifq,pidlDesktop))
		{
			pFolder = psfDesktop;
		}
		else
		{
			hr=psfDesktop->BindToObject(lptvid->lpifq,0,IID_IShellFolder,(LPVOID*)&pFolder);
			psfDesktop->Release();
		}
		if (pidlDesktop)
			GetShellPidl().FreePidl(pidlDesktop);
	}
	if (SUCCEEDED(hr))
	{
		bRet = Populate(lptvid,pFolder,true);
		pFolder->Release();
	}
	return bRet;
}

BOOL CIEShellListCtrl::Populate(LPCTSTR pszPath, bool bCallBack)
{
	LPITEMIDLIST pidlfq=NULL;
	LPITEMIDLIST pidl=NULL;
	LPSHELLFOLDER pDesktop = NULL;
    SHGetDesktopFolder(&pDesktop);
	if (FAILED(GetShellPidl().SHPathToPidlEx(pszPath,&pidlfq,pDesktop)))
		return FALSE;
	LPSHELLFOLDER pSubFolder = NULL;
	if (FAILED(pDesktop->BindToObject(pidl, 0, IID_IShellFolder,(LPVOID*)&pSubFolder)))
		return FALSE;
	pidl = GetShellPidl().CopyLastItemID(pidlfq);
	TVITEMDATA tvid;
	tvid.lpifq = pidlfq;
	tvid.lpi = pidl;
	tvid.lpsfParent = NULL;
	BOOL bRet = Populate(&tvid,pSubFolder,bCallBack);
	if (pDesktop)
		pDesktop->Release();
	if (pSubFolder)
		pSubFolder->Release();
	if (pidl)
		m_pMalloc->Free(pidl);
	if (pidlfq)
		m_pMalloc->Free(pidlfq);
		
	return bRet;
}

BOOL CIEShellListCtrl::Populate(LPTVITEMDATA lptvid,LPSHELLFOLDER psfFolder,bool bCallBack)
{
	m_bCallBack = bCallBack;
	FreeTVID();
	m_tvid.lpi = GetShellPidl().CopyItemIDList(lptvid->lpi);
	m_tvid.lpifq = GetShellPidl().CopyItemIDList(lptvid->lpifq);
#ifdef _DEBUG
	CString sPath;
	GetShellPidl().SHPidlToPathEx(m_tvid.lpifq,sPath,NULL);
	TRACE1("Populating path %s in CIEShellListCtrl\n",sPath);
#endif	
	if (lptvid->lpsfParent)
	{
		m_tvid.lpsfParent = lptvid->lpsfParent;
		m_tvid.lpsfParent->AddRef();
	}
	m_psfSubFolder = psfFolder;
	m_psfSubFolder->AddRef();
	Load();
    return TRUE;
}

CString CIEShellListCtrl::GetColumns()
{
	SHELLDETAILS sd;
	LPTSTR pszHeader=NULL;
	CString sColumns;
	for(int i=0;SUCCEEDED(m_ShellDetails.GetDetailsOf(NULL,i,&sd));i++)
	{
		GetShellPidl().StrRetToStr(sd.str,&pszHeader,NULL);
		if (pszHeader)
		{
			TRACE1("Column found %s\n",pszHeader);	
			if (!sColumns.IsEmpty())
				sColumns += _T("|");
			sColumns += pszHeader;
			GetShellPidl().Free(pszHeader);
			pszHeader= NULL;
		}
	}
	return sColumns;
}

void CIEShellListCtrl::InitColumns()
{
	CString sColumns = GetColumns();
	if (sColumns.IsEmpty())
		sColumns = m_sColumns;
	InitListCtrl(sColumns);
}

void CIEShellListCtrl::SetColumnWidths()
{
	if (!m_bCallBack)
	{
		for(int i=0;i < GetColumnCount();i++)
			SetColumnWidth(i,LVSCW_AUTOSIZE);
	}
}

void CIEShellListCtrl::Refresh()
{
	if (m_psfSubFolder==NULL)
		return;
	SetRefreshAllowed(false);
	SetRedraw(FALSE);
	int nCurSel = GetCurSel();
	TRACE(_T("Refreshing shell list control\n"));
	Load();
	SetCurSel(nCurSel);
	LONG Result;
	OnSelChanged(nCurSel,&Result);
	SetRedraw(TRUE);
	SetRefreshAllowed(true);
}

void CIEShellListCtrl::Load()
{
	CWaitCursor w;
    if (!InitItems(&m_tvid,m_bCallBack))
        return;
}

void CIEShellListCtrl::Init()
{
	if (m_bInitiliazed)
		return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -