procedure dirtree
PARAMETERS cDir,cExt
DO declare
LOCAL loDir
loDir = CreateObject("Tdir", cDir)
GO TOP
browse
***Code to do whatever you want with the files
DEFINE CLASS Tdir As Custom
cursorname=""
treelevel=0
cExt=UPPER(Cext)
PROCEDURE Init(lcPath, loParent)
IF TYPE("loParent")="O"
THIS.cursorname = loParent.cursorname
THIS.treelevel = loParent.treelevel + 1
ELSE
THIS.cursorname = "cs" + SUBSTR(SYS(2015), 3,10)
SELECT 0
CREATE CURSOR (THIS.cursorname) (treelevel N(3),;
filesize N(12), date D, fullname C(250))
ENDIF
THIS.DoFind(lcPath)
PROCEDURE DoFind(lcPath)
#DEFINE MAX_PATH 260
#DEFINE FILE_ATTRIBUTE_DIRECTORY 16
#DEFINE INVALID_HANDLE_VALUE -1
#DEFINE MAX_DWORD 0xffffffff+1
#DEFINE FIND_DATA_SIZE 318
lcPath = ALLTRIM(lcPath)
IF Right(lcPath,1) <> "\"
lcPath = lcPath + "\"
ENDIF
LOCAL hFind, cFindBuffer, lnAttr, cFilename, nFileCount,;
nDirCount, nFileSize, cWriteTime, nLatestWriteTime, oNext
cFindBuffer = Repli(Chr(0), FIND_DATA_SIZE)
hFind = FindFirstFile(lcPath + "*.*", @cFindBuffer)
IF hFind = INVALID_HANDLE_VALUE
RETURN
ENDIF
STORE 0 TO nDirCount, nFileCount, nFileSize, nLatestWriteTime
DO WHILE .T.
lnAttr = buf2dword(SUBSTR(cFindBuffer, 1,4))
cFilename = SUBSTR(cFindBuffer, 45,MAX_PATH)
cFilename = Left(cFilename, AT(Chr(0),cFilename)-1)
cWriteTime = SUBSTR(cFindBuffer, 21,8)
IF EMPTY(nLatestWriteTime)
nLatestWriteTime = cWriteTime
ELSE
IF CompareFileTime(cWriteTime, nLatestWriteTime) = 1
nLatestWriteTime = cWriteTime
ENDIF
ENDIF
IF BITAND(lnAttr, FILE_ATTRIBUTE_DIRECTORY) = FILE_ATTRIBUTE_DIRECTORY
* for a directory
IF Not LEFT(cFilename,1)="."
oNext = CreateObject("Tdir", lcPath + cFilename + "\", THIS)
ENDIF
ELSE
* for a regular file
IF LIKE(cExt,cFilename)
nFileSize = nFileSize +;
buf2dword(SUBSTR(cFindBuffer, 29,4)) * MAX_DWORD +;
buf2dword(SUBSTR(cFindBuffer, 33,4))
ntime=sys2dt(nLatestWriteTime)
INSERT INTO (THIS.cursorname) VALUES (THIS.treelevel,;
m.nFileSize,m.ntime,lcPath+cFileName)
endif
ENDIF
IF FindNextFile(hFind, @cFindBuffer) = 0
EXIT
ENDIF
ENDDO
= FindClose(hFind)
ENDDEFINE
FUNCTION sys2dt(lcFiletime)
* converts a SYSTEMTIME buffer to DATE
LOCAL lcSystime, lcStoredSet, lcDate, lcTime, ltResult,;
lnYear, lnMonth, lnDay, lnHours, lnMinutes, lnSeconds
lcSystime = Repli(Chr(0), 16)
= FileTimeToSystemTime(lcFiletime, @lcSystime)
lnYear = buf2word(SUBSTR(lcSystime, 1,2))
lnMonth = buf2word(SUBSTR(lcSystime, 3,2))
lnDay = buf2word(SUBSTR(lcSystime, 7,2))
lnHours = buf2word(SUBSTR(lcSystime, 9,2))
lnMinutes = buf2word(SUBSTR(lcSystime, 11,2))
lnSeconds = buf2word(SUBSTR(lcSystime, 13,2))
lcStoredSet = SET("DATE")
lcStoredSet1 = SET('STRICTDATE')
SET DATE TO MDY
SET STRICTDATE TO 0
lcDate = STRTRAN(STR(lnMonth,2) + "/" + STR(lnDay,2) +;
"/" + STR(lnYear,4), " ","0")
ltresult=CTOT(lcdate)
SET DATE TO &lcStoredSet
SET STRICTDATE TO &lcStoredset1
RETURN ltResult
FUNCTION buf2word(lcBuffer)
RETURN Asc(SUBSTR(lcBuffer, 1,1)) +;
Asc(SUBSTR(lcBuffer, 2,1)) * 256
FUNCTION buf2dword(lcBuffer)
RETURN Asc(SUBSTR(lcBuffer, 1,1)) +;
Asc(SUBSTR(lcBuffer, 2,1)) * 256 +;
Asc(SUBSTR(lcBuffer, 3,1)) * 65536 +;
Asc(SUBSTR(lcBuffer, 4,1)) * 16777216
PROCEDURE declare
DECLARE INTEGER FindClose IN kernel32 INTEGER hFindFile
DECLARE INTEGER FindFirstFile IN kernel32;
STRING lpFileName, STRING @lpFindFileData
DECLARE INTEGER FindNextFile IN kernel32;
INTEGER hFindFile, STRING @lpFindFileData
DECLARE INTEGER FileTimeToSystemTime IN kernel32;
STRING lpFileTime, STRING @lpSystemTime
DECLARE INTEGER CompareFileTime IN kernel32;
STRING lpFileTime1, STRING lpFileTime2