📄 ftptrctl.cpp
字号:
// FTPTrCtl.cpp : implementation file
//
// This is a part of the Microsoft Foundation Classes C++ library.
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// This source code is only intended as a supplement to the
// Microsoft Foundation Classes Reference and related
// electronic documentation provided with the library.
// See these sources for detailed information regarding the
// Microsoft Foundation Classes product.
#include "stdafx.h"
#include "FTPTREE.h"
#include "FTPtrCtl.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMyTreeCtrl
CMyTreeCtrl::CMyTreeCtrl()
{
// m_pFtpConnection holds a pointer to an FTP connection
// that is maintained by CFTPTREEDlg.
m_pFtpConnection = NULL;
}
CMyTreeCtrl::~CMyTreeCtrl()
{
}
BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)
//{{AFX_MSG_MAP(CMyTreeCtrl)
ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
ON_WM_DESTROY()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMyTreeCtrl message handlers
void CMyTreeCtrl::OnDestroy()
{
CImageList *pimagelist;
pimagelist = GetImageList(TVSIL_NORMAL);
pimagelist->DeleteImageList();
delete pimagelist;
}
void CMyTreeCtrl::PopulateTree(CFtpConnection* pConnection, const CString *pstrDir)
{
CWaitCursor cursor; // this will automatically display a wait cursor
// Make sure tree is empty before (re)populating it
DeleteAllItems();
// If CFtpConnection is NULL, display error in tree
if (!pConnection)
{
// change style -- remove TVS_LINESATROOT if it is currently set
ModifyStyle(TVS_LINESATROOT, 0);
TV_INSERTSTRUCT tvstruct;
tvstruct.hParent = NULL;
tvstruct.hInsertAfter = TVI_FIRST;
tvstruct.item.iImage = 0;
tvstruct.item.iSelectedImage = 0;
tvstruct.item.pszText = _T("An FTP connection has not been established.");
tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
InsertItem(&tvstruct);
m_pFtpConnection = NULL;
}
else
{
m_pFtpConnection = pConnection;
CString cstr = _T("/"); // look at the root directory first
// insert the the root into the tree struct
TV_INSERTSTRUCT tvstruct;
tvstruct.hParent = NULL;
tvstruct.hInsertAfter = TVI_LAST;
tvstruct.item.iImage = 1;
tvstruct.item.iSelectedImage = 1;
tvstruct.item.pszText = _T("/");
tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
HTREEITEM hThisItem = InsertItem(&tvstruct);
// the root dir needs to think it has children for Expand() to work
// Expand() will call ExploreDir() to find the root's real children
tvstruct.hParent = hThisItem;
InsertItem(&tvstruct);
Expand(GetRootItem(), TVE_EXPAND);
// if the root has no real children, make sure TVS_LINESATROOT is not set
if (!ItemHasChildren(GetRootItem()))
{
ModifyStyle(TVS_LINESATROOT, 0);
return;
}
// otherwise, there are children, so set TVS_LINESATROOT
ModifyStyle(0, TVS_LINESATROOT);
if (pstrDir == NULL)
return;
// expand as far as was indicated in strDir
int nIndex;
CString strTemp;
CString strSrc = *pstrDir;
HTREEITEM hTI = GetRootItem();
while (!strSrc.IsEmpty())
{
nIndex = strSrc.Find(_T("/"));
if (nIndex < 0)
{
cstr = strSrc;
strSrc.Empty();
}
else if (nIndex > 0)
{ // the "/" trailing the directory name is not included
cstr = strSrc.Left(nIndex);
strTemp = strSrc.Right(strSrc.GetLength() - (nIndex+1));
strSrc = strTemp;
}
if(!cstr.IsEmpty() && (nIndex != 0))
{
// cstr now has the name of a file or dir -- look for a child that matches it
hTI = GetChildItem(hTI);
while ((hTI != NULL) && (cstr != GetItemText(hTI)))
{
hTI = GetNextItem(hTI, TVGN_NEXT);
}
// if you find it, expand the node or select the file
if ((hTI != NULL) && (cstr == GetItemText(hTI)))
{
if (ItemHasChildren(hTI))
Expand(hTI, TVE_EXPAND);
else
{
SelectItem(hTI); // focus it here, too...
TV_ITEM tv;
tv.hItem = hTI;
tv.mask = TVIF_HANDLE | TVIF_STATE;
tv.stateMask = TVIS_BOLD;
if (GetItem(&tv))
{
tv.mask = TVIF_HANDLE | TVIF_STATE;
tv.stateMask = TVIS_BOLD;
tv.state = TVIS_BOLD;
SetItem(&tv);
}
strSrc.Empty(); // it's a file, so we're not gonna go any further
}
}
// if it wasn't found, you've gone as far as you can, so quit...
else strSrc.Empty();
}
else // nIndex == 0
{
strTemp = strSrc.Right(strSrc.GetLength() - 1);
strSrc = strTemp;
}
} // end expand
}
}
void CMyTreeCtrl::ExploreDir(const CString& strDir, HTREEITEM hParent)
{
TV_INSERTSTRUCT tvstruct;
CString strSearchDir;
// remove any children of this directory
HTREEITEM hIT = GetChildItem(hParent);
HTREEITEM hTemp;
while (hIT != NULL)
{
hTemp = GetNextSiblingItem(hIT);
DeleteItem(hIT);
hIT = hTemp;
}
// prepare to find all the files in the specified directory
if (hParent != GetRootItem())
{
strSearchDir = strDir + _T("/*");
}
else
{
strSearchDir = _T("/*");
}
CFtpFileFind ftpFind(m_pFtpConnection);
BOOL bContinue = ftpFind.FindFile(strSearchDir);
if (!bContinue)
{
// the directory is empty; just close up and return.
ftpFind.Close();
return;
}
BOOL bDir = FALSE;
HTREEITEM hThisItem;
CString strFileName;
while (bContinue) // set up and insert a tvstruct for each item in the directory
{
// FindNextFile muxt be called before info can be gleaned from ftpFind
bContinue = ftpFind.FindNextFile();
strFileName = ftpFind.GetFileName();
if (ftpFind.IsDirectory())
{
// found a directory. MUST find out if it has a child, and if so
bDir = TRUE;
tvstruct.item.iImage = 1;
tvstruct.item.iSelectedImage = 1;
}
else
{
tvstruct.item.iImage = 2;
tvstruct.item.iSelectedImage = 2;
}
tvstruct.hParent = hParent;
tvstruct.hInsertAfter = TVI_LAST;
tvstruct.item.pszText = (LPTSTR)(LPCTSTR)strFileName; // GetFileName() returns a CString
tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
hThisItem = InsertItem(&tvstruct);
}
ftpFind.Close();
// If any directories were found, and if they are not empty, a dummy child
// must be created so they can be expanded later. This check is done AFTER
// all of strDir has been explored because only one CFtpFileFind object can
// be open for any given FTP session.
if (bDir)
{
CFtpFileFind* pTempFtpFind = NULL;
CString strFullSearchPath;
int nImage, nSelectedImage;
hThisItem = GetChildItem(hParent);
while (hThisItem != NULL)
{
GetItemImage(hThisItem, nImage, nSelectedImage);
if (nImage == 1) // this item is a directory
{
strFileName = GetItemText(hThisItem);
// build the full path to the current directory
strFullSearchPath = strDir + strFileName + _T("/*");
pTempFtpFind = new CFtpFileFind(m_pFtpConnection);
if (pTempFtpFind->FindFile(strFullSearchPath))
{
tvstruct.hParent = hThisItem;
tvstruct.hInsertAfter = TVI_LAST;
tvstruct.item.iImage = 1;
tvstruct.item.iSelectedImage = 1;
tvstruct.item.pszText = _T("1");;
tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
InsertItem(&tvstruct);
}
pTempFtpFind->Close();
delete pTempFtpFind;
}
hThisItem = GetNextSiblingItem(hThisItem);
}
}
return;
}
void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
{
NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
// TODO: Add your control notification handler code here
// find out what item is getting expanded, and send that to Expand(hItem, TVE_EXPAND)
if (pNMTreeView->hdr.code == TVN_ITEMEXPANDING)
{
HTREEITEM hIT = pNMTreeView->itemNew.hItem;
CString cstr, strPath;
// build up the path to htreeitem
strPath = GetItemText(hIT);
while (hIT != GetRootItem())
{
hIT = GetParentItem(hIT);
if (hIT == GetRootItem())
cstr.Format(_T("/%s"), (LPCTSTR)strPath);
else
cstr.Format(_T("%s/%s"), (LPCTSTR)GetItemText(hIT), (LPCTSTR)strPath);
strPath = cstr;
}
// use that dir to call ExploreDir
ExploreDir(strPath, pNMTreeView->itemNew.hItem);
}
*pResult = 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -