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

📄 foldertreectrl.cpp

📁 该软件为EDA行业所用
💻 CPP
字号:
// FolderTreeCtrl.cpp : implementation file
//

#include "stdafx.h"
//#include "MultiFolder.h"
//#include "SearchTree.h"
#include "FolderTreeCtrl.h"

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

/////////////////////////////////////////////////////////////////////////////
// CFolderTreeCtrl

CFolderTreeCtrl::CFolderTreeCtrl()
{
	m_uFlags = 0;
}

CFolderTreeCtrl::~CFolderTreeCtrl()
{
}

BEGIN_MESSAGE_MAP(CFolderTreeCtrl, CTreeCtrl)
	//{{AFX_MSG_MAP(CFolderTreeCtrl)
	ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
	ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
	ON_WM_LBUTTONDOWN()
	ON_WM_KEYDOWN()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CFolderTreeCtrl message handlers
BOOL CFolderTreeCtrl::DisplayTree(LPCTSTR strRoot, BOOL bFiles)
{
	DeleteAllItems();

    m_bFiles = bFiles;  // if TRUE, Display Path- and Filenames 
	if ( strRoot == NULL || strRoot[0] == '\0' )
	{
		if ( !DisplayDrives() )
			return FALSE;
		m_strRoot = "";
	}
    else
	{
		m_strRoot = strRoot;
		if ( m_strRoot.Right(1) != '\\' )
			m_strRoot += "\\";
		HTREEITEM hParent = AddItem( TVI_ROOT, m_strRoot );
		DisplayPath( hParent, strRoot );
	}
	return TRUE;	
}

BOOL CFolderTreeCtrl::DisplayDrives()
{
	DeleteAllItems();
	char  szDrives[128];
	char* pDrive;
	if ( !GetLogicalDriveStrings( sizeof(szDrives), szDrives ) )
	{
		m_strError = "Error Getting Logical DriveStrings!";
		return FALSE;
	}

	pDrive = szDrives;
	DWORD dwType;	
	while( *pDrive )
	{
		dwType = ::GetDriveType(pDrive);
		if(dwType == DRIVE_FIXED)
		{
			HTREEITEM hParent = AddItem( TVI_ROOT, pDrive );
			if ( FindSubDir( pDrive ) )
				InsertItem( "", 0, 0, hParent );
		}
		pDrive += strlen( pDrive ) + 1;
	}

	return TRUE;
}

HTREEITEM CFolderTreeCtrl::AddItem(HTREEITEM hParent, LPCTSTR strPath)
{
    CString    strTemp = strPath;

	if ( strTemp.Right(1) == "\\" )
		strTemp.SetAt( strTemp.GetLength() - 1, '\0' );
	
	if ( hParent == TVI_ROOT )
	{
		return InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT|TVIF_STATE,
			(LPCTSTR)strTemp,0,1,INDEXTOSTATEIMAGEMASK(1),
			TVIS_STATEIMAGEMASK,0,hParent,TVI_LAST);
	}
	
	return InsertItem(TVIF_IMAGE|TVIF_SELECTEDIMAGE|TVIF_TEXT|TVIF_STATE,
		GetSubPath(strTemp),0,1,INDEXTOSTATEIMAGEMASK(1),
		TVIS_STATEIMAGEMASK,0,hParent,TVI_LAST);
}

void CFolderTreeCtrl::DisplayPath(HTREEITEM hParent, LPCTSTR strPath)
{
	CFileFind find;
	CString	strPathFiles = strPath;
	CString strPathName;
	BOOL      bFind;
	int		nIndex = 0;
	
	if ( strPathFiles.Right(1) != "\\" )
		strPathFiles += "\\";
	strPathFiles += "*.*";

	bFind = find.FindFile( strPathFiles );

	CWaitCursor wc;
	SetRedraw( FALSE );
	while ( bFind )
	{
		bFind = find.FindNextFile();
		if ( find.IsDirectory() && !find.IsDots() )
		{		
			HTREEITEM hItem = AddItem( hParent,find.GetFilePath());
			if (FindSubDir(find.GetFilePath()))
				InsertItem( "", 0, 0, hItem );
		}
	}

	//nState: 0->无选择钮 1->没有选择 2->部分选择 3->全部选择
	UINT nState = GetItemState( hParent, TVIS_STATEIMAGEMASK ) >> 12;
	if(nState == 3)
		SetItemState( hParent, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );

	SetRedraw( TRUE );	
}

BOOL CFolderTreeCtrl::FindSubDir( LPCTSTR strPath)
{
	CFileFind find;
	CString   strTemp = strPath;
	BOOL      bFind;

	if ( strTemp[strTemp.GetLength()-1] == '\\' )
		strTemp += "*.*";
	else
		strTemp += "\\*.*";
		
	bFind = find.FindFile( strTemp );
	
	while ( bFind )
	{
		bFind = find.FindNextFile();

		if ( find.IsDirectory() && !find.IsDots() )
		{
			return TRUE;
		}
		if ( !find.IsDirectory() && m_bFiles && !find.IsHidden() )
			return TRUE;		
	}
	return FALSE;
}

void CFolderTreeCtrl::ExpandItem(HTREEITEM hItem, UINT nCode)
{	
	CString strPath;
	
	if ( nCode == TVE_EXPAND )
	{
		HTREEITEM hChild = GetChildItem( hItem );
		while ( hChild )
		{
			DeleteItem( hChild );
			hChild = GetChildItem( hItem );
		}        
		strPath = GetFullPath( hItem );
		DisplayPath( hItem, strPath );
	}
}

CString CFolderTreeCtrl::GetFullPath(HTREEITEM hItem)
{
	// get the Full Path of the item
	CString strReturn;
	CString strTemp;
	HTREEITEM hParent = hItem;

	strReturn = "";

	while ( hParent )
	{		
		strTemp  = GetItemText( hParent );
		strTemp += "\\";
		strReturn = strTemp + strReturn;
		hParent = GetParentItem( hParent );
	}
    
	strReturn.TrimRight( '\\' );

    return strReturn;
}

LPCTSTR CFolderTreeCtrl::GetSubPath(LPCTSTR strPath)
{
	//
	// getting the last SubPath from a PathString
	// e.g. C:\temp\readme.txt
	// the result = readme.txt
	static CString strTemp;
	int     iPos;

	strTemp = strPath;
	if ( strTemp.Right(1) == '\\' )
		 strTemp.SetAt( strTemp.GetLength() - 1, '\0' );
	iPos = strTemp.ReverseFind( '\\' );
	if ( iPos != -1 )
	    strTemp = strTemp.Mid( iPos + 1);

	return (LPCTSTR)strTemp;
}

BOOL CFolderTreeCtrl::SetItemState(HTREEITEM hItem, UINT nState, UINT nStateMask, BOOL bSearch)
{
	BOOL bReturn = CTreeCtrl::SetItemState( hItem, nState, nStateMask );

	UINT iState = nState >> 12;
	if(iState!=0)
	{
		if(bSearch)
			TravelChild(hItem, iState);
		TravelSiblingAndParent(hItem,iState);
	}
	return bReturn;
}

void CFolderTreeCtrl::TravelChild(HTREEITEM hItem, int nState)
{
	HTREEITEM hChildItem,hBrotherItem;
	
	//查找子节点,没有就结束
	hChildItem=GetChildItem(hItem);
	if(hChildItem!=NULL)
	{
		//设置子节点的状态与当前节点的状态一致
		CTreeCtrl::SetItemState( hChildItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
		//再递归处理子节点的子节点和兄弟节点
		TravelChild(hChildItem, nState);
		
		//处理子节点的兄弟节点和其子节点
		hBrotherItem=GetNextSiblingItem(hChildItem);
		while (hBrotherItem)
		{
			//设置子节点的兄弟节点状态与当前节点的状态一致
			int nState1 = GetItemState( hBrotherItem, TVIS_STATEIMAGEMASK ) >> 12;
			if(nState1!=0)
			{
				CTreeCtrl::SetItemState( hBrotherItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
			}
			//再递归处理子节点的兄弟节点的子节点和兄弟节点
			TravelChild(hBrotherItem, nState);
			hBrotherItem=GetNextSiblingItem(hBrotherItem);
		}
	}
}

void CFolderTreeCtrl::TravelSiblingAndParent(HTREEITEM hItem, int nState)
{
	HTREEITEM hNextSiblingItem,hPrevSiblingItem,hParentItem;
	
	//查找父节点,没有就结束
	hParentItem=GetParentItem(hItem);
	if(hParentItem!=NULL)
	{
		int nState1=nState;//设初始值,防止没有兄弟节点时出错
		
		//查找当前节点下面的兄弟节点的状态
		hNextSiblingItem=GetNextSiblingItem(hItem);
		while(hNextSiblingItem!=NULL)
		{
			nState1 = GetItemState( hNextSiblingItem, TVIS_STATEIMAGEMASK ) >> 12;
			if(nState1!=nState && nState1!=0) break;
			else hNextSiblingItem=GetNextSiblingItem(hNextSiblingItem);
		}
		
		if(nState1==nState)
		{
			//查找当前节点上面的兄弟节点的状态
			hPrevSiblingItem=GetPrevSiblingItem(hItem);
			while(hPrevSiblingItem!=NULL)
			{
				nState1 = GetItemState( hPrevSiblingItem, TVIS_STATEIMAGEMASK ) >> 12;
				if(nState1!=nState && nState1!=0) break;
				else hPrevSiblingItem=GetPrevSiblingItem(hPrevSiblingItem);
			}
		}
		
		if(nState1==nState || nState1==0)
		{
			nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
			if(nState1!=0)
			{
				//如果状态一致,则父节点的状态与当前节点的状态一致
				CTreeCtrl::SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
			}
			//再递归处理父节点的兄弟节点和其父节点
			TravelSiblingAndParent(hParentItem,nState);
		}
		else
		{
			//状态不一致,则当前节点的父节点、父节点的父节点……状态均为第三态
			hParentItem=GetParentItem(hItem);
			while(hParentItem!=NULL)
			{
				nState1 = GetItemState( hParentItem, TVIS_STATEIMAGEMASK ) >> 12;
				if(nState1!=0)
				{
					CTreeCtrl::SetItemState( hParentItem, INDEXTOSTATEIMAGEMASK(2), TVIS_STATEIMAGEMASK );
				}
				hParentItem=GetParentItem(hParentItem);
			}
		}
	}	
}

void CFolderTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	CString strPath;
	 
	if ( pNMTreeView->itemNew.state & TVIS_EXPANDED )
	{
		ExpandItem( pNMTreeView->itemNew.hItem, TVE_EXPAND );
	}
	else
	{
		HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem );
				
		while ( hChild ) 
		{
			DeleteItem( hChild );
			hChild = GetChildItem( pNMTreeView->itemNew.hItem );
		}
		InsertItem( "", pNMTreeView->itemNew.hItem );
	}
	*pResult = 0;
}

void CFolderTreeCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult) 
{
	if(m_uFlags & TVHT_ONITEMSTATEICON)
		*pResult=1;
	else 
		*pResult = 0;
}

void CFolderTreeCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	HTREEITEM hItem = HitTest(point, &m_uFlags);
	if ( (m_uFlags&TVHT_ONITEMSTATEICON ))
	{
		//nState: 0->无选择钮 1->没有选择 2->部分选择 3->全部选择
		UINT nState = GetItemState( hItem, TVIS_STATEIMAGEMASK ) >> 12;
		nState=(nState==3)?1:3;
		SetItemState( hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
	}
	
	CTreeCtrl::OnLButtonDown(nFlags, point);
}

void CFolderTreeCtrl::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
 	//处理空格键
 	if(nChar==0x20)
 	{
 		HTREEITEM hItem = GetSelectedItem();
 		UINT nState = GetItemState( hItem, TVIS_STATEIMAGEMASK ) >> 12;
 		if(nState!=0)
 		{
 			nState=(nState==3)?1:3;
			SetItemState( hItem, INDEXTOSTATEIMAGEMASK(nState), TVIS_STATEIMAGEMASK );
 		}
 	}
	else	
		CTreeCtrl::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CFolderTreeCtrl::CalcuSelectPath()
{
	UINT nState;
	HTREEITEM hParent;
	CString strPath;

	hParent = GetRootItem();
	m_strlist.RemoveAll();
	while( hParent != NULL )
	{
		nState = GetItemState( hParent, TVIS_STATEIMAGEMASK ) >> 12;
		switch(nState)
		{
		case 2:
			strPath = GetItemText(hParent);
			CalcuSelectSubPath(hParent,strPath);
			break;
		case 3:
			strPath = GetItemText(hParent);
			strPath += "\\";
			m_strlist.AddTail(strPath);
			break;
		}
		hParent = GetNextSiblingItem(hParent);
	};
	
}

void CFolderTreeCtrl::CalcuSelectSubPath(HTREEITEM hParent,CString strPath)
{
	UINT nState;
	HTREEITEM hItem = GetChildItem(hParent);
	CString strPathName;
	CString strDirectory(strPath);
	CString strTemp;
	while( hItem != NULL )
	{
		nState = GetItemState( hItem, TVIS_STATEIMAGEMASK ) >> 12;
		switch(nState)
		{
		case 2:
			strPathName = GetItemText(hItem);
			strTemp = strDirectory;
			strTemp += "\\" + strPathName;
			CalcuSelectSubPath(hItem,strTemp);
			break;
		case 3:
			strPathName = GetItemText(hItem);
			strTemp = strDirectory;
			strTemp += "\\" + strPathName;
			m_strlist.AddTail(strTemp);
			break;
		}
		hItem = GetNextSiblingItem(hItem);
	};
}

CStringList* CFolderTreeCtrl::GetSelectPath()
{
	CalcuSelectPath();
	if(m_strlist.IsEmpty())
		return NULL;
	return &m_strlist;
}

⌨️ 快捷键说明

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