Click here to Skip to main content
Click here to Skip to main content

FTP Client Class

By , 8 Dec 2012
 
ftpclient_demo.zip
FTPClient_demo
Release
FTPexample.exe
res
Download.avi
Filecopy.avi
FTPexample.ico
FTPexample.manifest
Search.avi
Upload.avi
ftpclient_demo_mfc.zip
FtpClient
FtpClient_Demo_Mfc
res
Download.avi
Filecopy.avi
FTPexample.ico
FTPexample.manifest
Search.avi
Upload.avi
ftpclient_src.zip
ftptestdevcpp.zip
FTPTestDevCPP
FTPTest.dev
FTPTest.layout
Makefile.win
#include "stdafx.h"
#include "FTPFileTreeCtrl.h"
#include "resource.h"

using namespace nsFTP;
using namespace nsFTP::nsView;

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


IMPLEMENT_DYNAMIC(CFTPFileTreeCtrl, CTreeCtrl)

BEGIN_MESSAGE_MAP(CFTPFileTreeCtrl, CTreeCtrl)
   ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemExpanded)
END_MESSAGE_MAP()

CFTPFileTreeCtrl::CFTPFileTreeCtrl() :
   m_pFTP(NULL),
   m_fFiles(false),
   m_ShellImageList(true, false)
{
}

CFTPFileTreeCtrl::~CFTPFileTreeCtrl()
{
}

bool CFTPFileTreeCtrl::DisplayTree(CFTPClient* pFTP, const CString& cszDisplayName, const CString& cszRootDir, bool fFiles)
{
   ASSERT( pFTP );

   m_pFTP = pFTP;

   m_fFiles  = fFiles;

   DeleteAllItems();

   m_RootInfo.m_cszRoot        = cszRootDir;
   m_RootInfo.m_cszDisplayName = cszDisplayName + _T(" ") + cszRootDir;

   m_RootInfo.m_htiRoot = AddItem(TVI_ROOT, cszDisplayName, true);
   DisplayPath(m_RootInfo.m_htiRoot);
   Expand(m_RootInfo.m_htiRoot, TVE_EXPAND);
   SelectItem(m_RootInfo.m_htiRoot);

   return true;   
}

void CFTPFileTreeCtrl::DisplayPath(HTREEITEM hParent)
{
   CWaitCursor wait;

   TFTPFileStatusShPtrVec vFileList;
   GetDirectoryListing(hParent, vFileList);

   SetRedraw(false);

   std::sort(vFileList.begin(), vFileList.end(), CFTPFileStatusContainerSort(CFTPFileStatusContainerSort::CName(), true, true));

   for( TFTPFileStatusShPtrVec::iterator it = vFileList.begin(); it!=vFileList.end(); it++ )
   {
      if( (*it)->IsCwdPossible() )
      {
         if( !(*it)->IsDot() )
         {
            HTREEITEM hItem = AddItem(hParent, (*it)->Name().c_str(), true);
            // insert dummy element for displaying plus sign
            InsertItem(_T(""), 0, 0, hItem); 
         }
      }
      else if( m_fFiles )
      {
         AddItem(hParent, (*it)->Name().c_str(), false);
      }
   }

   SetRedraw();
}

void CFTPFileTreeCtrl::GetDirectoryListing(HTREEITEM hItem, TFTPFileStatusShPtrVec& vFileList) const
{
   ASSERT( m_pFTP );
   if( m_RootInfo.m_htiRoot == hItem )
      m_pFTP->List(static_cast<LPCTSTR>(m_RootInfo.m_cszRoot), vFileList);
   else
      m_pFTP->List(static_cast<LPCTSTR>(GetFullPath(hItem)), vFileList);
}

HTREEITEM CFTPFileTreeCtrl::AddItem(HTREEITEM hParent, const CString& cszPath, const bool fDir)
{
   int iIcon = 0;
   int iIconSel = 0;

   if( fDir )
   {
      iIcon    = m_ShellImageList.GetFolderIcon(false, true);
      iIconSel = m_ShellImageList.GetFolderIcon(true, true);
   }
   else
   {
      iIcon    = m_ShellImageList.GetImageForExtension(cszPath, true);
      iIconSel = iIcon;
   }

   if( hParent==TVI_ROOT )
      return InsertItem(cszPath, iIcon, iIconSel, hParent);

   return InsertItem(GetSubPath(cszPath), iIcon, iIconSel, hParent);
}

CString CFTPFileTreeCtrl::GetSubPath(const CString& cszPath)
{
   CString cszTemp(cszPath);

   cszTemp.TrimRight(_T('/'));
   int iPos = cszTemp.ReverseFind(_T('/'));
   if( iPos != -1 )
      cszTemp = cszTemp.Mid(iPos + 1);

   return cszTemp;
}

void CFTPFileTreeCtrl::OnItemExpanded(NMHDR* pNMHDR, LRESULT* pResult) 
{
   NM_TREEVIEW* pNMTreeView = reinterpret_cast<NM_TREEVIEW*>(pNMHDR);

   if( pNMTreeView->itemNew.state & TVIS_EXPANDED )
   {
      SetRedraw(false);
      HTREEITEM hChild = GetChildItem(pNMTreeView->itemNew.hItem);
      while( hChild )
      {
         DeleteItem( hChild );
         hChild = GetChildItem( pNMTreeView->itemNew.hItem );
      }
      DisplayPath(pNMTreeView->itemNew.hItem);
      SetRedraw();
   }
   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(_T(""), pNMTreeView->itemNew.hItem);
   }

   *pResult = 0;
}

CString CFTPFileTreeCtrl::GetFullPath(HTREEITEM hItem) const
{
   CString cszFullPath;

   while( hItem )
   {
      if( hItem == m_RootInfo.m_htiRoot )
      {
         if (m_RootInfo.m_cszRoot.GetLength()>0 && m_RootInfo.m_cszRoot.Right(1)==_T("/"))
            cszFullPath = m_RootInfo.m_cszRoot + cszFullPath;
         else
            cszFullPath = m_RootInfo.m_cszRoot + _T("/") + cszFullPath;
      }
      else
      {
         cszFullPath = GetItemText(hItem) + _T("/") + cszFullPath;
      }
      hItem = GetParentItem(hItem);
   }
   
   cszFullPath.TrimRight(_T("/"));

   return cszFullPath;
}

bool CFTPFileTreeCtrl::SetSelectedPath(const CString& cszPath)
{
   // Setting the Selection in the Tree
   CString cszTempPath(cszPath);
   cszTempPath.Delete(0, m_RootInfo.m_cszRoot.GetLength());
   LPTSTR pszPath = cszTempPath.GetBuffer(0);
   
   SetRedraw(false);

   HTREEITEM hParent = GetChildItem(TVI_ROOT);
   pszPath = _tcstok(pszPath, _T("/"));
   while( pszPath && hParent )
   {
      hParent = SearchChildItem(hParent, pszPath);
      if( hParent )  // Not found!
      {           
         // 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
         if( GetItemState(hParent, TVIS_EXPANDEDONCE) )
         {
            Expand(hParent, TVE_EXPAND);
            Expand(hParent, TVE_COLLAPSE|TVE_COLLAPSERESET);
            InsertItem(_T(""), hParent);      // insert a blank child-item
         }
         Expand(hParent, TVE_EXPAND);  // now, expand send a notification
      }
      pszPath = _tcstok(NULL, _T("/"));
   }

   SetRedraw();
   cszTempPath.ReleaseBuffer();
   
   if ( hParent ) // Ok the last subpath was found
   {     
      SelectItem(hParent); // select the last expanded item
      EnsureVisible(hParent);
      return true;
   }

   return false;
}

HTREEITEM CFTPFileTreeCtrl::SearchChildItem(HTREEITEM hItem, const CString& cszText)
{
   HTREEITEM hFound = GetChildItem( hItem );
   while( hFound )
   {
      if( GetItemText(hFound).CompareNoCase(cszText)==0 )
         return hFound;
      hFound = GetNextItem(hFound, TVGN_NEXT);
   }
   return NULL;
}

void CFTPFileTreeCtrl::PreSubclassWindow() 
{
   SetImageList(m_ShellImageList.GetSmallImageList(), TVSIL_NORMAL);

   if( GetStyle() & TVS_EDITLABELS ) 
   {
      ModifyStyle(TVS_EDITLABELS, 0); // Don't allow the user to edit ItemLabels
   }

   CTreeCtrl::PreSubclassWindow();
}

By viewing downloads associated with this article you agree to the Terms of use and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

otom
Software Developer (Senior)
Germany Germany
Member
No Biography provided

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 9 Dec 2012
Article Copyright 2004 by otom
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid