PlanetSquires Forums
Support Forums => General Board => Topic started by: Petrus Vorster on February 17, 2021, 11:14:25 AM
-
Hi All
Is there anyone still willing to give some Powerbasic tips?
I am working on a small tool for someone and Pb is perfect for it.
(and i really haven't spend much time on Freebasic after the company disaster)
I want it to look in a specific folder (usually Downloads) for specific text files and list them in a listview control.
From there i got it covered.
The users are not very computer literate and I lose them on "go and search for the downloaded file..."
I just want to make it one-click-all-done little app.
Just cannot remember how to run that file search.
-If you are interested, let me know.
Regards, Peter
-
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
'_____________________________________________________________________________
'
-
Perhaps the 'file find' sample program that came with PB/Win could be adapted for this?
-
Thanks mates, i resolved it.
Local temp$, list$
Myfile$ = masterdir + "\*bio*.txt"
temp$ = Dir$(myfile$)
While Len(temp$)
FF_ListView_InsertItem(hwnd_form3_listview1,1,0,temp$)
temp$ = Dir$(Next)
Wend
Thanks' a million, i know most doesn't work on PB any more.
Regards, Peter
-
Hi Peter,
I know that this isn't what you meant, but I have used 'everything' for a number of years to find files. It works. https://www.voidtools.com/
-
Hi Guys
I use Everything too for finding files.
I am trying to make a tool to read an output file a biometric system writes to the download folder.
It outputs in TXT, but it has a header and "somewhat delimited" lines which gives me a headache.
I can remove the header and read the operating cost center from the file.
Every line consist of 6 entries, but the last entry is not delimited, which means Parse assumes the beginning of the next line as part of the first.
Its not fixed length which means i cannot just count characters.
I have attached an example here of such a file. (The supplier wont change the output files, so i have to make this work)
Still trying to figure out how i am going to add a delimiter for the next line.
Any ideas will be most welcome.
-Peter
-
Seems i can do this:
Replace $lf with "," in masterstring$
Seem to do the trick for now.
-Regards, Peter
-
Hi Peter, don't know if it is the same file, but end of lines show as cr/lf and each field separated by | . It looks pretty consistent to me, and I've read many such files by sort of manually parsing (in FB, not PB) . I'm not sure why it is difficult to get the data. Basically, read it a line at a time and use a few string functions to split it into the fields, searching on the |. Then save it however you like. I think it would also be possible, if only a one off file conversion that you have to do, then a search and replace in Notepad++, or other text editor, if you wanted comma separated. If there are a few files that others need to process, then notepad++ may be too dangerous for them ;-).
Anyway, you've done it now, so that's OK.
Best wishes,
Ray
-
Hi
I resolved it eventually.
I just used Shrink$, removed any Line feeds, replaced them all with a comma and the parsing went smooth from there.
Opening an Excel file from there went smooth as well.
Now the only remaining thing is to test the outputs with previous reports i manually uploaded into Excel for accuracy.
There is ZERO place here for a mistake.
Maybe i just like to chat with you guys once in a while. :-)
I find that AFTER i post for help, drank strong coffee, then most of the time i figure it out.
Nice hearing from you all.
-Peter
-
Hi Peter,
Chat is OK. If I was using fb as much as i was a year or to ago, I'd have knocked out a few lines of code to parse your file, but, I'd have to correct my syntax errors, check whether it was instr or mid/whatever, and before long it would be next Christmas, and it wouldn't be any use to you. What is needed is one standard programming language. comments with either ' or //, and ending lines with ; or not, and as for white spaces... No chance or course, they can't even agree on a standard mobile phone charging socket. :D