Advanced Windows CD-ROM 中有一个例子,部分代码如下:
使用 FindFirstFile, FindNextFile 递归实现。如需要完整例子请留 Email。
static BOOL IsChildDir (WIN32_FIND_DATA *lpFindData) {
return(
((lpFindData->dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY) != 0) &&
(lstrcmp(lpFindData->cFileName, __TEXT(".")) != 0) &&
(lstrcmp(lpFindData->cFileName, __TEXT("..")) != 0));
}
/////////////////////////////////////////////////////////////
static BOOL FindNextChildDir (HANDLE hFindFile,
WIN32_FIND_DATA *lpFindData) {
BOOL fFound = FALSE;
do
{
fFound = FindNextFile(hFindFile, lpFindData);
} while (fFound &&
!IsChildDir(lpFindData));
return(fFound);
}
/////////////////////////////////////////////////////////////
static HANDLE FindFirstChildDir (LPTSTR szPath,
WIN32_FIND_DATA *lpFindData) {
BOOL fFound;
HANDLE hFindFile = FindFirstFile(szPath, lpFindData);
if (hFindFile != INVALID_HANDLE_VALUE) {
fFound = IsChildDir(lpFindData);
if (!fFound)
fFound = FindNextChildDir(hFindFile, lpFindData);
if (!fFound) {
FindClose(hFindFile);
hFindFile = INVALID_HANDLE_VALUE;
}
}
return(hFindFile);
}
/////////////////////////////////////////////////////////////
// To minimize stack use, one instance of the DIRWALKDATA
// structure is created as a local variable in DirWalk,
// and a pointer to it is passed to DirWalkRecurse.
// Data used by DirWalkRecurse
typedef struct {
HWND hwndTreeLB;
// Handle to the output list box
int nDepth;
// Nesting depth
BOOL fRecurse;
// Set to TRUE to list subdirectories.
TCHAR szBuf[1000];
// Output formatting buffer
int nIndent;
// Indentation character count
BOOL fOk;
// Loop control flag
BOOL fIsDir;
// Loop control flag
WIN32_FIND_DATA FindData;
// File information
} DIRWALKDATA, *LPDIRWALKDATA;
/////////////////////////////////////////////////////////////
// Walk the directory structure and fill a list box with
// filenames. If pDW->fRecurse is set, list any child
// directories by recursively calling DirWalkRecurse.
static void DirWalkRecurse (LPDIRWALKDATA pDW) {
HANDLE hFind;
pDW->nDepth++;
pDW->nIndent = 3 * pDW->nDepth;
_stprintf(pDW->szBuf, __TEXT("%*s"), pDW->nIndent,
__TEXT(""));
GetCurrentDirectory(chDIMOF(pDW->szBuf) - pDW->nIndent,
&pDW->szBuf[pDW->nIndent]);
ListBox_AddString(pDW->hwndTreeLB, pDW->szBuf);
hFind = FindFirstFile(__TEXT("*.*"), &pDW->FindData);
pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
while (pDW->fOk) {
pDW->fIsDir = pDW->FindData.dwFileAttributes &
FILE_ATTRIBUTE_DIRECTORY;
if (!pDW->fIsDir ||
(!pDW->fRecurse &&
IsChildDir(&pDW->FindData))) {
_stprintf(pDW->szBuf,
pDW->fIsDir ? __TEXT("%*s[%s]") : __TEXT("%*s%s"),
pDW->nIndent, __TEXT(""),
pDW->FindData.cFileName);
ListBox_AddString(pDW->hwndTreeLB, pDW->szBuf);
}
pDW->fOk = FindNextFile(hFind, &pDW->FindData);
}
if (hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
if (pDW->fRecurse) {
// Get the first child directory.
hFind = FindFirstChildDir(
__TEXT("*.*"), &pDW->FindData);
pDW->fOk = (hFind != INVALID_HANDLE_VALUE);
while (pDW->fOk) {
// Change into the child directory.
if (SetCurrentDirectory(pDW->FindData.cFileName)) {
// Perform the recursive walk into the child
// directory. Remember that some members of pDW
// will be overwritten by this call.
DirWalkRecurse(pDW);
// Change back to the child's parent directory.
SetCurrentDirectory(__TEXT(".."));
}
pDW->fOk = FindNextChildDir(hFind, &pDW->FindData);
}
if (hFind != INVALID_HANDLE_VALUE)
FindClose(hFind);
}
pDW->nDepth--;
}
/////////////////////////////////////////////////////////////
// Walk the directory structure and fill a list box with
// filenames. This function sets up a call to
// DirWalkRecurse, whichdo
es the real work.
void DirWalk (
HWND hwndTreeLB, // List box to fill
LPCTSTR pszRootPath, // Starting point of the tree walk
BOOL fRecurse) { // Expand subdirectories.
TCHAR szCurrDir[_MAX_DIR];
DIRWALKDATA DW;
// Clear out the list box.
ListBox_ResetContent(hwndTreeLB);
// Save the current directory so that it can
// be restored later.
GetCurrentDirectory(chDIMOF(szCurrDir), szCurrDir);
// Set the current directory to where we want
// to start walking.
SetCurrentDirectory(pszRootPath);
// nDepth is used to control indenting. The value -1 will
// cause the first level to display flush left.
DW.nDepth = -1;
DW.hwndTreeLB = hwndTreeLB;
DW.fRecurse = fRecurse;
// Call the recursive function to walk the subdirectories.
DirWalkRecurse(&DW);
// Restore the current directory to what it was
// before the function was called.
SetCurrentDirectory(szCurrDir);
}