home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / mfc / internet / ftptree / ftptrctl.cpp next >
Encoding:
C/C++ Source or Header  |  1998-03-27  |  8.4 KB  |  333 lines

  1. // FTPTrCtl.cpp : implementation file
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "stdafx.h"
  14. #include "FTPTREE.h"
  15. #include "FTPtrCtl.h"
  16.  
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22.  
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CMyTreeCtrl
  25.  
  26. CMyTreeCtrl::CMyTreeCtrl()
  27. {
  28.     // m_pFtpConnection holds a pointer to an FTP connection
  29.     // that is maintained by CFTPTREEDlg.
  30.     m_pFtpConnection = NULL;
  31. }
  32.  
  33. CMyTreeCtrl::~CMyTreeCtrl()
  34. {
  35. }
  36.  
  37.  
  38. BEGIN_MESSAGE_MAP(CMyTreeCtrl, CTreeCtrl)
  39.     //{{AFX_MSG_MAP(CMyTreeCtrl)
  40.     ON_NOTIFY_REFLECT(TVN_ITEMEXPANDING, OnItemexpanding)
  41.     ON_WM_DESTROY()
  42.     //}}AFX_MSG_MAP
  43. END_MESSAGE_MAP()
  44.  
  45. /////////////////////////////////////////////////////////////////////////////
  46. // CMyTreeCtrl message handlers
  47.  
  48. void CMyTreeCtrl::OnDestroy()
  49. {
  50.     CImageList  *pimagelist;
  51.  
  52.     pimagelist = GetImageList(TVSIL_NORMAL);
  53.     pimagelist->DeleteImageList();
  54.     delete pimagelist;
  55. }
  56.  
  57.  
  58. void CMyTreeCtrl::PopulateTree(CFtpConnection* pConnection, const CString& strDir)
  59. {
  60.     CWaitCursor cursor; // this will automatically display a wait cursor
  61.  
  62.     // Make sure tree is empty before (re)populating it
  63.     DeleteAllItems();
  64.  
  65.     // If CFtpConnection is NULL, display error in tree
  66.     if (!pConnection)
  67.     {
  68.  
  69.         // change style -- remove TVS_LINESATROOT if it is currently set
  70.         ModifyStyle(TVS_LINESATROOT, 0);
  71.  
  72.         TV_INSERTSTRUCT tvstruct;
  73.  
  74.         tvstruct.hParent = NULL;
  75.         tvstruct.hInsertAfter = TVI_FIRST;
  76.         tvstruct.item.iImage = 0;
  77.         tvstruct.item.iSelectedImage = 0;
  78.         tvstruct.item.pszText = _T("An FTP connection has not been established.");
  79.         tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
  80.         InsertItem(&tvstruct);
  81.  
  82.         m_pFtpConnection = NULL;
  83.     }
  84.     else
  85.     {
  86.         m_pFtpConnection = pConnection;
  87.  
  88.         CString cstr = _T("/"); // look at the root directory first
  89.  
  90.         // insert the the root into the tree struct
  91.         TV_INSERTSTRUCT tvstruct;
  92.  
  93.         tvstruct.hParent = NULL;
  94.         tvstruct.hInsertAfter = TVI_LAST;
  95.         tvstruct.item.iImage = 1;
  96.         tvstruct.item.iSelectedImage = 1;
  97.         tvstruct.item.pszText = _T("/");
  98.         tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
  99.         HTREEITEM hThisItem = InsertItem(&tvstruct);
  100.  
  101.         // the root dir needs to think it has children for Expand() to work
  102.         // Expand() will call ExploreDir() to find the root's real children
  103.         tvstruct.hParent = hThisItem;
  104.         InsertItem(&tvstruct);
  105.  
  106.         Expand(GetRootItem(), TVE_EXPAND);
  107.  
  108.         // if the root has no real children, make sure TVS_LINESATROOT is not set
  109.         if (!ItemHasChildren(GetRootItem()))
  110.         {
  111.             ModifyStyle(TVS_LINESATROOT, 0);
  112.             return;
  113.         }
  114.  
  115.         // otherwise, there are children, so set TVS_LINESATROOT
  116.         ModifyStyle(0, TVS_LINESATROOT);
  117.  
  118.         if (!strDir)
  119.             return;
  120.  
  121.         // expand as far as was indicated in strDir
  122.         int nIndex;
  123.         CString strTemp;
  124.         CString strSrc = strDir;
  125.         HTREEITEM hTI = GetRootItem();
  126.         while (!strSrc.IsEmpty())
  127.         {
  128.             nIndex = strSrc.Find(_T("/"));
  129.             if (nIndex < 0)
  130.             {
  131.                 cstr = strSrc;
  132.                 strSrc.Empty();
  133.             }
  134.             else if (nIndex > 0)
  135.             { // the "/" trailing the directory name is not included
  136.                 cstr = strSrc.Left(nIndex);
  137.                 strTemp = strSrc.Right(strSrc.GetLength() - (nIndex+1));
  138.                 strSrc = strTemp;
  139.             }
  140.  
  141.             if(!cstr.IsEmpty() && (nIndex != 0))
  142.             {
  143.  
  144.                 // cstr now has the name of a file or dir -- look for a child that matches it
  145.                 hTI = GetChildItem(hTI);
  146.                 while ((hTI != NULL) && (cstr != GetItemText(hTI)))
  147.                 {
  148.                     hTI = GetNextItem(hTI, TVGN_NEXT);
  149.                 }
  150.  
  151.                 // if you find it, expand the node or select the file
  152.                 if ((hTI != NULL) && (cstr == GetItemText(hTI)))
  153.                 {
  154.                     if (ItemHasChildren(hTI))
  155.                         Expand(hTI, TVE_EXPAND);
  156.                     else
  157.                     {
  158.                         SelectItem(hTI);    // focus it here, too...
  159.                         TV_ITEM tv;
  160.                         tv.hItem = hTI;
  161.                         tv.mask = TVIF_HANDLE | TVIF_STATE;
  162.                         tv.stateMask = TVIS_BOLD;
  163.                         if (GetItem(&tv))
  164.                         {
  165.                             tv.mask = TVIF_HANDLE | TVIF_STATE;
  166.                             tv.stateMask = TVIS_BOLD;
  167.                             tv.state = TVIS_BOLD;
  168.                             SetItem(&tv);
  169.                         }
  170.                         strSrc.Empty(); // it's a file, so we're not gonna go any further
  171.                     }
  172.                 }
  173.  
  174.                 // if it wasn't found, you've gone as far as you can, so quit...
  175.                 else strSrc.Empty();
  176.             }
  177.             else // nIndex == 0
  178.             {
  179.                 strTemp = strSrc.Right(strSrc.GetLength() - 1);
  180.                 strSrc = strTemp;
  181.             }
  182.         } // end expand
  183.     }
  184. }
  185.  
  186. void CMyTreeCtrl::ExploreDir(const CString& strDir, HTREEITEM hParent)
  187. {
  188.     TV_INSERTSTRUCT tvstruct;
  189.     CString strSearchDir;
  190.  
  191.     // remove any children of this directory
  192.     HTREEITEM hIT = GetChildItem(hParent);
  193.     HTREEITEM hTemp;
  194.  
  195.     while (hIT != NULL)
  196.     {
  197.         hTemp = GetNextSiblingItem(hIT);
  198.         DeleteItem(hIT);
  199.         hIT = hTemp;
  200.     }
  201.  
  202.     // prepare to find all the files in the specified directory
  203.     if (hParent != GetRootItem())
  204.     {
  205.         strSearchDir = strDir + _T("/*");
  206.     }
  207.     else
  208.     {
  209.         strSearchDir = _T("/*");
  210.     }
  211.  
  212.  
  213.     CFtpFileFind ftpFind(m_pFtpConnection);
  214.  
  215.     BOOL bContinue = ftpFind.FindFile(strSearchDir);
  216.     if (!bContinue)
  217.     {
  218.         // the directory is empty; just close up and return.
  219.         ftpFind.Close();
  220.         return;
  221.     }
  222.  
  223.     BOOL bDir = FALSE;
  224.     HTREEITEM hThisItem;
  225.     CString strFileName;
  226.  
  227.     while (bContinue) // set up and insert a tvstruct for each item in the directory
  228.     {
  229.         // FindNextFile muxt be called before info can be gleaned from ftpFind
  230.         bContinue = ftpFind.FindNextFile();
  231.         strFileName = ftpFind.GetFileName();
  232.  
  233.         if (ftpFind.IsDirectory())
  234.         {
  235.             // found a directory.  MUST find out if it has a child, and if so
  236.  
  237.             bDir = TRUE;
  238.  
  239.             tvstruct.item.iImage = 1;
  240.             tvstruct.item.iSelectedImage = 1;
  241.         }
  242.         else
  243.         {
  244.  
  245.             tvstruct.item.iImage = 2;
  246.             tvstruct.item.iSelectedImage = 2;
  247.         }
  248.  
  249.         tvstruct.hParent = hParent;
  250.         tvstruct.hInsertAfter = TVI_LAST;
  251.         tvstruct.item.pszText = (LPTSTR)(LPCTSTR)strFileName;   // GetFileName() returns a CString
  252.         tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
  253.  
  254.         hThisItem = InsertItem(&tvstruct);
  255.  
  256.     }
  257.  
  258.     ftpFind.Close();
  259.  
  260.     // If any directories were found, and if they are not empty, a dummy child
  261.     // must be created so they can be expanded later.  This check is done AFTER
  262.     // all of strDir has been explored because only one CFtpFileFind object can
  263.     // be open for any given FTP session.
  264.     if (bDir)
  265.     {
  266.         CFtpFileFind* pTempFtpFind = NULL;
  267.         CString strFullSearchPath;
  268.         int nImage, nSelectedImage;
  269.  
  270.         hThisItem = GetChildItem(hParent);
  271.  
  272.         while (hThisItem != NULL)
  273.         {
  274.             GetItemImage(hThisItem, nImage, nSelectedImage);
  275.             if (nImage == 1) // this item is a directory
  276.             {
  277.                 strFileName = GetItemText(hThisItem);
  278.                 // build the full path to the current directory
  279.                 strFullSearchPath = strDir + strFileName + _T("/*");
  280.                 pTempFtpFind = new CFtpFileFind(m_pFtpConnection);
  281.                 if (pTempFtpFind->FindFile(strFullSearchPath))
  282.                 {
  283.                     tvstruct.hParent = hThisItem;
  284.                     tvstruct.hInsertAfter = TVI_LAST;
  285.                     tvstruct.item.iImage = 1;
  286.                     tvstruct.item.iSelectedImage = 1;
  287.                     tvstruct.item.pszText = _T("1");;
  288.                     tvstruct.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE | TVIF_TEXT;
  289.                     InsertItem(&tvstruct);
  290.                 }
  291.                 pTempFtpFind->Close();
  292.                 delete pTempFtpFind;
  293.             }
  294.             hThisItem = GetNextSiblingItem(hThisItem);
  295.         }
  296.     }
  297.  
  298.     return;
  299.  
  300. }
  301.  
  302. void CMyTreeCtrl::OnItemexpanding(NMHDR* pNMHDR, LRESULT* pResult)
  303. {
  304.     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  305.     // TODO: Add your control notification handler code here
  306.  
  307.     // find out what item is getting expanded, and send that to Expand(hItem, TVE_EXPAND)
  308.     if (pNMTreeView->hdr.code == TVN_ITEMEXPANDING)
  309.     {
  310.         HTREEITEM hIT = pNMTreeView->itemNew.hItem;
  311.         CString cstr, strPath;
  312.  
  313.         // build up the path to htreeitem
  314.         strPath = GetItemText(hIT);
  315.  
  316.         while (hIT != GetRootItem())
  317.         {
  318.             hIT = GetParentItem(hIT);
  319.  
  320.             if (hIT == GetRootItem())
  321.                 cstr.Format(_T("/%s"), (LPCTSTR)strPath);
  322.             else
  323.                 cstr.Format(_T("%s/%s"), (LPCTSTR)GetItemText(hIT), (LPCTSTR)strPath);
  324.  
  325.             strPath = cstr;
  326.         }
  327.  
  328.         // use that dir to call ExploreDir
  329.         ExploreDir(strPath, pNMTreeView->itemNew.hItem);
  330.     }
  331.     *pResult = 0;
  332. }
  333.