PlanetSquires Forums

Please login or register.

Login with username, password and session length
Advanced search  

Author Topic: PB question  (Read 463 times)

Petrus Vorster

  • Senior Member
  • ***
  • Posts: 480
PB question
« 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
Logged

Pierre Bellisle

  • Junior Member
  • **
  • Posts: 103
Re: PB question
« Reply #1 on: February 18, 2021, 02:19:56 AM »

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.

Code: [Select]
#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
'_____________________________________________________________________________
'
« Last Edit: February 18, 2021, 02:26:44 AM by Pierre Bellisle »
Logged

Nathan Durland

  • Junior Member
  • **
  • Posts: 84
Re: PB question
« Reply #2 on: February 18, 2021, 09:07:22 AM »

Perhaps the 'file find' sample program that came with PB/Win could be adapted for this?
Logged

Petrus Vorster

  • Senior Member
  • ***
  • Posts: 480
Re: PB question
« Reply #3 on: February 19, 2021, 08:36:09 AM »

Thanks mates, i resolved it.
Code: [Select]
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
Logged

raymw

  • Senior Member
  • ***
  • Posts: 415
Re: PB question
« Reply #4 on: February 20, 2021, 10:17:03 AM »

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/
Logged

Petrus Vorster

  • Senior Member
  • ***
  • Posts: 480
Re: PB question
« Reply #5 on: February 22, 2021, 02:30:03 PM »

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
Logged

Petrus Vorster

  • Senior Member
  • ***
  • Posts: 480
Re: PB question
« Reply #6 on: February 22, 2021, 02:43:02 PM »

Seems i can do this:

Replace $lf with "," in masterstring$

Seem to do the trick for now.

-Regards, Peter
Logged

raymw

  • Senior Member
  • ***
  • Posts: 415
Re: PB question
« Reply #7 on: February 22, 2021, 08:12:57 PM »

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
Logged

Petrus Vorster

  • Senior Member
  • ***
  • Posts: 480
Re: PB question
« Reply #8 on: February 23, 2021, 07:51:49 AM »

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
Logged

raymw

  • Senior Member
  • ***
  • Posts: 415
Re: PB question
« Reply #9 on: February 23, 2021, 09:13:16 AM »

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

Logged