CTreeView explorer

I am trying to emulate the win explorer using the tree view.  Is there a simple way to do this on init.  I dont need to have the icons next to them, however it would be nice.

Sorry for being unclear.  Next to each folder needs to be the folder icon.  But underneath all of the directory listings I need to have all the files show up that are within that particular directory.
LVL 1
boodabellyAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

JPMartineauCommented:
Check this out:  

http://www.codeguru.com/treeview/
under the "Directory Browsers" section

You will find a few implementations of what you seem to want. You will surely find one that suits you.

Good Luck
0
boodabellyAuthor Commented:
I have already checked those out and they are not accomplishing what I need to be done with efficiency, or without noticeable bugs.  I will work with it a little more and see what comes of it.  Thank you for your time though.
0
stu32934Commented:
I've worked through a tree view and a gallery 'tile' view. The Stingray objective Toolkit Pro (www.stingray.com)has tree view functionality.

Have a search for CGridCtrl on codeguru. This is by Chris Maunder and we've found this could be adapted for a tree view.

0
Cloud Class® Course: Certified Penetration Testing

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

abancroftCommented:
You want a tree view that shows shell objects AND their contents. e.g. both folders and files are displayed in the tree?

How comprehensive does this have to be?

Does it have to respond to file system changes? e.g. user delete's file in Explorer - does your app have to respond?

Does it have to display all shell objects? Or just drives/folders & files?

There is an MSDN article that may help: http://msdn.microsoft.com/library/periodic/period96/D1/vc1096.htm
0
boodabellyAuthor Commented:
abancroft,
I am looking at the article that you suggested now.  My main problem is trying to get the whole tree structure filled at load time rather than throughout the execution.

stu,
I have to use the tree control
0
abancroftCommented:
Depending on how many drives and folders you need to display, filling the entire tree (all drives, folders & files) at load time may not be a good idea.

Do you need to display all drives/folders/files? Or just a subset?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
boodabellyAuthor Commented:
I am only needing to display the C drive to the user.

The MSDN samples looks allright but I cant find the rest of the source that he left out on the cd's.  Im trying to patch it together now.
0
abancroftCommented:
Then loading the tree during OnInitialUpdate() will be slow and take up excessive memory.

You'll have to scan the entire C drive and the tree will have to allocate enough space to store all the filenames (including paths).

To get some idea of the speed, go to a DOS prompt, change to C:\ and execute the following command:
  C:\> dir /s > c:\temp\test.txt <enter>

After this completes, look & see how big test.txt is - it'll be about twice as big as the tree memory requirement.
0
boodabellyAuthor Commented:
That took about ten seconds in DOS.  How does MS get it accomplished so fast when you open explorer.  Is there some way to access the memory that MS probably already has loaded for the file structures?
0
abancroftCommented:
MS probably doesn't do that.

I know I don't do it - I have a treeview that sits atop a database (the DB can contain thousands of items).

What you need to do is display the root (C:) and the items directly beneath it (the files & folders in C:) on initialisation.

The tree control will notify it's parent when a branch is about to be expanded (TVN_ITEMEXPANDING).

When you recieve this notification, you can then fill in the relevant tree item with the files & folders that the corresponding disk folder contains.
0
boodabellyAuthor Commented:
abancroft,
Thats what I have been trying, but since I am also adding all the files that are listed in the folder too.  It take a few, maybe even 5 or 10 seconds to expand.  I guess this might be something that they have to live with, or Ill just have to scrap the treeview.

Let me get this finished and Ill close the question for you.

If you know anyways to search and display the contents of the folders that is optimized for speed please let me know.

Thanks.
0
abancroftCommented:
Maybe I wasn't clear enough.

When the user expands a node, you only fill in the files & folder IN THAT NODE. This should be almost as fast as doing "dir <your folder>" (note no /s). Don't recurse and fill in any sub folders - these get filled when the user expands them.

Once a node has been filled in once, you don't need to fill it in again.
0
boodabellyAuthor Commented:
Ok I got you now.

Thanks.
0
boodabellyAuthor Commented:
abancroft,

Ive hit a wall.  I can get the treectrl to load if I call my function explicitly in the code.  If I try to have to function called with the expand item message it blows up.  Here is the source for what I have so far.  Most of this is modified MSDN, but I dont know what I am missing here.

//
// FileBrowser.cpp : implementation file
//

#include "stdafx.h"
#include "pn Archiver.h"
#include "FileBrowser.h"

CFileBrowser::CFileBrowser()
{
      m_strRoot = "";
}

CFileBrowser::~CFileBrowser()
{
      m_imgList.Detach();
}

BEGIN_MESSAGE_MAP(CFileBrowser, CTreeCtrl)
      //{{AFX_MSG_MAP(CFileBrowser)
      ON_NOTIFY_REFLECT(TVN_ITEMEXPANDED, OnItemexpanded)
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()

int CFileBrowser::loadTree()
{
      HTREEITEM hRoot;
      DWORD        dwStyle;

      dwStyle = GetStyle();                                                                                                                  // read the windowstyle

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

      hRoot = createTV_Item("C:", TVI_ROOT);
      createTV_Item("", hRoot);

      getDirInfo("C:", hRoot);

      return 1;
}

HTREEITEM CFileBrowser::createTV_Item(LPCTSTR szText, HTREEITEM hParent)
{
      TVINSERTSTRUCT tvInsert;
      TVITEM               tvItem;
      HTREEITEM         hRoot;

      tvItem.mask                        = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
      tvItem.pszText                  = (char *)szText;
      tvItem.cchTextMax            = strlen((const char *)szText);
      tvItem.iImage                  = 0;
      tvItem.iSelectedImage      = 0;
      tvItem.cChildren            = 1;

      tvInsert.hParent            = hParent;
      tvInsert.hInsertAfter      = TVI_SORT;
      tvInsert.item                  = tvItem;

      hRoot = InsertItem(&tvInsert);

      return hRoot;
}

void CFileBrowser::getDirInfo(CString currentDir, HTREEITEM hParent)
{
      CFileFind ffFinder;
      BOOL        bWorking;
      HTREEITEM hTemp;

      bWorking = ffFinder.FindFile(currentDir + "\\*.*");

      while (bWorking)
      {
            bWorking = ffFinder.FindNextFile();
            
            if(ffFinder.IsDirectory())
            {
                  if(ffFinder.IsDots() || ffFinder.IsSystem())
                  {
                        continue;
                  }

                  hTemp = createTV_Item(ffFinder.GetFileTitle(), hParent);

                  if(hasChildren(ffFinder.GetFilePath()))
                  {
                        createTV_Item("", hTemp);
                  }                        
            }
            else if(ffFinder.IsHidden() || ffFinder.IsSystem())
            {
                  continue;
            }
            else
            {
            //      hTemp = createTV_Item(ffFinder.GetFileName(), hParent);
            }
      }
}

void CFileBrowser::OnItemexpanded(NMHDR *pNMHDR, LRESULT *pResult)
{
      NM_TREEVIEW *pNMTreeView = (NM_TREEVIEW *)pNMHDR;
      CString            strTemp;

      if(pNMTreeView->itemNew.state & TVIS_EXPANDED)
      {
            expandItem(pNMTreeView->itemNew.hItem, TVE_EXPAND);
      }
      else
      {
      }

      pResult = 0;
}

int CFileBrowser::hasChildren(CString szPath)
{
      CFileFind ffPath;
      int              iHasChildren;

      iHasChildren = ffPath.FindFile(szPath + "\\*.*");

      while(iHasChildren)
      {
            iHasChildren = ffPath.FindNextFile();

            if(ffPath.IsDots())
            {
                  continue;
            }

            if(ffPath.IsDirectory() || iHasChildren)
            {
                  return 1;
            }
      }

      return 0;
}

void CFileBrowser::expandItem(HTREEITEM hItem, UINT nCode)
{      
      HTREEITEM hChild;
      CString        strPath;
      strPath = getFullPath(hItem);
      if(nCode == TVE_EXPAND)
      {
            hChild = GetChildItem(hItem);

            while(hChild)
            {
                  DeleteItem(hChild);
                  hChild = GetChildItem(hItem);
            }
       
            strPath = getFullPath(hItem);
            getDirInfo(strPath, hItem);
      }
}

CString CFileBrowser::getFullPath(HTREEITEM hItem)
{
      CString strReturn;
      CString strTemp;
      HTREEITEM hParent = hItem;

      strReturn = "";

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

    if(strReturn.Right(1) == '\\')
      {
            strReturn.SetAt(strReturn.GetLength() - 1, '\0');
      }

    return strReturn;
}

0
boodabellyAuthor Commented:
sorry about the indentions, I guess they didnt take on the copy and paste.
0
abancroftCommented:
Can't see anything obvious.

What happens when you set a break point & step through the message handler?
0
boodabellyAuthor Commented:
All of the parameters and everything get passed in correctly to the function from calling getDirInfo() in expandItem.  But when I step through it bWorking is FALSE.  bWorking is true when its called from the loadTree().  I have asked three other people here at work, the problem is we are graphics programmers not MFC programmers.
0
abancroftCommented:
When does bWorking get set to FALSE? FindFile() or FindNextFile()?

Add a call to GetLastError() to see what the error is.
0
boodabellyAuthor Commented:
I figured it out.  I changed this



if(strReturn.Right(1) == '\\')
{
  strReturn.SetAt(strReturn.GetLength() - 1, '\0');
}

to strReturn += "\\*.*";

and now it works.
 
0
inprasCommented:
Hi
Go to
http://indigo.ie/~pjn/index.html#visualc
click on GUI Freeware
there U have an example
CTreeFileControl & CSortedArray - A Tree control to display files & a sortable "CArray"
clck on this and down load
Hope this helps
inpras
0
boodabellyAuthor Commented:
thanks for the help
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.