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

📄 iefoldertreectrl.cpp

📁 vc座的资源管理器源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//*******************************************************************************
// 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>
//*******************************************************************************


#include "stdafx.h"
#include "IEFolderTreeCtrl.h"
#include "UIMessages.h"
#include <vector>
#include <map>

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

typedef map<CShellPidlCompare,HTREEITEM> mapPidlToHTREEITEM;
typedef vector<LPITEMIDLIST> vecPidl;

int CALLBACK CIEFolderTreeCtrl::CompareProc(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
{
	LPTVITEMDATA lptvid1 = (LPTVITEMDATA)((CUIListCtrlData*)lParam1)->GetExtData();
	LPTVITEMDATA lptvid2 = (LPTVITEMDATA)((CUIListCtrlData*)lParam2)->GetExtData();
	LPSHELLFOLDER psfParent = (LPSHELLFOLDER)lParamSort;

	HRESULT hr = psfParent->CompareIDs (0, lptvid1->lpi, lptvid2->lpi);
	if (FAILED (hr))
		return 0;
	return (short)hr;
} 

/////////////////////////////////////////////////////////////////////////////
// CIEFolderTreeCtrl

CIEFolderTreeCtrl::CIEFolderTreeCtrl()
{
	SHGetMalloc(&m_pMalloc);
	m_hImageList = NULL;
}

CIEFolderTreeCtrl::~CIEFolderTreeCtrl()
{
	// Free our memory allocator
	if (m_pMalloc)
		m_pMalloc->Release();
}

void CIEFolderTreeCtrl::Refresh()
{
	HTREEITEM hItem = GetRootItem();
    if (hItem == NULL)
        return;
	CWaitCursor w;
	SetRedraw(FALSE);
    RefreshNode(hItem);
	SetRedraw(TRUE);
}

void CIEFolderTreeCtrl::OnDeleteItemData(DWORD dwData)
{
	LPTVITEMDATA pItemData=(LPTVITEMDATA)dwData;
	if (pItemData == NULL)
		return;
	if (pItemData->lpsfParent)
		pItemData->lpsfParent->Release();
	if (pItemData->lpi)
		m_pMalloc->Free(pItemData->lpi);  
	if (pItemData->lpifq)
		m_pMalloc->Free(pItemData->lpifq);  
	m_pMalloc->Free(pItemData);
}

BOOL CIEFolderTreeCtrl::LoadURL(HTREEITEM hItem)
{
	if (GetRootItem() == hItem)
		return FALSE;
	if (ItemHasChildren(hItem))
		return FALSE;
	CString strText(GetItemText(hItem));
	AfxMessageBox(strText);
	return TRUE;
}

bool CIEFolderTreeCtrl::LoadItems(LPCTSTR pszPath,DWORD dwFolderType)
{
	ASSERT(m_pMalloc);
	if (m_hImageList == NULL)
		Init();
	bool bRet = false;

	CWaitCursor w;
	DeleteAllItems();
	//DeleteItemData();

	LPITEMIDLIST pidl=NULL;
	LPSHELLFOLDER psfDesktop=NULL;
	LPSHELLFOLDER pSubFolder=NULL;
	HRESULT hr = SHGetDesktopFolder(&psfDesktop);

	if (dwFolderType)
	{
		hr = SHGetSpecialFolderLocation(NULL, dwFolderType, &pidl);
#ifdef _DEBUG
		CString sPath;
		GetShellPidl().SHPidlToPathEx(pidl,sPath);
		TRACE1("Populating special folder %s\n",sPath);
#endif
		hr = psfDesktop->BindToObject(pidl, 0, IID_IShellFolder,(LPVOID*)&pSubFolder);
	}
	else
	{
		if (pszPath && *pszPath != '\0')
		{
			hr = m_ShellPidl.SHPathToPidlEx(pszPath,&pidl,psfDesktop);
			if (SUCCEEDED(hr))
			{
				hr = psfDesktop->BindToObject(pidl, 0, IID_IShellFolder,(LPVOID*)&pSubFolder);
				if (SUCCEEDED(hr))
					m_sRootPath = pszPath;
			}
		}
		else
		{
			hr = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, &pidl);
		}
	}
	LPCTSTR pszTitle=NULL;
	SHFILEINFO fileInfo;
	ZeroMemory(&fileInfo,sizeof(fileInfo));
	int nImage=0, nSelImage=0;
	if (pidl)
	{
		SHGetFileInfo((LPCTSTR)pidl, NULL, &fileInfo, sizeof(fileInfo), SHGFI_PIDL|SHGFI_ATTRIBUTES|SHGFI_DISPLAYNAME);
		pszTitle = fileInfo.szDisplayName;
		m_ShellPidl.GetNormalAndSelectedIcons(pidl, nImage, nSelImage);
		if (nImage < 0)
			nImage = 0;
		if (nSelImage < 0)
			nSelImage = 0;
	}
	if (SUCCEEDED(hr))
	{
		LPTVITEMDATA lptvid = (LPTVITEMDATA)m_pMalloc->Alloc(sizeof(TVITEMDATA));
		if (lptvid == NULL)
			return bRet;
		ZeroMemory(lptvid,sizeof(TVITEMDATA));
		// Now make a copy of the ITEMIDLIST.
		lptvid->lpi = m_ShellPidl.CopyLastItemID(pidl);
		lptvid->lpifq = m_ShellPidl.CopyItemIDList(pidl);
		lptvid->lpsfParent = NULL;
		if (lptvid->lpsfParent)
			lptvid->lpsfParent->AddRef();

		HTREEITEM hRootItem = AddAnItem((HTREEITEM)NULL,pszTitle,(LPARAM)lptvid,(HTREEITEM)TVI_ROOT,nImage,nSelImage);
		AddItems(hRootItem,pSubFolder ? pSubFolder : psfDesktop);
		Expand(hRootItem,TVE_EXPAND);
		PostMessage(WM_APP_POPULATE_TREE);
		bRet = true;
	}
	if (pidl)
		m_pMalloc->Free(pidl);
	if (pSubFolder)
		pSubFolder->Release();
	if (psfDesktop)
		psfDesktop->Release();
	return bRet;
}

bool CIEFolderTreeCtrl::AddItems(HTREEITEM hItem,IShellFolder* pFolder)
{
	IEnumIDList* pItems = NULL;
	LPITEMIDLIST pidlNext = NULL;
	DWORD dwFlags = SHCONTF_FOLDERS;
	if (GetShellSettings().ShowAllObjects() && !GetShellSettings().ShowSysFiles())
		dwFlags |= SHCONTF_INCLUDEHIDDEN;
	// Enumerate all object in the given folder
	HRESULT hr = pFolder->EnumObjects(NULL, dwFlags, &pItems);
	if (hr != NOERROR)
		return false;
	while (NOERROR == hr)
	{
		hr = pItems->Next(1, &pidlNext, NULL);
		if (hr == S_FALSE || pidlNext == NULL)
			break;
		if (AddFolder(hItem,pidlNext,pFolder) == NULL)
			m_pMalloc->Free(pidlNext);
		pidlNext = NULL;
	}
	if (pidlNext)
		m_pMalloc->Free(pidlNext);
	if (pItems)
		pItems->Release();
	Sort(hItem,pFolder);
	return true;
}

void CIEFolderTreeCtrl::Sort(HTREEITEM hParent,LPSHELLFOLDER pFolder)
{
	// Sort the the node based on pidls
	TVSORTCB cbSort;
	cbSort.hParent = hParent;
	cbSort.lpfnCompare = CompareProc;
	cbSort.lParam = (LPARAM)pFolder;
	SortChildrenCB(&cbSort);
}

HTREEITEM CIEFolderTreeCtrl::AddFolder(HTREEITEM hItem,LPCTSTR pszPath)
{
	LPITEMIDLIST pidlfq=NULL;
	HRESULT hr = GetShellPidl().SHPathToPidlEx(pszPath,&pidlfq,NULL);
	if (FAILED(hr))
		return NULL;
	LPTVITEMDATA lptvid = (LPTVITEMDATA)GetItemData(hItem);
	ASSERT(lptvid);
	LPITEMIDLIST pidl = GetShellPidl().CopyLastItemID(pidlfq);
	HTREEITEM hFolderItem = AddFolder(hItem,pidl,lptvid->lpsfParent);
	if (pidlfq)
		m_pMalloc->Free(pidlfq);
	return hFolderItem;
}

HTREEITEM CIEFolderTreeCtrl::AddFolder(HTREEITEM hItem,LPITEMIDLIST pidl,LPSHELLFOLDER pFolder)
{
	ASSERT(m_pMalloc);
	LPTSTR pszFilePath = NULL;
	STRRET StrRetFilePath;
	SHFILEINFO FileInfo;

	ZeroMemory(&FileInfo,sizeof(FileInfo));
	FileInfo.dwAttributes=SFGAO_HASSUBFOLDER | SFGAO_FOLDER;
	HRESULT hr = pFolder->GetAttributesOf(1,(LPCITEMIDLIST*)&pidl,&FileInfo.dwAttributes);
	if (FAILED(hr))
		return NULL;
// Create a submenu if this item is a folder
	if (!(FileInfo.dwAttributes & (SFGAO_HASSUBFOLDER | SFGAO_FOLDER)))
		return NULL;
	pFolder->GetDisplayNameOf(pidl,SHGDN_INFOLDER,&StrRetFilePath);
	GetShellPidl().StrRetToStr(StrRetFilePath, &pszFilePath, pidl);
	if (pszFilePath)
	{
		lstrcpy(FileInfo.szDisplayName,pszFilePath);
		m_pMalloc->Free(pszFilePath);
		pszFilePath = NULL;
	}
	// allocate new itemdata
	LPTVITEMDATA lptvid = (LPTVITEMDATA)m_pMalloc->Alloc(sizeof(TVITEMDATA));
	if (lptvid == NULL)
		return NULL;
	ZeroMemory(lptvid,sizeof(TVITEMDATA));
	// get itemdata for current node
	LPTVITEMDATA lpptvid = (LPTVITEMDATA)GetItemData(hItem);
	ASSERT(lpptvid);
	// create new fully qualified pidl
	lptvid->lpifq = m_ShellPidl.ConcatPidl(lpptvid->lpifq,pidl);
	// save relative pidl (will be freed in the clean up)
	lptvid->lpi = pidl;
	int nImage=0;

⌨️ 快捷键说明

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