Walk_Directories.cpp
Upload User: dq031136
Upload Date: 2022-08-08
Package Size: 802k
Code Size: 6k
Development Platform:

C++ Builder

  1. //
  2. // Walk_Directories.cpp
  3. //
  4. #include "CmnHdr.H"
  5. #include <windows.h>
  6. #include <windowsx.h>
  7. #include <tchar.h>
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include "Resource.H"
  12. static BOOL IsChildDir (WIN32_FIND_DATA *lpFindData) 
  13. {
  14.   return(
  15.     ((lpFindData->dwFileAttributes &
  16.       FILE_ATTRIBUTE_DIRECTORY) != 0) &&
  17.       (lstrcmp(lpFindData->cFileName, _TEXT(".")) !=0) &&
  18.       (lstrcmp(lpFindData->cFileName, _TEXT("..")) != 0));
  19. }
  20. static BOOL FindNextChildDir (HANDLE hFindFile, WIN32_FIND_DATA *lpFindData)
  21. {
  22.   BOOL fFound = FALSE;
  23.   do
  24.   {
  25.     fFound = FindNextFile(hFindFile, lpFindData);
  26.   } while (fFound && !IsChildDir(lpFindData));
  27.   return(fFound);
  28. }
  29. static HANDLE FindFirstChildDir (LPTSTR szPath, WIN32_FIND_DATA *lpFindData)
  30. {
  31.   BOOL fFound;
  32.   HANDLE hFindFile = FindFirstFile(szPath, lpFindData);
  33.   if (hFindFile != INVALID_HANDLE_VALUE)
  34.   {
  35.     fFound = IsChildDir(lpFindData);
  36.     if (!fFound)
  37.       fFound = FindNextChildDir(hFindFile, lpFindData);
  38.     if (!fFound)
  39.     {
  40.       FindClose(hFindFile);
  41.       hFindFile = INVALID_HANDLE_VALUE;
  42.     }
  43.   }
  44.   return (hFindFile);
  45. }
  46. // To minimize stack use, one instance of the DIRWALKDATA structure is
  47. // created as a local variable in DirWalk.C, and a pointer to it is passed
  48. // to DirWalkRecurse()
  49. // Data Used by DirWalkRecurse
  50. typedef struct
  51. {
  52.   HWND hwndTreeLB;           // Handle to the output list box
  53.   int nDepth;                // Nesting depth
  54.   BOOL fRecurse;             // Set to TRUE to list subdirectories
  55.   TCHAR szBuf[1000];         // Output formatting buffer
  56.   int nIndent;               // Indentation character count
  57.   BOOL fOk;                  // Loop control flag
  58.   BOOL fIsDir;                // Loop control flag
  59.   WIN32_FIND_DATA FindData;   // File information
  60. } DIRWALKDATA, *LPDIRWALKDATA;
  61. // Walk the directory structure and fill a ListBox control with filenames.
  62. // If pDW->fRecurse is set, list any child directories by recursively calling
  63. // DirWalkRecurse.
  64. static void DirWalkRecurse (LPDIRWALKDATA pDW)
  65. {
  66.   HANDLE hFind;
  67.   pDW->nDepth++;
  68.   pDW->nIndent = 3 * pDW->nDepth;
  69.   _stprintf(pDW->szBuf, _TEXT("%*s"), pDW->nIndent, _TEXT(""));
  70.   GetCurrentDirectory(chDIMOF(pDW->szBuf) - pDW->nIndent, &pDW->szBuf[pDW->nIndent]);
  71.   ListBox_AddString(pDW->hwndTreeLB, pDW->szBuf);
  72.   hFind = FindFirstFile(_TEXT("*.*"), &pDW->FindData);
  73.   pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
  74.   while (pDW->fOk)
  75.   {
  76.     pDW->fIsDir = pDW->FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
  77.     if (!pDW->fIsDir || (!pDW->fRecurse && IsChildDir(&pDW->FindData)))
  78.     {
  79.       _stprintf(pDW->szBuf,
  80.         pDW->fIsDir ? _TEXT("%*s[%s]") : _TEXT("%*s%s"),
  81.         pDW->nIndent, _TEXT(""),
  82.         pDW->FindData.cFileName);
  83.       ListBox_AddString(pDW->hwndTreeLB, pDW->szBuf);
  84.     }
  85.     pDW->fOk = FindNextFile(hFind, &pDW->FindData);
  86.   }
  87.   if (hFind != INVALID_HANDLE_VALUE)
  88.     FindClose(hFind);
  89.   if (pDW->fRecurse)
  90.   {
  91.     // Get the first child directory
  92.     hFind = FindFirstChildDir(_TEXT("*.*"), &pDW->FindData);
  93.     pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
  94.     while (pDW->fOk)
  95.     {
  96.       // Change into the child directory
  97.       if (SetCurrentDirectory(pDW->FindData.cFileName))
  98.       {
  99.         // Perform the recursive walk into the child directory.
  100.         // Remember that some members of pDW will be overwritten by this call.
  101.         DirWalkRecurse(pDW);
  102.         // Change back to the child's parent directory.
  103.         SetCurrentDirectory(_TEXT(".."));
  104.       }
  105.       pDW->fOk = FindNextChildDir(hFind, &pDW->FindData);
  106.     }
  107.     if (hFind != INVALID_HANDLE_VALUE)
  108.       FindClose(hFind);
  109.   }
  110.   pDW->nDepth--;
  111. }
  112. // Walk the directory structure and fill a ListBox with filenames.
  113. // This function sets up a call to DirWalkRecurse, which does the real work.
  114. void DirWalk (
  115.               HWND hwndTreeLB,              // ListBox to fill
  116.               LPCTSTR pszRootPath,          // Starting point of the tree walk
  117.               BOOL fRecurse                 // Expand subdirectories
  118.               )
  119. {
  120.   TCHAR szCurrDir[_MAX_DIR];
  121.   DIRWALKDATA DW;                 // Create instance of DIRWALKDATA
  122.   // Clear the ListBox
  123.   ListBox_ResetContent(hwndTreeLB);
  124.   // Save the current directory so that it can be restored later.
  125.   GetCurrentDirectory(chDIMOF(szCurrDir), szCurrDir);
  126.   // Set the current directory to where you want to start walking
  127.   SetCurrentDirectory(pszRootPath);
  128.   // nDepth is used to control indenting. The value -1 will cause
  129.   // the first level to display flush left.
  130.   DW.nDepth = -1;
  131.   DW.hwndTreeLB = hwndTreeLB;
  132.   DW.fRecurse = fRecurse;
  133.   // Call the recursive function to walk the subdirectories.
  134.   DirWalkRecurse(&DW);
  135.  
  136.   // Restore the current directory to what it was before the function was called.
  137.   SetCurrentDirectory(szCurrDir);
  138. }
  139. BOOL Dlg_OnInitDialog (HWND hwnd, HWND hwndFocus, LPARAM lParam)
  140. {
  141.   RECT rc;
  142.   // Associate an icon with the dialog box.
  143.   chSETDLGICONS(hwnd, IDI_DIRWALK, IDI_DIRWALK);
  144.   DirWalk(GetDlgItem(hwnd, IDC_TREE), _TEXT("\"), TRUE);
  145.   GetClientRect(hwnd, &rc);
  146.   SetWindowPos(GetDlgItem(hwnd, IDC_TREE), NULL, 0, 0, rc.right, rc.bottom, SWP_NOZORDER);
  147.   return(TRUE);
  148. }
  149. void Dlg_OnSize (HWND hwnd, UINT state, int cx, int cy)
  150. {
  151.   SetWindowPos(GetDlgItem(hwnd, IDC_TREE), NULL, 0, 0, cx, cy, SWP_NOZORDER);
  152. }
  153. void Dlg_OnCommand (HWND hwnd, int id, HWND hwndCtl, UINT CodeNotify)
  154. {
  155.   switch (id)
  156.   {
  157.   case IDCANCEL:
  158.     EndDialog(hwnd, id);
  159.     break;
  160.   case IDOK:
  161.     // Call the recursive routine to walk the tree
  162.     DirWalk(GetDlgItem(hwnd, IDC_TREE), _TEXT("\"), TRUE);
  163.     break;
  164.   }
  165. }
  166. BOOL CALLBACK Dlg_Proc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  167. {
  168.   switch (uMsg)
  169.   {
  170.     chHANDLE_DLGMSG(hwnd, WM_INITDIALOG, Dlg_OnInitDialog);
  171.     chHANDLE_DLGMSG(hwnd, WM_SIZE, Dlg_OnSize);
  172.     chHANDLE_DLGMSG(hwnd, WM_COMMAND, Dlg_OnCommand);
  173.   }
  174.   return(FALSE);
  175. }
  176. int WINAPI WinMain(HINSTANCE hinstExe, HINSTANCE hinstPrev, LPSTR pszCmdLine, int nCmdShow)
  177. {
  178.   chWARNIFUNICODEUNDERWIN95();
  179.   DialogBox(hinstExe, MAKEINTRESOURCE(IDD_DIRWALK), NULL, Dlg_Proc);
  180.   return(0);
  181. }