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

📄 ieshelltreectrl.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>
//*******************************************************************************

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

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

/////////////////////////////////////////////////////////////////////////////
// CIEShellTreeCtrl

CIEShellTreeCtrl::CIEShellTreeCtrl()
{
	m_lptvid = NULL;
	m_hListWnd = NULL;
	m_hComboWnd = NULL;
	m_nThreadCount = 0;
	m_bRefreshAllowed = true;
	m_bNotifyParent = false;
	// Turn off WM_DROPFILES
	SetDropFiles(false);
}

CIEShellTreeCtrl::~CIEShellTreeCtrl()
{
}

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

void CIEShellTreeCtrl::RefreshComboBox(LPTVITEMDATA lptvid)
{
	if (m_hComboWnd)
	{
		::PostMessage(m_hComboWnd,WM_APP_CB_IE_POPULATE,(WPARAM)lptvid->lpifq,0);
	}
}

void CIEShellTreeCtrl::SetNotificationObject(bool bNotify)
{
	if (bNotify)
		CreateFileChangeThreads(GetSafeHwnd());
	else
		DestroyThreads();
}

void CIEShellTreeCtrl::UpOneLevel(HTREEITEM hItem)
{
	if (hItem == NULL)
	{
		hItem = GetSelectedItem();
	}
	if (hItem == NULL)
		return;
	HTREEITEM hParentItem = GetParentItem(hItem);
	if (hParentItem)
		Select(hParentItem,TVGN_CARET);
}

void CIEShellTreeCtrl::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 CIEShellTreeCtrl::CreateFileChangeThreads(HWND hwnd)
{
	if (m_nThreadCount)
		return;
	TCHAR szDrives[MAX_PATH];
	DWORD dwSize = sizeof(szDrives)/sizeof(TCHAR);
	DWORD dwChars = GetLogicalDriveStrings(dwSize,szDrives);
	if (dwChars == 0 || dwChars > dwSize) 
	{
		TRACE(_T("Warning: CreateFileChangeThreads failed in GetLogicalDriveStrings\n"));
		return;
	}
	UINT nType;
	CString sDrive;
	LPCTSTR pszDrives=szDrives;
	while (*pszDrives != '\0')
	{
		sDrive = pszDrives;
		nType = ::GetDriveType(sDrive);
		if (nType == DRIVE_FIXED || nType == DRIVE_REMOTE || nType == DRIVE_RAMDISK)
		{
			CreateFileChangeThread(sDrive,hwnd);
		}
		pszDrives = _tcsninc(pszDrives,sDrive.GetLength()+1);
	}
}

void CIEShellTreeCtrl::CreateFileChangeThread(const CString& sPath,HWND hwnd)
{
	if (m_nThreadCount >= MAX_THREADS)
		return;
    PDC_THREADINFO pThreadInfo = new DC_THREADINFO; // Thread will delete
    pThreadInfo->sPath = sPath;
    pThreadInfo->hEvent = m_event[m_nThreadCount].m_hObject;
    pThreadInfo->pTreeCtrl = this;

    CWinThread* pThread = AfxBeginThread (ThreadFunc, pThreadInfo,
        THREAD_PRIORITY_IDLE);

    pThread->m_bAutoDelete = FALSE;
    m_hThreads[m_nThreadCount] = pThread->m_hThread;
    m_pThreads[m_nThreadCount++] = pThread;
}

HTREEITEM CIEShellTreeCtrl::SearchSiblings(HTREEITEM hItem,LPITEMIDLIST pidlAbs)
{
	LPTVITEMDATA pItem = NULL;
	HTREEITEM hChildItem = GetChildItem(hItem);
	HTREEITEM hFoundItem;
	while (hChildItem) 
	{
			pItem = (LPTVITEMDATA)GetItemData(hChildItem);
			if (GetShellPidl().ComparePidls(NULL,pItem->lpifq,pidlAbs))
			   break;
			hFoundItem = SearchSiblings(hChildItem,pidlAbs);
			if (hFoundItem)
				return hFoundItem;
			hChildItem = GetNextSiblingItem(hChildItem);
	}
	return hChildItem;
}

HTREEITEM CIEShellTreeCtrl::ExpandMyComputer(LPITEMIDLIST pidlAbs)
{
	HTREEITEM hItem=NULL;
	if (pidlAbs == NULL)
		return hItem;
	LPITEMIDLIST pidlMyComputer=NULL;
	LPITEMIDLIST pidlFirst=GetShellPidl().CopyItemID(pidlAbs);
    SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlMyComputer); 
	if (GetShellPidl().ComparePidls(NULL,pidlMyComputer,pidlFirst))
	{
		hItem = ExpandPidl(pidlMyComputer);
	}
	if (pidlMyComputer)
		GetShellPidl().FreePidl(pidlMyComputer);
	if (pidlFirst)
		GetShellPidl().FreePidl(pidlFirst);
	return hItem;
}

HTREEITEM CIEShellTreeCtrl::ExpandPidl(LPITEMIDLIST pidlAbs)
{
	HTREEITEM hItem = SearchSiblings(GetRootItem(),pidlAbs);
	if (hItem)
	{
		Expand(hItem,TVE_EXPAND);
	}
	return hItem;
}

HTREEITEM CIEShellTreeCtrl::FindPidl(LPITEMIDLIST pidlAbs,BOOL bSelect)
{
	HTREEITEM hItem = NULL;
	if (pidlAbs == NULL)
		hItem = GetRootItem();
	else
		hItem = SearchSiblings(GetRootItem(),pidlAbs);
	if (bSelect && hItem != GetSelectedItem())
	{
		SelectItem(hItem);
		SelectionChanged(hItem,GetItemData(hItem));
	}
	return hItem;
}

HTREEITEM CIEShellTreeCtrl::FindItem (HTREEITEM hItem, const CString& strTarget)
{
    while (hItem != NULL) 
	{
        if (GetItemText (hItem) == strTarget)
            break;
        hItem = GetNextSiblingItem (hItem);
    }
    return hItem;
}

UINT CIEShellTreeCtrl::DeleteChildren (HTREEITEM hItem)
{
    UINT nCount = 0;
    HTREEITEM hChild = GetChildItem (hItem);

    while (hChild != NULL)
	{
        HTREEITEM hNextItem = GetNextSiblingItem (hChild);
        DeleteItem (hChild);
        hChild = hNextItem;
        nCount++;
    }
    return nCount;
}

void CIEShellTreeCtrl::Init()
{
	ModifyStyle(0,TVS_EDITLABELS);
	CIEFolderTreeCtrl::Init();
}

void CIEShellTreeCtrl::Refresh()
{
	SetRefreshAllowed(false);
	CIEFolderTreeCtrl::Refresh();
	SetRefreshAllowed(true);
}

bool CIEShellTreeCtrl::DragEnter(CDD_OleDropTargetInfo *pInfo)
{
	HTREEITEM hItem = pInfo->GetTreeItem(); 
	if (hItem == NULL)
		return false;
	LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
	ASSERT(ptvid);
	if (ptvid == NULL)
		return false;
	return m_ShellDragDrop.DragEnter(pInfo,ptvid->lpsfParent,ptvid->lpi);
}

bool CIEShellTreeCtrl::DragLeave(CDD_OleDropTargetInfo *pInfo)
{
	return m_ShellDragDrop.DragLeave(pInfo);
}

bool CIEShellTreeCtrl::DragOver(CDD_OleDropTargetInfo *pInfo)
{
	pInfo->SetDropEffect(DROPEFFECT_NONE);

	HTREEITEM hItem = pInfo->GetTreeItem(); 
	if (hItem == NULL)
		return false;
	LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
	ASSERT(ptvid);
	if (ptvid == NULL)
		return false;
	return m_ShellDragDrop.DragOver(pInfo,ptvid->lpsfParent,ptvid->lpi);
}

bool CIEShellTreeCtrl::DragDrop(CDD_OleDropTargetInfo *pInfo)
{
	HTREEITEM hItem = pInfo->GetTreeItem(); 
	if (hItem == NULL)
		return false;
	LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(hItem);
	ASSERT(ptvid);
	if (ptvid == NULL)
		return false;
	return m_ShellDragDrop.DragDrop(pInfo,ptvid->lpsfParent,ptvid->lpi);
}

DROPEFFECT CIEShellTreeCtrl::DoDragDrop(NM_TREEVIEW* pNMTreeView,COleDataSource *pOleDataSource)
{
	if (pNMTreeView->itemNew.hItem == GetRootItem())
		return DROPEFFECT_NONE;
	CCF_ShellIDList sl;
	CShellPidl pidl;
	HTREEITEM hParentItem = GetParentItem(pNMTreeView->itemNew.hItem);
	LPTVITEMDATA ptvid = (LPTVITEMDATA)GetItemData(pNMTreeView->itemNew.hItem);
	LPTVITEMDATA ptvid_parent = (LPTVITEMDATA)GetItemData(hParentItem);
	ASSERT(ptvid);
	ASSERT(ptvid_parent);
	if (GetShellPidl().IsDesktopFolder(ptvid->lpsfParent))
		sl.AddPidl(GetShellPidl().GetEmptyPidl());
	else
		sl.AddPidl(ptvid_parent->lpifq);
	sl.AddPidl(ptvid->lpi);
	CCF_HDROP cf_hdrop;
	CCF_String cf_text;
	CString sPath;
	pidl.SHPidlToPathEx(ptvid->lpifq,sPath);
	cf_hdrop.AddDropPoint(CPoint(pNMTreeView->ptDrag),FALSE);
	cf_hdrop.AddFileName(sPath);
	sPath += _T("\r\n");
	cf_text.SetString(sPath);
	CWDClipboardData::Instance()->SetData(pOleDataSource,&cf_text,CWDClipboardData::e_cfString);
	CWDClipboardData::Instance()->SetData(pOleDataSource,&cf_hdrop,CWDClipboardData::e_cfHDROP);
	CWDClipboardData::Instance()->SetData(pOleDataSource,&sl,CWDClipboardData::e_cfShellIDList);
	return GetShellPidl().GetDragDropAttributes(ptvid);
}

bool CIEShellTreeCtrl::EndLabelEdit(HTREEITEM hItem,LPCTSTR pszText)
{
	LPTVITEMDATA plvit = (LPTVITEMDATA)GetItemData(hItem);
	CString sFromPath;
	CString sToPath;
	GetShellPidl().SHPidlToPathEx(plvit->lpifq,sFromPath);
	sToPath = sFromPath;
	sToPath.Replace(GetItemText(hItem),pszText);
	SHFILEOPSTRUCT shf;
	TCHAR szFrom[MAX_PATH+1];
	TCHAR szTo[MAX_PATH+1];
	ZeroMemory(szFrom,sizeof(szFrom));
	lstrcpy(szFrom,sFromPath);
	ZeroMemory(szTo,sizeof(szTo));
	lstrcpy(szTo,sToPath);
	ZeroMemory(&shf,sizeof(shf));
	shf.hwnd = GetSafeHwnd();
	shf.wFunc = FO_RENAME;
	shf.pFrom = szFrom;
	shf.pTo = szTo;
#ifdef _DEBUG
	CString sMess;

⌨️ 快捷键说明

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