typedef BOOL (CALLBACK* ENUMDIRPROC)
( LPCTSTR pszCurrentPath
, LPCTSTR pszTarget
, LPWIN32_FIND_DATA lpWinFindData
, LPVOID lpContext
, BOOL bIsChangedFolder );
typedef struct _ENUMDIRINFO
{
BOOL bNotifyDirChange;
TCHAR szRootDir[MAX_PATH];
TCHAR *szExtFilter;
DWORD dwItemCount;
LPVOID lpUserContext;
ENUMDIRPROC pCbFEnumProc;
_ENUMDIRINFO()
{
memset(this, 0, sizeof(*this));
}
} ENUMDIRINFO, *LPENUMDIRINFO;
BOOL WINAPI EnumDirectory(LPENUMDIRINFO pContext)
{
BOOL bRet = TRUE;
TCHAR szCurrentFolder[MAX_PATH];
TCHAR szFindFirstFile[MAX_PATH];
HANDLE hFindFirstFile = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA WinFindData;
if ( pContext == NULL )
return ERROR_INVALID_PARAMETER;
if ( pContext->szRootDir == NULL )
return ERROR_INVALID_PARAMETER;
StringCchCopy(szCurrentFolder, MAX_PATH, pContext->szRootDir);
if ( szCurrentFolder[_tcslen(szCurrentFolder)-1] != _T('\\') )
StringCchCat(szCurrentFolder, MAX_PATH, _T("\\"));
StringCchCopy(szFindFirstFile, MAX_PATH, szCurrentFolder);
StringCchCat(szFindFirstFile, MAX_PATH, _T("*.*"));
hFindFirstFile = FindFirstFile( szFindFirstFile, &WinFindData);
if ( hFindFirstFile != INVALID_HANDLE_VALUE )
{
if ( pContext->bNotifyDirChange )
{
if ( pContext->pCbFEnumProc != NULL )
{
bRet = pContext->pCbFEnumProc( szCurrentFolder, szCurrentFolder, &WinFindData, pContext->lpUserContext, TRUE );
if ( !bRet )
return FALSE;
}
}
do
{
if ( WinFindData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY )
{
if ( _tcscmp(WinFindData.cFileName, _T(".")) == 0 || _tcscmp(WinFindData.cFileName, _T("..")) == 0)
{
continue;
}
else
{
ENUMDIRINFO tfnf = *pContext;
tfnf.dwItemCount = 0;
StringCchPrintf(tfnf.szRootDir, MAX_PATH, _T("%s%s"), szCurrentFolder, WinFindData.cFileName);
bRet = EnumDirectory(&tfnf);
pContext->dwItemCount += tfnf.dwItemCount;
if ( !bRet )
break;
}
}
else
{
BOOL bBypass = FALSE;
if ( pContext->szExtFilter != NULL )
{
TCHAR szExt[MAX_PATH];
TCHAR szFilter[MAX_PATH];
TCHAR* pszExt = _tcsrchr(WinFindData.cFileName, _T('.'));
if ( pszExt++ != NULL )
{
StringCchCopy(szExt, MAX_PATH, pszExt);
StringCchCopy(szFilter, MAX_PATH, pContext->szExtFilter);
TCHAR* pszCurrentToken = szFilter;
TCHAR* pszDelimiter = _tcschr(pszCurrentToken, _T('|'));
size_t nSize = 0;
_tcslwr(szExt);
_tcslwr(szFilter);
if ( pszDelimiter == NULL )
{
if ( _tcscmp(szExt, szFilter) == 0 )
{}
else
continue;
}
else do
{
if ( pszDelimiter == NULL )
nSize = _tcslen(pszCurrentToken);
else
nSize = pszDelimiter - pszCurrentToken;
if ( _tcsncmp(pszCurrentToken, szExt, nSize) == 0 )
break;
if ( pszDelimiter == NULL )
{
bBypass = TRUE;
break;
}
else
{
pszCurrentToken = ++pszDelimiter;
pszDelimiter = _tcschr(pszCurrentToken, _T('|'));
}
} while ( TRUE );
}
else
continue;
}
if ( !bBypass )
{
TCHAR szFile[MAX_PATH];
StringCchPrintf(szFile, MAX_PATH, _T("%s%s"), szCurrentFolder, WinFindData.cFileName);
pContext->dwItemCount++;
if ( pContext->pCbFEnumProc != NULL )
{
bRet = pContext->pCbFEnumProc(szCurrentFolder, szFile , &WinFindData, pContext->lpUserContext, FALSE );
if ( !bRet )
break;
}
}
}
}
while ( FindNextFile(hFindFirstFile, &WinFindData) && bRet );
FindClose(hFindFirstFile);
return bRet;
}
else
{
// if enum failed (ex. access denied), print you want.
// printf("Enum Failed %S LE:%d\n", szFindFirstFile, GetLastError());
return TRUE;
}
}
예제
BOOL CALLBACK SampleFunction(LPCTSTR pszCurrentPath
, LPCTSTR pszTarget
, LPWIN32_FIND_DATA lpWinFindData
, LPVOID lpContext
, BOOL bIsChangedFolder )
{
if ( bIsChangedFolder )
printf("Changed Folder : %S\n", pszCurrentPath);
else
{
// printf("Enum FullPathFile : %S\n", pszTarget);
// printf("Enum FullPath : %S\n", pszCurrentPath);
printf("Enum File : %S\n", lpWinFindData->cFileName);
}
if ( 0 )
return FALSE; // if stop enum, return FALSE
else
return TRUE; // if continue enum, return TRUE
}
int _tmain(int argc, _TCHAR* argv[])
{
setlocale(LC_ALL, "korean");
ENUMDIRINFO m;
m.bNotifyDirChange = FALSE; // Not notify changes directories.
m.pCbFEnumProc = SampleFunction; // callback
m.lpUserContext = NULL; // user context addr
m.szExtFilter = _T("png|jpg|bmp"); // filtering extentions.
StringCchCopy(m.szRootDir, MAX_PATH, _T("C:\\")); // set root directory for enum
EnumDirectory(&m); // call!
printf("Total : %d\n", m.dwItemCount);
return 0;
}