📄 dirtreectrl.cpp
字号:
// DirTreeCtrl.cpp:
//
// wrapped CTreeCtrl to select and or display folders and files (optional )
//
#include "stdafx.h"
#include "DirTreeCtrl.h"
#include "SortStringArray.h"
#include "FileGuardApp.h"
#include "MainFrm.h"
#include "FileGuardDoc.h"
#include "FileGuardView.h"
#include "FileGuard.h"
#include "FGDevice.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDirTreeCtrl
CDirTreeCtrl::CDirTreeCtrl()
{
m_strRoot = ""; // Auf Leer setzen
}
CDirTreeCtrl::~CDirTreeCtrl()
{
m_imgList.Detach();
}
BEGIN_MESSAGE_MAP(CDirTreeCtrl, CTreeCtrl)
//{{AFX_MSG_MAP(CDirTreeCtrl)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
// ON_NOTIFY_REFLECT(NM_CLICK, OnClick)
// ON_NOTIFY_REFLECT(NM_RCLICK, OnRightClick) //debug This message cannot be handled now.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// Behandlungsroutinen f黵 Nachrichten CDirTreeCtrl
BOOL CDirTreeCtrl::DisplayTree(LPCTSTR strRoot, BOOL bFiles)
{
DWORD dwStyle = GetStyle(); // read the windowstyle
if ( dwStyle & TVS_EDITLABELS )
{
// Don't allow the user to edit ItemLabels
ModifyStyle( TVS_EDITLABELS , 0 );
}
// Display the DirTree with the Rootname e.g. C:\
// if Rootname == NULL then Display all Drives on this PC
// First, we need the system-ImageList
DeleteAllItems();
if ( !GetSysImgList() )
return FALSE;
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 CDirTreeCtrl::GetSysImgList()
{
SHFILEINFO shFinfo;
HIMAGELIST hImgList = NULL;
if ( GetImageList( TVSIL_NORMAL ) )
m_imgList.Detach();
hImgList = (HIMAGELIST)SHGetFileInfo( "C:\\",
0,
&shFinfo,
sizeof( shFinfo ),
SHGFI_SYSICONINDEX |
SHGFI_SMALLICON );
if ( !hImgList )
{
m_strError = "Cannot retrieve the Handle of SystemImageList!";
return FALSE;
}
m_imgList.m_hImageList = hImgList;
SetImageList( &m_imgList, TVSIL_NORMAL );
return TRUE; // OK
}
// Displaying the Availible Drives on this PC
// This are the First Items in the TreeCtrl
BOOL CDirTreeCtrl::DisplayDrives()
{
DeleteAllItems();
char szDrives[128];
char* pDrive;
if ( !GetLogicalDriveStrings( sizeof(szDrives), szDrives ) )
{
m_strError = "Error Getting Logical DriveStrings!";
return FALSE;
}
pDrive = szDrives;
while( *pDrive )
{
HTREEITEM hParent = AddItem( TVI_ROOT, pDrive );
if ( FindSubDir( pDrive ) )
InsertItem( "", 0, 0, hParent );
//the driver is under protection?
CString strDrive=pDrive;
FGFormatPath(strDrive);
if(protFileList.IsInList(strDrive))
SetCheck(hParent);
pDrive += strlen( pDrive ) + 1;
}
return TRUE;
}
// Displaying the Path in the TreeCtrl
void CDirTreeCtrl::DisplayPath(HTREEITEM hParent, LPCTSTR strPath)
{
CFileFind find;
CString strPathFiles = strPath;
BOOL bFind;
CSortStringArray strDirArray;
CSortStringArray strFileArray;
if ( strPathFiles.Right(1) != "\\" )
strPathFiles += "\\";
strPathFiles += "*.*";
bFind = find.FindFile( strPathFiles );
while ( bFind )
{
bFind = find.FindNextFile();
if ( find.IsDirectory() && !find.IsDots() )
{
strDirArray.Add( find.GetFilePath() );
}
if ( !find.IsDirectory() && m_bFiles )
strFileArray.Add( find.GetFilePath() );
}
strDirArray.Sort();
SetRedraw( FALSE );
CWaitCursor wait;
for ( int i = 0; i < strDirArray.GetSize(); i++ )
{
HTREEITEM hItem = AddItem( hParent, strDirArray.GetAt(i) );
if ( FindSubDir( strDirArray.GetAt(i) ) )
InsertItem( "", 0, 0, hItem );
CString dir=strDirArray.GetAt(i);
FGFormatPath(dir);
if(protFileList.IsInList((LPCTSTR)dir)) //IsInList or IsUnderProtection???
SetCheck(hItem);
//to do: show protection type.
}
if ( m_bFiles )
{
strFileArray.Sort();
for ( i = 0; i < strFileArray.GetSize(); i++ )
{
HTREEITEM hItem = AddItem( hParent, strFileArray.GetAt(i) );
CString file=strFileArray.GetAt(i);
FGFormatPath(file);
if(protFileList.IsInList(file))
SetCheck(hItem);
//to do: show protection type.
}
}
SetRedraw( TRUE );
}
HTREEITEM CDirTreeCtrl::AddItem(HTREEITEM hParent, LPCTSTR strPath)
{
// Adding the Item to the TreeCtrl with the current Icons
SHFILEINFO shFinfo;
int iIcon, iIconSel;
CString strTemp = strPath;
if ( strTemp.Right(1) != '\\' )
strTemp += "\\";
if ( !SHGetFileInfo( strTemp,
0,
&shFinfo,
sizeof( shFinfo ),
SHGFI_ICON |
SHGFI_SMALLICON ) )
{
m_strError = "Error Gettting SystemFileInfo!";
return NULL;
}
iIcon = shFinfo.iIcon;
// we only need the index from the system image list
DestroyIcon( shFinfo.hIcon );
if ( !SHGetFileInfo( strTemp,
0,
&shFinfo,
sizeof( shFinfo ),
SHGFI_ICON | SHGFI_OPENICON |
SHGFI_SMALLICON ) )
{
m_strError = "Error Gettting SystemFileInfo!";
return NULL;
}
iIconSel = shFinfo.iIcon;
// we only need the index of the system image list
DestroyIcon( shFinfo.hIcon );
if ( strTemp.Right(1) == "\\" )
strTemp.SetAt( strTemp.GetLength() - 1, '\0' );
if ( hParent == TVI_ROOT )
return InsertItem( strTemp, iIcon, iIconSel, hParent );
return InsertItem( GetSubPath( strTemp ), iIcon, iIconSel, hParent );
}
LPCTSTR CDirTreeCtrl::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 CDirTreeCtrl::FindSubDir( LPCTSTR strPath)
{
//
// Are there subDirs ?
//
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;
}
//Save the selection on collasping.
void CDirTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
if(pNMTreeView->action==TVE_COLLAPSE || pNMTreeView->action==TVE_COLLAPSERESET)
UpdateData(TRUE);
*pResult = 0;
}
void CDirTreeCtrl::OnItemexpanded(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
CString strPath;
if ( pNMTreeView->itemNew.state & TVIS_EXPANDED )
{
//UINT uTest = TVIS_EXPANDEDONCE;
ExpandItem( pNMTreeView->itemNew.hItem, TVE_EXPAND );
/*
//
// Delete All items
// And display the subpath
//
HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem );
while ( hChild )
{
DeleteItem( hChild );
hChild = GetChildItem( pNMTreeView->itemNew.hItem );
}
strPath = GetFullPath( pNMTreeView->itemNew.hItem );
DisplayPath( pNMTreeView->itemNew.hItem, strPath );
*/
}
else
{
//
// Delete the Items, but leave one there, for
// expanding the item next time
//
HTREEITEM hChild = GetChildItem( pNMTreeView->itemNew.hItem );
while ( hChild )
{
DeleteItem( hChild );
hChild = GetChildItem( pNMTreeView->itemNew.hItem );
}
InsertItem( "", pNMTreeView->itemNew.hItem );
}
*pResult = 0;
}
CString CDirTreeCtrl::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;
}
BOOL CDirTreeCtrl::SetSelPath(LPCTSTR strPath)
{
// Setting the Selection in the Tree
HTREEITEM hParent = TVI_ROOT;
int iLen = strlen(strPath) + 2;
char* pszPath = new char[iLen];
char* pPath = pszPath;
BOOL bRet = FALSE;
if ( !IsValidPath( strPath ) )
{
delete [ ] pszPath; // this must be added 29.03.99
return FALSE;
}
strcpy( pszPath, strPath );
strupr( pszPath );
if ( pszPath[strlen(pszPath)-1] != '\\' )
strcat( pszPath, "\\" );
int iLen2 = strlen( pszPath );
for (WORD i = 0; i < iLen2; i++ )
{
if ( pszPath[i] == '\\' )
{
SetRedraw( FALSE );
pszPath[i] = '\0';
hParent = SearchSiblingItem( hParent, pPath );
if ( !hParent ) // Not found!
break;
else
{
// Info:
// the notification OnItemExpanded
// will not called every time
// after the call Expand.
// You must call Expand with TVE_COLLAPSE | TVE_COLLAPSERESET
// to Reset the TVIS_EXPANDEDONCE Flag
UINT uState;
uState = GetItemState( hParent, TVIS_EXPANDEDONCE );
if ( uState )
{
Expand( hParent, TVE_EXPAND );
Expand( hParent, TVE_COLLAPSE | TVE_COLLAPSERESET );
InsertItem("", hParent ); // insert a blank child-item
Expand( hParent, TVE_EXPAND ); // now, expand send a notification
}
else
Expand( hParent, TVE_EXPAND );
}
pPath += strlen(pPath) + 1;
}
}
delete [] pszPath;
if ( hParent ) // Ok the last subpath was found
{
SelectItem( hParent ); // select the last expanded item
bRet = TRUE;
}
else
{
bRet = FALSE;
}
SetRedraw( TRUE );
return bRet;
}
HTREEITEM CDirTreeCtrl::SearchSiblingItem( HTREEITEM hItem, LPCTSTR strText)
{
HTREEITEM hFound = GetChildItem( hItem );
CString strTemp;
while ( hFound )
{
strTemp = GetItemText( hFound );
strTemp.MakeUpper();
if ( strTemp == strText )
return hFound;
hFound = GetNextItem( hFound, TVGN_NEXT );
}
return NULL;
}
void CDirTreeCtrl::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 );
}
}
BOOL CDirTreeCtrl::IsValidPath(LPCTSTR strPath)
{
// This function check the Pathname
HTREEITEM hChild;
CString strItem;
CString strTempPath = strPath;
BOOL bFound = FALSE;
CFileFind find;
hChild = GetChildItem( TVI_ROOT );
strTempPath.MakeUpper();
strTempPath.TrimRight('\\');
while ( hChild )
{
strItem = GetItemText( hChild );
strItem.MakeUpper();
if ( strItem == strTempPath.Mid( 0, strItem.GetLength() ) )
{
bFound = TRUE;
break;
}
hChild = GetNextItem( hChild, TVGN_NEXT );
}
if ( !bFound )
return FALSE;
strTempPath += "\\nul";
if ( find.FindFile( strTempPath ) )
return TRUE;
return FALSE;
}
//if action is TRUE, Update protFileList from TreeCtrl.
//if action is FALSE, update treectrl form protFileList.
BOOL CDirTreeCtrl::UpdateData(BOOL action)
{
HTREEITEM hItem;
CString strProtFilePath;
//Only visual item can be modified, so just deal with them.
//(But remember to update when tree is collapsing.)
if((hItem=GetNextItem(NULL, TVGN_FIRSTVISIBLE))==NULL)
return TRUE;
UpdateOneItem(hItem, action);
while((hItem=GetNextItem(hItem, TVGN_NEXTVISIBLE))!=NULL)
UpdateOneItem(hItem, action);
::SendNotifyMessage(::GetParent(m_hWnd), WM_SHOW_DATA, 2, NULL);
return TRUE;
}
//Show(action==FALSE) or save(action==TRUE) data in/from an item.
void CDirTreeCtrl::UpdateOneItem(HTREEITEM hItem, BOOL action)
{
CString strProtFilePath=GetFullPath(hItem);
FGFormatPath(strProtFilePath);
if(action)
{
//store data from an item.
if(GetCheck(hItem))
{
/* if(hItem==GetSelectedItem() && !protFileList.IsInList(strProtFilePath))//GetItemState(hItem, TVIS_SELECTED)==TVIS_SELECTED)
{
protFileList.Add(strProtFilePath);//, ((CFileGuardView *) GetParent())->GetCurProtectionType());
return;
}
*/
//Search for the newly checked item;
if(!protFileList.IsInList(strProtFilePath))
{
protFileList.Add(strProtFilePath); //if the file or path is checked and not in the list,
// add it to the list using default protection type.
// If the file or path is already in the path, needless
// to add it.
SelectItem(hItem);
}
}
else protFileList.Remove(strProtFilePath); //if the file or path is unchecked, remove it.
}
else
{
//show data in an item.
if(protFileList.IsInList(strProtFilePath))
SetCheck(hItem);
else SetCheck(hItem, FALSE);
} // if(hItem)
}
//Save and show on selection changed.
void CDirTreeCtrl::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
CString strPath;
//Save old item.
if(pNMTreeView->itemOld.hItem)
{
strPath=GetFullPath(pNMTreeView->itemOld.hItem);
FGFormatPath(strPath);
if(GetCheck(pNMTreeView->itemOld.hItem))
protFileList.Add(strPath, ((CFileGuardView *)GetParent())->GetCurProtectionType());
else protFileList.Remove(strPath);
}
ShowItemType(pNMTreeView->itemNew.hItem);
*pResult = 0;
}
void CDirTreeCtrl::OnClick(NMHDR* pNMHDR, LRESULT* pResult)
{
UpdateData(TRUE);
((CFileGuardView *) GetParent())->ClearProtectionType();
ShowItemType(GetSelectedItem());
*pResult = 0;
}
//Show the protection type of the new item.
void CDirTreeCtrl::ShowItemType(HTREEITEM hItem)
{
FILE_NODE *pFNode;
CString strPath=GetFullPath(hItem);
FGFormatPath(strPath);
((CFileGuardView *)GetParent())->ClearProtectionType();
if((pFNode=protFileList.IsInList(strPath))!=NULL)
((CFileGuardView *)GetParent())->ShowProtectionType(&pFNode->protFile);
}
void CDirTreeCtrl::OnRightClick(NMHDR* pNMHDR, LRESULT* pResult)
{
*pResult = 0;
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
HTREEITEM hItem=pNMTreeView->itemNew.hItem;
if(!hItem)
return;
CString strPath=GetFullPath(hItem);
ShowFileProperty(strPath);
}
void CDirTreeCtrl::OnPostClick()
{
UpdateData(TRUE);
ShowItemType(GetSelectedItem());
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -