Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

FindFirstFile, FindNextFile and FindClose

137 views
Skip to first unread message

dus...@012.net.il

unread,
Jan 14, 2003, 4:14:34 AM1/14/03
to
Hello,
I am trying to navigate folders and add all the files of certain
type into a list control.
I've written the following code and tested it on a sample folder,
which had several files under it + 2 subfolders with files too.
When I tried it with 0 or 1 subfolders it worked well, but when I
added the second subfolder, it didn't count it.

I am working with VC++ 6 and on WinXP.

Does anyone can help me???
Thanks a lot.

--------------------------------------------------------

SetCurrentDirectory("C:\\stam");
ExploreDir();

void CSomeClass::ExploreDir()
{
WIN32_FIND_DATA fd; HANDLE hDir;

hDir=FindFirstFile("*.*",&fd);

if(hDir==INVALID_HANDLE_VALUE) // check if
return;

do
{
//if next file is a directory:
if((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
!(fd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
{
if(!(strcmp(fd.cFileName , ".") == 0 || (strcmp(fd.cFileName ,
"..") == 0)))
{
SetCurrentDirectory(fd.cFileName);
memset(&fd, 0, sizeof(fd));
ExploreDir();
}
}
else//if next file is a file:
{
for(int tp = 0; tp < sizeof(file_types)/sizeof(char*); tp++)
if(strstr(fd.cFileName, file_types[tp]))
m_pFilesList->InsertItem(tp, fd.cFileName, tp);
}
}while(FindNextFile(hDir,&fd)==TRUE);

FindClose(hDir);
return; // close handle and return
}

Jugoslav Dujic

unread,
Jan 14, 2003, 5:19:31 AM1/14/03
to
<dus...@012.net.il> wrote in message
news:faecfce7.03011...@posting.google.com...

I didn't analyse your code very carefully, but SetCurrentDirectory
here is toying with fire and I'd bet it is the culprit. You should
pass directory name as a char* and use full paths throughout.

For the reference of logic, here's a tested & working code, in an,
um, strange language (for easier reading: // is concatenation
operator (strcat), ignore TRIM, C2F, CHAR(0), /= is !=,
m_bInterrupted, lParam & bRecursive are not significant for your use) :

!======================================================================
!XEnumFiles passes all files which satisfy given filter-spec to user-
!-defined function fnCallback. It can recursively traverse subdirectories.
RECURSIVE INTEGER FUNCTION XEnumFiles(sDir, sFilter, fnCallback, &
bRecursive, lParam) RESULT (nFiles)

USE XSTRINGS

CHARACTER(*),INTENT(IN):: sDir
CHARACTER(*),INTENT(IN):: sFilter
INTERFACE
LOGICAL FUNCTION fnCallback(sFile, lParam)
CHARACTER(*),INTENT(IN):: sFile
INTEGER:: lParam
END FUNCTION fnCallback
END INTERFACE
LOGICAL, OPTIONAL, INTENT(IN):: bRecursive
INTEGER, OPTIONAL, INTENT(IN):: lParam

CHARACTER(MAX_PATH):: sSubDir
TYPE (T_WIN32_FIND_DATA):: WFDdir, WFDfile
INTEGER:: iSt, &
hFindDir, & !For traversing subdirectories
hFindFile, & !For traversing this directory
lcParam
LOGICAL:: bFoundDir, &
bFoundFile

nFiles = 0

m_bInterrupted = .FALSE.

IF (PRESENT(lParam)) THEN
lcParam = lParam
ELSE
lcParam = 0
END IF

IF (PRESENT(bRecursive)) THEN
IF (bRecursive) THEN
hFindDir = FindFirstFile(TRIM(sDir)//"\\*.*"C, WFDdir)
bFoundDir = .TRUE.
DO WHILE (hFindDir/=INVALID_HANDLE_VALUE .AND. bFoundDir)
IF (IAND(WFDdir%dwFileAttributes, FILE_ATTRIBUTE_DIRECTORY)/=0 .AND. &
WFDdir%cFileName(1:1)/=".") THEN

sSubDir = TRIM(sDir)//"\"//C2F(WFDdir%cFileName)
nFiles = nFiles + XEnumFiles(sSubDir, sFilter, fnCallback,
bRecursive)
IF (m_bInterrupted) RETURN
END IF
bFoundDir = FindNextFile(hFindDir, WFDdir)
END DO
iSt = FindClose(hFindDir)
END IF
END IF

bFoundFile=.TRUE.
!Now search for files in this directory
hFindFile = FindFirstFile(TRIM(sDir)//"\"//sFilter//CHAR(0), WFDfile)
DO WHILE (hFindFile/=INVALID_HANDLE_VALUE .AND. bFoundFile)
nFiles = nFiles + 1
sSubDir = TRIM(sDir)//"\"//C2F(WFDfile%cFileName)
m_bInterrupted = fnCallback(sSubDir, lcParam)
IF (m_bInterrupted) THEN
iSt = FindClose(hFindFile)
RETURN
END IF
bFoundFile = FindNextFile(hFindFile, WFDfile)
END DO
iSt = FindClose(hFindFile)

END FUNCTION XEnumFiles

--
Jugoslav
___________
www.geocities.com/jdujic


Stephen Kellett

unread,
Jan 14, 2003, 5:21:17 AM1/14/03
to
In message <faecfce7.03011...@posting.google.com>,
dus...@012.net.il writes

>Hello,
> I am trying to navigate folders and add all the files of certain
>type into a list control.
> I've written the following code and tested it on a sample folder,
>which had several files under it + 2 subfolders with files too.
> When I tried it with 0 or 1 subfolders it worked well, but when I
>added the second subfolder, it didn't count it.

Hardly surprising:

Parent
Child1
Child2

Your algorithm goes Parent->Child1 ->(no more children)

You have not added any code for stepping back out of Child1.

A better way (in my opinion) is to make the function recursive, so that
when you find a directory, you pass the path to the directory to the
function. That way you never call SetCurrentDirectory, and you get
directory traversing for free. Roughly something like below.

void recursive(LPCTSTR dir)
{
CString path;

path = dir
path += _T("\\*.*")

FindFirstFile()
do
{
if (dir)
{
if (. or ..)
// ignore
else
{
// child directory

recursive(dir + name of child dir);
}
}
else
{
// check file type and do something with file
}
} while(FindNextFile)

FindClose
}

--
Stephen Kellett http://www.objmedia.demon.co.uk
Object Media Limited C++/Java/Windows NT/Unix/X Windows/Multimedia
If you are suffering from RSI, contact me for advice.
Unsolicited email from spam merchants not welcome.

dus...@012.net.il

unread,
Jan 14, 2003, 2:50:43 PM1/14/03
to
Stephan & Jugoslav!
Thank you for your kind help.
It did help me.
0 new messages