An easy way to enumerate files is by using EnumDirTree(),
I used SHGetKnownFolderPath() to get the download-folder
I did use a listbox instead of a listview in the following demo.
Jose's include are used.
#COMPILE EXE '#Win 10.04 (D:\Dev\Pow\Bas\Jose Roca\Forum\Jose\Windows API Headers\3.1.07\uz)#
#DIM ALL
#REGISTER NONE
#INCLUDE "Win32Api.inc"
#INCLUDE "DbgHelp.inc"
#RESOURCE MANIFEST, 1, "xpTheme.xml"
GLOBAL hDlg AS DWORD
$AppName = "Enum download folder"
%Listbox = 101
'_____________________________________________________________________________
FUNCTION WinError$(BYVAL ErrorCode AS DWORD) AS STRING
LOCAL pzError AS STRINGZ POINTER 'Max is 64K
LOCAL ErrorLen AS DWORD
ErrorLen = FormatMessage(%FORMAT_MESSAGE_FROM_SYSTEM OR %FORMAT_MESSAGE_ALLOCATE_BUFFER, _
BYVAL %NULL, ErrorCode, %NULL, BYVAL VARPTR(pzError), %NULL, BYVAL %NULL)
IF ErrorLen THEN
FUNCTION = "Error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ") : " & @pzError
LocalFree(pzError)
ELSE
FUNCTION = "Unknown error" & STR$(ErrorCode) & " (0x" & HEX$(ErrorCode) & ")"
END IF
END FUNCTION
'_____________________________________________________________________________
FUNCTION GetKnownFolderPath(BYREF sKnownFolderId AS STRING) AS WSTRING
LOCAL pwPath AS WSTRINGZ POINTER
LOCAL sPath AS STRING
LOCAL RetVal AS DWORD
'SHGetKnownFolderPath https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-shgetknownfolderpath
RetVal = SHGetKnownFolderPath(BYVAL STRPTR(sKnownFolderId), %KF_FLAG_DEFAULT, %NULL, pwPath)
IF RetVal = %S_OK THEN
FUNCTION = @pwPath
CoTaskMemFree(pwPath)
ELSE
FUNCTION = "SHGetKnownFolderPath error! " & WinError$(RetVal)
END IF
END FUNCTION
'______________________________________________________________________________
FUNCTION EnumDirTreeCallBack(BYREF zFullPathFileName AS ASCIIZ, BYVAL pData AS STRING POINTER) AS LONG
STATIC LastBackSlashPos AS LONG
IF LastBackSlashPos = 0 THEN LastBackSlashPos = INSTR(-1, zFullPathFileName, "\")
LastBackSlashPos = INSTR(-1, zFullPathFileName, "\") 'To enum subdir
IF LastBackSlashPos = INSTR(-1, zFullPathFileName, "\") THEN 'Enum root
LISTBOX ADD hDlg, %Listbox, zFullPathFileName
@pData &= zFullPathFileName & $CRLF 'Another way to get CRLF separated file name in one string without using global variable.
ELSE
FUNCTION = %TRUE 'Stop enum
END IF
END FUNCTION
'______________________________________________________________________________
CALLBACK FUNCTION DlgProc
LOCAL zRootPath AS STRINGZ * %MAX_PATH
LOCAL zWhatToSearchFor AS STRINGZ * %MAX_PATH
LOCAL sData AS STRING
LOCAL sDownloadFolder AS STRING
LOCAL hProcess AS DWORD
LOCAL pData AS DWORD
SELECT CASE CBMSG
CASE %WM_INITDIALOG
sDownloadFolder = GetKnownFolderPath($FOLDERID_Downloads)
IF LEN(sDownloadFolder) = 0 THEN
zRootPath = CURDIR$ & "\"
ELSE
zRootPath = sDownloadFolder & "\"
END IF
zWhatToSearchFor = "*.txt"
SetWindowText(hDlg, $AppName & " - " & zRootPath & zWhatToSearchFor)
'EnumDirTree https://docs.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-enumdirtree
hProcess = OpenProcess(%PROCESS_QUERY_INFORMATION, 1, GetCurrentProcessId())
IF hProcess THEN
IF SymInitialize(hProcess, zRootPath, %TRUE) THEN
pData = VARPTR(sData) 'To get files in a single variable
EnumDirTree(hProcess, zRootPath, zWhatToSearchFor, BYVAL %NULL, CODEPTR(EnumDirTreeCallBack), pData)
MessageBox(hDlg, BYVAL STRPTR(sData), $AppName, %MB_OK OR %MB_TOPMOST)
END IF
CloseHandle(hProcess)
END IF
CASE %WM_SIZE
LOCAL ClientSizeX AS LONG
LOCAL ClientSizeY AS LONG
IF CBWPARAM <> %SIZE_MINIMIZED THEN
ClientSizeX = LO(WORD, CBLPARAM)
ClientSizeY = HI(WORD, CBLPARAM)
MoveWindow(GetDlgItem(hDlg, %Listbox), 10, 10, ClientSizeX - 20, ClientSizeY - 20, %TRUE)
END IF
END SELECT
END FUNCTION
'_____________________________________________________________________________
FUNCTION PBMAIN()
LOCAL hIcon AS DWORD
DIALOG FONT "Segoe UI", 9
DIALOG NEW %HWND_DESKTOP, $AppName, , , 300, 150, _
%WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_SIZEBOX OR %WS_SYSMENU, %WS_EX_LEFT TO hDlg
hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294) 'o
SetClassLong(hDlg, %GCL_HICON, hIcon)
SetClassLong(hDlg, %GCL_HICONSM, hIcon)
CONTROL ADD LISTBOX, hDlg, %Listbox, , 5, 5, 290, 140, %LBS_EXTENDEDSEL OR %LBS_MULTIPLESEL OR _
%LBS_NOINTEGRALHEIGHT OR %LBS_NOTIFY OR _
%LBS_SORT OR %WS_TABSTOP OR %WS_VSCROLL, _
%WS_EX_LEFT OR %WS_EX_STATICEDGE
DIALOG SHOW MODAL hDlg CALL DlgProc
DestroyIcon(hIcon)
END FUNCTION
'_____________________________________________________________________________
'