Thread: Directory listing in treeview control

  1. #1
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879

    Question Directory listing in treeview control

    Hi everyone,

    In my dialog-based program, I'm trying to fill in a tree view control with the contents of harddrive. With listboxes/comboboxes/other stuff, there are messages like LB_DIR and DlgDirList and CB_DIR and all that, that you can use to fill the control with the contents of the directory. But for treeview controls, which are the most commonly used for that purpose, there doesn't seem to be any ez-fill function/macro/message to use. I've already searched MSDN (the one with MSVC++), and I've tried Google (turning up a whole lot of useless stuff), so please don't give the generic google to me

    Have I overlooked something, or is it really necessary to manually find every file on the harddrive with FindFirstFile()/FindNextFile() and then fill in an entry for each?
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

  2. #2
    Registered User
    Join Date
    Feb 2003
    Posts
    76
    This is an EnumFiles function I created some time ago. It's a non-recursive function. If you look hard enough at the code, you can figure out the rest of the problem: how to add the files to the treeview.

    Code:
    // filename.h
    
    #include <windows.h>
    
    typedef BOOL (CALLBACK *ENUMFILEPROC)(LPCTSTR,LPTSTR,DWORD,LPARAM);
    #define PATHSEP '\\'
    #define EXTSEP  '.'
    #define EF_RECURSE    0x0001
    #define EF_NOGETDIR   0x0002
    #define EF_NOGETFILE  0x0004
    #define EF_GETDIRLAST 0x0008
    
    BOOL ParsePath(LPCTSTR filespec,LPTSTR path,LPTSTR *name,LPTSTR *ext);
    BOOL EnumFiles(LPCTSTR filespec, UINT uFlags, ENUMFILEPROC efp, LPARAM lParam);
    
    #define SetFileNameExt(out,dir,name,ext) \
    wsprintf(out,"%s%c%s%c%s",(dir)?dir:"",PATHSEP,(name)?name:"",EXTSEP,(ext)?ext:"")
    #define SetFileName(out,dir,name) \
    wsprintf(out,"%s%c%s",(dir)?dir:"",PATHSEP,(name)?name:"")
    Code:
    // filename.c
    #include "filename.h"
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    BOOL ParsePath(LPCTSTR filespec,
                   LPTSTR path,
                   LPTSTR *name,
                   LPTSTR *ext){
     if(name)*name=NULL;
     if(ext)*ext=NULL;
     if (lstrlen(filespec) >= _MAX_PATH)
      return FALSE;
     if (lstrcmp(filespec,_T("."))==0 || lstrcmp(filespec,_T(".."))==0) {
      if(path)GetCurrentDirectory(MAX_PATH,path);
      return TRUE;
     } else {
      // Parse extension
      int i;
      TCHAR c;
      int len = lstrlen(filespec);
      for (i = len-1; i>=0; i--) {
       c = filespec[i];
       if (c==PATHSEP) {
        break;
       } else if (c==EXTSEP) {
        if(ext)*ext = &filespec[i+1];
        i--; // skip dot
        break;
       }
      }
      // Parse name
      for ( ; i>=0; i--) {
       c = filespec[i];
       if (c==PATHSEP) {
        if(name)*name = &filespec[i+1];
        if(path)lstrcpyn(path,filespec,i+1);
        break;
       } else if (i==0) {
        if(name)*name=filespec;
        if(path)GetCurrentDirectory(MAX_PATH,path);
        break;
       }
      }
     }
     return TRUE;
    }
    
    
    
    static int charicmp ( char char1, char char2 ){
     char	Char1 = ( 'a' <= char1 ) && ( char1 <= 'z' ) ? char1 - 'a' + 'A' : char1;
     char	Char2 = ( 'a' <= char2 ) && ( char2 <= 'z' ) ? char2 - 'a' + 'A' : char2;
     return ( Char2 - Char1 );
    }
    static int _mfs_regexp(LPSTR lpFileName,LPSTR lpFilter){
     LPSTR                   lpTempFileName = lpFileName;
     LPSTR                   lpTempFilter   = lpFilter;
     char                    TempToken [ 2 ];
     BOOL                    Matched = FALSE;
     if((! lpFileName) ||(! *lpFileName) ||
     (! lpFilter) ||(! *lpFilter))
       return(FALSE);
     while((lpTempFilter) &&(*lpTempFilter) &&(! Matched)){
      memset(TempToken, 0, sizeof(TempToken));
      switch(*lpTempFilter){
       default:
        if(charicmp(*lpTempFileName, *lpTempFilter)){
         lpTempFileName = lpFileName;
         if ((lpTempFilter = strpbrk(lpTempFilter, " ,;")))
          lpTempFilter++;
        } else {
         lpTempFilter++;
         lpTempFileName++;
         switch(*lpTempFilter){
          default:
           break;
          case '\0':case ' ':case ',':case ';':
           if(! *lpTempFileName)
            Matched = TRUE;
           break;
         }
        }
        break;
       case '?':
        lpTempFilter++;
        lpTempFileName++;
        break;
       case '*':
        if(!(TempToken [ 0 ] = *(++lpTempFilter)))
         Matched = TRUE;
        else
        {
         lpTempFilter++;
         while((lpTempFileName = strpbrk(lpTempFileName, TempToken)) &&
                (! Matched))
          Matched = _mfs_regexp(++lpTempFileName, lpTempFilter);
         if((! lpTempFileName) &&(! Matched))
         {
          lpTempFileName = lpFileName;
          if ((lpTempFilter = strpbrk(lpTempFilter, " ,;")))
           lpTempFilter++;
         }
        }
        break;
       case '\0':case ' ':case ',':case ';':
        Matched = TRUE;
        break;
      }
     }
     return(Matched);
    }
    
    BOOL EnumFiles(LPCTSTR filespec, UINT uFlags, ENUMFILEPROC efp, LPARAM lParam){
     HANDLE hf=INVALID_HANDLE_VALUE;
     WIN32_FIND_DATA fd;
     TCHAR fullname[MAX_PATH];
     TCHAR fullpath[MAX_PATH];
     TCHAR findspec[MAX_PATH];
     HANDLE *pStack=NULL; // handle stack to improve efficiency
     int stacksize=0;
     LPTSTR name,ext;
     BOOL bexit=FALSE;
     BOOL ngf=(uFlags&EF_NOGETFILE);
     BOOL ngd=(uFlags&EF_NOGETDIR);
     BOOL rcu=(uFlags&EF_RECURSE);
     BOOL rcf=FALSE;
     int i;
     if(ngf&&ngd)
      return TRUE;
     ParsePath(filespec,fullname,&name,&ext);
     if(uFlags&EF_RECURSE){
      pStack=malloc(sizeof(HANDLE)*MAX_PATH);
      if(!pStack)return FALSE;
      SetFileName(findspec,fullname,"*.*");
      rcf=TRUE;
     } else {
      lstrcpy(findspec,filespec);
     }
     while(1){
      BOOL leavenow=FALSE;
      if(hf==INVALID_HANDLE_VALUE)
       hf=FindFirstFile(findspec,&fd);
      if(pStack)pStack[stacksize++]=hf;
      if(hf!=INVALID_HANDLE_VALUE){
       // push onto stack
       while(1){
        BOOL isdir=(fd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY);
        if(lstrcmp(fd.cFileName,".")&&lstrcmp(fd.cFileName,"..")){
    //   DebugOut("%s | %s",fd.cFileName,name);
    #define CHKAGAINST (!rcu||(rcu&&(isdir||(!isdir&&_mfs_regexp(fd.cFileName,name)))))
         if(((!ngf&&!ngd)||(ngf&&isdir)||(ngd&&!isdir))
            &&CHKAGAINST){
          SetFileName(fullpath,fullname,fd.cFileName);
          if(!efp(fullpath,
                 fd.cFileName,
                 fd.dwFileAttributes,
                 lParam)){
           FindClose(hf);
           if(pStack)free(pStack);
           return TRUE;
          }
         }
         if((uFlags&EF_RECURSE)&&isdir){
          BOOL ret;
          TCHAR fullpath2[MAX_PATH];
          SetFileName(fullpath,fullname,fd.cFileName);
          SetFileName(fullpath2,fullpath,name);
          SetFileName(findspec,fullpath2,"*.*");
          leavenow=TRUE;
          break;
         }
        }
        if(!FindNextFile(hf,&fd))
         break;
       }
       if(leavenow){
        hf=INVALID_HANDLE_VALUE;
        continue;
       }
       FindClose(hf);
      }
      // pop from stack
      if(pStack&&stacksize>0)hf=pStack[--stacksize];
      if(uFlags&EF_RECURSE){
       if(stacksize==0)break;
      } else break;
      for(i=lstrlen(findspec)-1;i<=0;i--)
       if(findspec[i]==PATHSEP){findspec[i]='\0';break;}
     }
     if(pStack)free(pStack);
     return TRUE;
    }
    
    
    //  sample callback functions
    
    
    BOOL EnumFiles_CalcTotalFileSize(LPCTSTR filename, LPTSTR filepart, DWORD dwAttr, LPARAM lParam){
     PDWORD64 pdwlSize=(void*)lParam;
     if(!(dwAttr&FILE_ATTRIBUTE_DIRECTORY)){
      DWORD dwLow,dwHigh;
      HANDLE hf=OpenFileForReading(filename);
      dwLow=GetFileSize(hf,&dwHigh);
      if(dwHigh==0)
       *pdwlSize+=(DWORD64)dwLow;
      else
       *pdwlSize+=((DWORD64)dwHigh<<32)|dwLow;
      CloseHandle(hf);
     }
     return TRUE;
    }
    
    BOOL EnumFiles_NumberOfFiles(LPCTSTR filename, LPTSTR filepart, DWORD dwAttr, LPARAM lParam){
     PDWORD pdwNum=(void*)lParam;
     *pdwNum+=1;
     return TRUE;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Couple errors please help :-D
    By JJJIrish05 in forum C Programming
    Replies: 9
    Last Post: 03-06-2008, 02:54 AM
  2. Listing specific files in a directory
    By knirirr in forum C Programming
    Replies: 14
    Last Post: 01-29-2008, 05:42 AM
  3. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  4. Directory listing
    By brif in forum C++ Programming
    Replies: 1
    Last Post: 10-10-2002, 06:44 AM
  5. Tab Controls - API
    By -KEN- in forum Windows Programming
    Replies: 7
    Last Post: 06-02-2002, 09:44 AM