Author Topic: How to load system fileselector  (Read 4725 times)

0 Members and 1 Guest are viewing this topic.

Offline cfalcon030

  • Newbie
  • Posts: 6
    • View Profile
How to load system fileselector
« on: December 07, 2021, 12:27:12 pm »
Hello,
I am new here and a fan of BASIC trying to assess qb64 /inform for my project. My program needs to do three things.

Get a file path from the system.
Get a directory path from the system.
Execute an external command based on program logic.

I understand that the third part can be done using the SHELL command, I just haven't found anything for the first part. I can't find a way to load the system fileselector.

Is that possible?

Alternatively, I saw that inform produced a fileselector. Is that callable somehow (I know I am not in the right subforum for that so I apologize in advance)

Offline SpriggsySpriggs

  • Forum Resident
  • Posts: 1145
  • Larger than life
    • View Profile
    • GitHub
Re: How to load system fileselector
« Reply #1 on: December 07, 2021, 12:31:04 pm »
I do not remember if this is my latest code (my PC is in the shop for repairs) but here is some Windows code for the Open/Save As dialogs. If I find code that is more updated then I will reply with it.

Code: QB64: [Select]
  1.  
  2. '$Let UNICODE = TRUE
  3. $If UNICODE = DEFINED Then
  4.     Const MAX_PATH = 65534 'Since the MAX_PATH for unicode is 32767 and it is a wide string, two bytes are needed per character. So, double the length
  5.     Const MODE = "Unicode"
  6.     Const MAX_PATH = 260
  7.     Const MODE = "ANSI"
  8.  
  9. $ExeIcon:'.\internal\source\qb64.ico'
  10.  
  11. _ConsoleTitle "Comdlg32 Open/Save Dialog (32/64) Test - " + MODE
  12.  
  13. Const OFN_ALLOWMULTISELECT = &H00000200
  14. Const OFN_CREATEPROMPT = &H00002000
  15. Const OFN_DONTADDTORECENT = &H02000000
  16. Const OFN_EXPLORER = &H00080000
  17. Const OFN_EXTENSIONDIFFERENT = &H00000400
  18. Const OFN_FILEMUSTEXIST = &H00001000
  19. Const OFN_FORCESHOWHIDDEN = &H10000000
  20. Const OFN_HIDEREADONLY = &H00000004
  21. Const OFN_NOCHANGEDIR = &H00000008
  22. Const OFN_NODEREFERENCELINKS = &H00100000
  23. Const OFN_NONETWORKBUTTON = &H00020000
  24. Const OFN_NOREADONLYRETURN = &H00008000
  25. Const OFN_NOTESTFILECREATE = &H00010000
  26. Const OFN_NOVALIDATE = &H00000100
  27. Const OFN_OVERWRITEPROMPT = &H00000002
  28. Const OFN_PATHMUSTEXIST = &H00000800
  29. Const OFN_READONLY = &H00000001
  30. Const OFN_SHAREAWARE = &H00004000
  31. Const OFN_SHOWHELP = &H00000010
  32. Const SAVE_DIALOG = &H01000000
  33. Const OPEN_DIALOG = &H02000000
  34.  
  35.  
  36. file = ComDlgFileName("Open Source File", _CWD$, "QB64 Files (*.BAS, *.BI, *.BM, *.FRM)|*.BAS;*.BI;*.BM;*.FRM|C/C++ Files (*.CPP, *.HPP, *.H, *.C)|*.CPP;*.HPP;*.H;*.C|All Files|*.*", OFN_FORCESHOWHIDDEN)
  37. If file <> "" Then
  38.     Print file
  39.     Open file For Binary Access Read As #1
  40.     Dim As String content: content = Space$(LOF(1))
  41.     Get #1, , content
  42.     Close
  43.     Print content
  44.     Dim As String filename: filename = Mid$(file, _InStrRev(file, "\") + 1)
  45.     _ConsoleTitle "Viewing - " + filename
  46.  
  47. 'Print SelectFolder("Pick a folder")
  48.  
  49. Function ComDlgFileName$ (Title As String, InitialDir As String, Filter As String, Flags As _Unsigned Long)
  50.     Type OPENFILENAME
  51.         As _Unsigned Long lStructSize
  52.         $If 64BIT Then
  53.             As String * 4 padding
  54.         $End If
  55.         As _Offset hwndOwner, hInstance, lpstrFilter, lpstrCustomFilter
  56.         As _Unsigned Long nMaxCustFilter, nFilterIndex
  57.         As _Offset lpstrFile
  58.         As _Unsigned Long nMaxFile
  59.         $If 64BIT Then
  60.             As String * 4 padding2
  61.         $End If
  62.         As _Offset lpstrFileTitle
  63.         As _Unsigned Long nMaxFileTitle
  64.         $If 64BIT Then
  65.             As String * 4 padding3
  66.         $End If
  67.         As _Offset lpstrInitialDir, lpstrTitle
  68.         As _Unsigned Long Flags
  69.         As Integer nFileOffset, nFileExtension
  70.         As _Offset lpstrDefExt, lCustData, lpfnHook, lpTemplateName, pvReserved
  71.         As _Unsigned Long dwReserved, FlagsEx
  72.     End Type
  73.  
  74.     Declare Dynamic Library "Comdlg32"
  75.         $If UNICODE = DEFINED Then
  76.         Sub GetSaveFileName Alias "GetSaveFileNameW" (ByVal ofn As _Offset)
  77.         Function GetOpenFileName& Alias "GetOpenFileNameW" (ByVal ofn As _Offset)
  78.         $Else
  79.             Sub GetSaveFileName Alias "GetSaveFileNameA" (ByVal ofn As _Offset)
  80.             Function GetOpenFileName& Alias "GetOpenFileNameA" (ByVal ofn As _Offset)
  81.         $End If
  82.     End Declare
  83.  
  84.     $If UNICODE = DEFINED Then
  85.         Function wcslen%& (ByVal str As _Offset)
  86.         End Declare
  87.     $Else
  88.         $If 64BIT Then
  89.             Declare CustomType Library ".\internal\c\c_compiler\x86_64-w64-mingw32\include\tchar"
  90.                 Function tcslen%& Alias "_tcslen" (ByVal str As _Offset)
  91.             End Declare
  92.         $Else
  93.             Declare CustomType Library ".\internal\c\c_compiler\i686-w64-mingw32\include\tchar"
  94.             Function tcslen%& Alias "_tcslen" (ByVal str As _Offset)
  95.             End Declare
  96.         $End If
  97.     $End If
  98.  
  99.     Dim As OPENFILENAME ofn
  100.     Do
  101.         Mid$(Filter, InStr(Filter, "|")) = Chr$(0)
  102.     Loop While InStr(Filter, "|")
  103.  
  104.     $If UNICODE = DEFINED Then
  105.         Title = ANSIToUnicode(Title + Chr$(0))
  106.         InitialDir = ANSIToUnicode(InitialDir + Chr$(0))
  107.         Filter = ANSIToUnicode(Filter + Chr$(0) + Chr$(0))
  108.     $Else
  109.         Title = Title + Chr$(0)
  110.         InitialDir = InitialDir + Chr$(0)
  111.         Filter = Filter + Chr$(0) + Chr$(0)
  112.     $End If
  113.     Dim As String * MAX_PATH oFile
  114.     ofn.lStructSize = Len(ofn)
  115.     ofn.hwndOwner = _WindowHandle
  116.     ofn.lpstrFilter = _Offset(Filter)
  117.     ofn.nFilterIndex = 1
  118.     ofn.nMaxFile = Len(oFile)
  119.     ofn.lpstrFileTitle = ofn.lpstrFile
  120.     ofn.nMaxFileTitle = ofn.nMaxFile
  121.     ofn.lpstrInitialDir = _Offset(InitialDir)
  122.     ofn.lpstrTitle = _Offset(Title)
  123.     ofn.lpstrFile = _Offset(oFile)
  124.     If OPEN_DIALOG And Flags Or (SAVE_DIALOG And Flags) = 0 Then
  125.         If OFN_ALLOWMULTISELECT And Flags Then Flags = Flags Or OFN_EXPLORER
  126.         ofn.Flags = Flags
  127.         If GetOpenFileName(_Offset(ofn)) <> 0 Then
  128.             If OFN_ALLOWMULTISELECT And Flags Then
  129.                 Dim As String file, outfiles, directory
  130.                 $If UNICODE = DEFINED Then
  131.                     Dim As _Offset tmp: tmp = ofn.lpstrFile + (ofn.nFileOffset * 2)
  132.                     Dim As _MEM pFiles: pFiles = _Mem(tmp, wcslen(tmp) * 2)
  133.                     Dim As _MEM dir: dir = _Mem(ofn.lpstrFile, wcslen(ofn.lpstrFile) * 2)
  134.                     directory = Space$(wcslen(ofn.lpstrFile) * 2)
  135.                 $Else
  136.                     Dim As _Offset tmp: tmp = ofn.lpstrFile + ofn.nFileOffset
  137.                     Dim As _MEM pFiles: pFiles = _Mem(tmp, tcslen(tmp))
  138.                     Dim As _MEM dir: dir = _Mem(ofn.lpstrFile, tcslen(ofn.lpstrFile))
  139.                     directory = Space$(tcslen(ofn.lpstrFile))
  140.                 $End If
  141.                 _MemGet dir, dir.OFFSET, directory
  142.                 _MemFree dir
  143.                 Dim As Long i
  144.                 $If UNICODE = DEFINED Then
  145.                     While wcslen(tmp)
  146.                     file = Space$(wcslen(tmp) * 2)
  147.                     _MemGet pFiles, pFiles.OFFSET, file
  148.                     Select Case i
  149.                     Case 0
  150.                     outfiles = directory + ANSIToUnicode("\") + file
  151.                     Case Else
  152.                     outfiles = outfiles + ANSIToUnicode("|") + directory + ANSIToUnicode("\") + file
  153.                     End Select
  154.                     i = i + 1
  155.                     tmp = tmp + Len(file) + 2
  156.                     pFiles = _Mem(tmp, wcslen(tmp) * 2)
  157.                     Wend
  158.                 $Else
  159.                     While tcslen(tmp)
  160.                         file = Space$(tcslen(tmp))
  161.                         _MemGet pFiles, pFiles.OFFSET, file
  162.                         Select Case i
  163.                             Case 0
  164.                                 outfiles = directory + "\" + file
  165.                             Case Else
  166.                                 outfiles = outfiles + "|" + directory + "\" + file
  167.                         End Select
  168.                         i = i + 1
  169.                         tmp = tmp + (tcslen(tmp) + 1)
  170.                         pFiles = _Mem(tmp, tcslen(tmp))
  171.                     Wend
  172.                 $End If
  173.                 _MemFree pFiles
  174.                 If i = 1 Then
  175.                     $If UNICODE = DEFINED Then
  176.                         file = wCharPtrToString(_Offset(directory))
  177.                     $Else
  178.                         file = directory
  179.                     $End If
  180.                     ComDlgFileName = file
  181.                 Else
  182.                     $If UNICODE = DEFINED Then
  183.                         outfiles = wCharPtrToString(_Offset(outfiles))
  184.                     $End If
  185.                     ComDlgFileName = outfiles
  186.                 End If
  187.             Else
  188.                 $If UNICODE = DEFINED Then
  189.                     Dim As String selectedfile: selectedfile = wCharPtrToString(_Offset(oFile))
  190.                     ComDlgFileName = selectedfile
  191.                 $Else
  192.                     ComDlgFileName = Mid$(oFile, 1, InStr(oFile, Chr$(0)) - 1)
  193.                 $End If
  194.             End If
  195.         End If
  196.     ElseIf SAVE_DIALOG And Flags Then
  197.         ofn.Flags = Flags
  198.         GetSaveFileName _Offset(ofn)
  199.         $If UNICODE = DEFINED Then
  200.             selectedfile = wCharPtrToString(_Offset(oFile))
  201.             ComDlgFileName = selectedfile
  202.         $Else
  203.             ComDlgFileName = Mid$(oFile, 1, InStr(oFile, Chr$(0)) - 1)
  204.         $End If
  205.     End If
  206.  
  207. Function SelectFolder$ (title As String)
  208.     Type BROWSEINFO
  209.         As _Offset hwndOwner, pidlRoot, pszDisplayName, lpszTitle
  210.         As _Unsigned Long ulFlags
  211.         As _Offset lpfn, lParam
  212.         As Long iImage
  213.     End Type
  214.     Declare Dynamic Library "Shell32"
  215.         $If UNICODE = DEFINED Then
  216.         Function SHBrowseForFolder%& Alias "SHBrowseForFolderW" (ByVal lpbi As _Offset)
  217.         Function SHGetPathFromIDList%% Alias "SHGetPathFromIDListW" (ByVal lpItem As _Offset, Byval szDir As _Offset)
  218.         $Else
  219.             Function SHBrowseForFolder%& (ByVal lpbi As _Offset)
  220.             Function SHGetPathFromIDList%% (ByVal lpItem As _Offset, Byval szDir As _Offset)
  221.         $End If
  222.     End Declare
  223.     Dim As BROWSEINFO browse
  224.     Dim As String * MAX_PATH folder
  225.     $If UNICODE = DEFINED Then
  226.         title = ANSIToUnicode(title + Chr$(0))
  227.     $Else
  228.         title = title + Chr$(0)
  229.     $End If
  230.     browse.hwndOwner = _WindowHandle
  231.     browse.pszDisplayName = _Offset(folder)
  232.     browse.lpszTitle = _Offset(title)
  233.     Dim As _Offset pfolder
  234.     pfolder = SHBrowseForFolder(_Offset(browse))
  235.     If pfolder Then
  236.         Dim As String * MAX_PATH resolvedPath
  237.         If SHGetPathFromIDList(pfolder, _Offset(resolvedPath)) Then
  238.             $If UNICODE = DEFINED Then
  239.                 SelectFolder = wCharPtrToString(_Offset(resolvedPath))
  240.             $Else
  241.                 SelectFolder = Mid$(resolvedPath, 1, InStr(resolvedPath, Chr$(0)) - 1)
  242.             $End If
  243.         End If
  244.     End If
  245.  
  246. $If UNICODE = DEFINED Then
  247.     Function wCharPtrToString$ (wchar As _Offset)
  248.     Dim As _Offset wlen: wlen = wcslen(wchar) * 2 'The length does not account for the 2-byte nature of Unicode so we multiply by 2
  249.     Dim As _MEM pChar: pChar = _Mem(wchar, wlen) 'Declaring a new _MEM block and setting it to grab the number of bytes referenced by wlen at pointer wchar
  250.     Dim As String char: char = Space$(wlen) 'Declaring a new string large enough to hold the unicode string
  251.     _MemGet pChar, pChar.OFFSET, char 'Storing the data in the string
  252.     _MemFree pChar 'Freeing the _MEM block
  253.     wCharPtrToString = UnicodeToANSI(char) 'Returning the converted Unicode string
  254.  
  255.     '$INCLUDE:'unicodetoansi.bas'
Shuwatch!

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: How to load system fileselector
« Reply #2 on: December 07, 2021, 12:35:48 pm »
Code: QB64: [Select]
  1. pwd$ = _STARTDIR$

That get's the starting directory of the binary.

There is also a CWD$ variable, that usually starts in the directory the binary was executed from.

Here is some sample code from the _CWD$ Wiki (http://www.qb64.org/wiki/CWD$)
Code: QB64: [Select]
  1. startdir$ = _CWD$
  2. PRINT "We started at "; startdir$
  3. MKDIR "a_temporary_dir"
  4. CHDIR "a_temporary_dir"
  5. PRINT "We are now in "; _CWD$
  6. CHDIR startdir$
  7. PRINT "And now we're back in "; _CWD$
  8. RMDIR "a_temporary_dir"

If you look at the Wiki page, you'll find at the bottom most if not all the statements that deal with directories in QB64
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How to load system fileselector
« Reply #3 on: December 07, 2021, 12:43:51 pm »
Command$(0) will give you exe and path.

Offline cfalcon030

  • Newbie
  • Posts: 6
    • View Profile
Re: How to load system fileselector
« Reply #4 on: December 07, 2021, 01:14:36 pm »
That was amazingly fast. Thank you.

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: How to load system fileselector
« Reply #5 on: December 07, 2021, 01:25:51 pm »
@bplus, I'm using that in a series of programs that I call, and it only returns the program name, without the directory it was executed from.

You you have an example of how it returns the path? Because if it does do that in some cases, I need to code for that in this application I've been working on since August!

Thanks.

Command$(0) will give you exe and path.
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How to load system fileselector
« Reply #6 on: December 07, 2021, 02:12:23 pm »
Hi George,

Command$(0) gives me a fully pathed .exe name of the running QB64 program. If you find the last slash you can divide the string into path and file name on Windows systems at least. But _CWD$ might give you the path string without the string manipulations.

Offline George McGinn

  • Global Moderator
  • Forum Regular
  • Posts: 210
    • View Profile
    • Resume
Re: How to load system fileselector
« Reply #7 on: December 07, 2021, 05:36:51 pm »
I see what's going on. Since I have been testing code either in the IDE or executing it directly from the directory via a terminal, all I got was ./ProgramName.

When I click on and execute the binary from the Files (like Windows File Manager) or from a terminal session that isn't in the directory the binary is in, I do see the path.

I can add the INSTRREV statement to get just the program name like:
Code: QB64: [Select]
  1. file$ = MID$(fullPath$, _INSTRREV(fullPath$, "/") + 1) '*** For Windows, I'll do this with \ instead

That will return to me just the program name.

Thanks

Hi George,

Command$(0) gives me a fully pathed .exe name of the running QB64 program. If you find the last slash you can divide the string into path and file name on Windows systems at least. But _CWD$ might give you the path string without the string manipulations.
____________________________________________________________________
George McGinn
Theoretical/Applied Computer Scientist
Member: IEEE, IEEE Computer Society
Technical Council on Software Engineering
IEEE Standards Association
American Association for the Advancement of Science (AAAS)

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How to load system fileselector
« Reply #8 on: December 08, 2021, 11:08:57 am »
@cfalcon030

Are you talking about a File/Folder navigator like Windows File Explorer?

I setup one in both InForm version and regular QB64 with my own GUI for reading and grabbing text out of files. If interested, try search for Text Fetch by yours truly.

Offline cfalcon030

  • Newbie
  • Posts: 6
    • View Profile
Re: How to load system fileselector
« Reply #9 on: December 08, 2021, 11:27:04 am »
@bplus exactly, I will look into it for sure.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How to load system fileselector
« Reply #10 on: December 08, 2021, 11:34:03 am »
Windows only, like the InForm version, I wasn't attempting cross platform file access then. (Probably a waste of time without another OS to test yourself.)
https://www.qb64.org/forum/index.php?topic=1876.msg111064#msg111064

My nascent GUI might be tough to follow, hell it's probably god awful. :)

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: How to load system fileselector
« Reply #11 on: December 08, 2021, 11:34:53 am »
Code: QB64: [Select]
  1.     FUNCTION FILE_load_dir& ALIAS load_dir (s AS STRING)
  2.     FUNCTION FILE_has_next_entry& ALIAS has_next_entry ()
  3.     SUB FILE_close_dir ALIAS close_dir ()
  4.     SUB FILE_get_next_entry ALIAS get_next_entry (s AS STRING, flags AS LONG, file_size AS LONG)
  5.     SUB FILE_get_current_dir ALIAS get_current_dir (s AS STRING)
  6.     FUNCTION FILE_current_dir_length& ALIAS current_dir_length ()
  7.  
  8. SCREEN _NEWIMAGE(1024, 720, 32)
  9.  
  10. a$ = SelectFile$("*.*", 100, 100)
  11. PRINT "You selected:"; a$
  12.  
  13.  
  14. FUNCTION SelectFile$ (search$, x AS INTEGER, y AS INTEGER)
  15.     'save some old values
  16.     LoadFile_DC = _DEFAULTCOLOR: LoadFile_BG = _BACKGROUNDCOLOR
  17.     LoadFile_s = _SOURCE: LoadFile_d = _DEST
  18.     f = _FONT: _FONT 16
  19.     'some variables
  20.  
  21.     LoadFile_BoxColor = &HFFAAAAFF
  22.     LoadFile_FolderColor = &HFFFFFF00
  23.     LoadFile_FileColor = &HFFFFFFFF
  24.     IF INSTR(_OS$, "[WINDOWS]") THEN LoadFile_Slash$ = "\" ELSE LoadFile_Slash$ = "/"
  25.     LoadFile_Dir$ = SPACE$(FILE_current_dir_length)
  26.     FILE_get_current_dir LoadFile_Dir$
  27.     LoadFile_Dir$ = LoadFile_Dir$ + LoadFile_Slash$
  28.     'LoadFile_Dir$ = "." + LoadFile_Slash$
  29.     LoadFile_w = 639: LoadFile_h = 479
  30.     REDIM LoadFile_Label(0) AS STRING: LoadFile_Label(0) = "DIR"
  31.     REDIM LoadFile_DirList(-1 TO 9, -1 TO 9999) AS STRING
  32.     LoadFile_last = 1
  33.     FolderDeep = 1
  34.  
  35.     'some error checking
  36.     IF search$ = "" THEN EXIT SUB 'We can't search for nothing!
  37.  
  38.     'Copy background
  39.     PCOPY 0, 1
  40.     'set workscreen
  41.     LoadFile_ws = _NEWIMAGE(640, 480, 32)
  42.  
  43.     'Count our filetypes to display
  44.     LoadFile_TypeCount = 0
  45.     DO
  46.         LoadFile_TypeCount = LoadFile_TypeCount + 1
  47.         LoadFile_l = INSTR(LoadFile_l + 1, search$, ";") ' look for ; to denote more files
  48.         REDIM _PRESERVE LoadFile_Label(LoadFile_TypeCount) AS STRING
  49.         IF LoadFile_l > 0 THEN LoadFile_Label(LoadFile_TypeCount) = MID$(search$, LoadFile_last + 1, LoadFile_l - LoadFile_last - 1) ELSE LoadFile_Label(LoadFile_TypeCount) = MID$(search$, LoadFile_last + 1, LEN(search$) - LoadFile_last)
  50.         LoadFile_last = LoadFile_l + 1
  51.     LOOP UNTIL LoadFile_l = 0
  52.     LoadFile_l = 640 / (LoadFile_TypeCount + 1)
  53.     REDIM LoadFile_start(LoadFile_TypeCount), LoadFile_previous(LoadFile_TypeCount), LoadFile_more(LoadFile_TypeCount), LoadFile_Count(LoadFile_TypeCount)
  54.     FOR i = 0 TO LoadFile_TypeCount: LoadFile_start(i) = 1: NEXT
  55.  
  56.     _SOURCE LoadFile_ws: _DEST LoadFile_ws
  57.     DO
  58.         _LIMIT 30
  59.         FOR i = 0 TO LoadFile_TypeCount
  60.             LoadFile_Count(i) = 0
  61.             FOR j = 0 TO 9999
  62.                 LoadFile_DirList(i, j) = ""
  63.             NEXT
  64.         NEXT
  65.         'Generate our updated directory listings.
  66.  
  67.         IF FILE_load_dir&(LoadFile_Dir$ + CHR$(0)) THEN
  68.             DO
  69.                 LoadFile_length = FILE_has_next_entry 'Get length of next entry
  70.                 IF LoadFile_length > -1 THEN 'If we have a next entry
  71.                     LoadFile_nam$ = SPACE$(LoadFile_length) 'Set the size of our string
  72.                     FILE_get_next_entry LoadFile_nam$, LoadFile_flags, LoadFile_file_size 'Get the file's name, size, and 'flags'
  73.                     'Check if it's a file or a directory
  74.  
  75.                     IF _DIREXISTS(LoadFile_Dir$ + LoadFile_nam$) THEN
  76.                         IF LoadFile_nam$ <> "." THEN
  77.                             LoadFile_Count(0) = LoadFile_Count(0) + 1
  78.                             LoadFile_DirList(0, LoadFile_Count(0)) = LoadFile_nam$
  79.                         END IF
  80.                     ELSE 'We have a file
  81.                         FOR i = 1 TO LoadFile_TypeCount
  82.                             LoadFile_ext$ = RIGHT$(LoadFile_nam$, LEN(LoadFile_Label(i)))
  83.                             IF UCASE$(LoadFile_ext$) = UCASE$(LoadFile_Label(i)) THEN
  84.                                 LoadFile_Count(i) = LoadFile_Count(i) + 1
  85.                                 LoadFile_DirList(i, LoadFile_Count(i)) = LEFT$(LoadFile_nam$, LEN(LoadFile_nam$) - LEN(LoadFile_Label(i)))
  86.                                 EXIT FOR
  87.                             ELSEIF LoadFile_Label(i) = ".*" THEN
  88.                                 LoadFile_Count(i) = LoadFile_Count(i) + 1
  89.                                 LoadFile_DirList(i, LoadFile_Count(i)) = LoadFile_nam$
  90.                             END IF
  91.                         NEXT
  92.                     END IF
  93.                 END IF
  94.             LOOP UNTIL LoadFile_length = -1
  95.             FILE_close_dir
  96.         END IF
  97.  
  98.         updatelist:
  99.  
  100.  
  101.         CLS , &HFF005050 'Draw a nice display box
  102.         COLOR , 0
  103.         LINE (0, 0)-(LoadFile_w, LoadFile_h + 5 - 2 * 16), LoadFile_BoxColor, B
  104.         LINE (1, 1)-(LoadFile_w - 1, LoadFile_h + 6 - 2 * 16), LoadFile_BoxColor, B
  105.         LINE (0, 0)-(LoadFile_w, LoadFile_h), LoadFile_BoxColor, B
  106.         LINE (1, 1)-(LoadFile_w - 1, LoadFile_h - 1), LoadFile_BoxColor, B
  107.  
  108.         LINE (0, 16 + 3)-(LoadFile_w, 16 + 3), LoadFile_BoxColor
  109.         LINE (0, 16 + 4)-(LoadFile_w, 16 + 4), LoadFile_BoxColor
  110.         FOR i = 0 TO LoadFile_TypeCount
  111.             _PRINTSTRING (i * LoadFile_l + (LoadFile_l - 8 * LEN(LoadFile_Label(i))) / 2, 2), LoadFile_Label(i)
  112.             LINE (i * LoadFile_l, 0)-(i * LoadFile_l, LoadFile_h + 5 - 2 * 16), LoadFile_BoxColor
  113.         NEXT
  114.  
  115.         LINE (627, 2)-(637, 18), &HFFFF0000, BF
  116.         LINE (626, 2)-(637, 18), &HFF000000, B
  117.  
  118.         _PRINTSTRING (628, 2), "X"
  119.         IF selection > 0 THEN
  120.             IF LoadFile_Label(row) <> ".*" AND LoadFile_Label(row) <> "DIR" THEN temp$ = LoadFile_DirList(row, selection) + LoadFile_Label(row) ELSE temp$ = LoadFile_DirList(row, selection)
  121.             IF LoadFile_DirList(row, selection) = "" THEN temp$ = ""
  122.             selection = 0
  123.         END IF
  124.         _PRINTSTRING (10, 28 * 16 + 7), LoadFile_Dir$
  125.         _PRINTSTRING (630 - LEN(temp$) * 8, 28 * 16 + 7), temp$
  126.         IF temp$ = "" THEN oldselection = 0
  127.         IF oldselection > 0 THEN LINE (row * LoadFile_l, (oldselection + 1) * 16 + 5)-((row + 1) * LoadFile_l, (oldselection + 2) * 16 + 5), &HAAAAA000, BF
  128.  
  129.         FOR i = 0 TO UBOUND(LoadFile_label)
  130.             IF i = 0 THEN COLOR LoadFile_FolderColor ELSE COLOR LoadFile_FileColor
  131.             counter = 0
  132.             FOR j = LoadFile_start(i) TO LoadFile_start(i) + 24
  133.                 counter = counter + 1
  134.                 IF LoadFile_DirList(i, j) = "" THEN EXIT FOR
  135.                 _PRINTSTRING (i * LoadFile_l + 5, (counter + 1) * 16 + 7), LEFT$(LoadFile_DirList(i, j), LoadFile_l / 8 - 2)
  136.             NEXT
  137.             IF j = LoadFile_start(i) + 25 THEN LoadFile_more(i) = -1 ELSE LoadFile_more(i) = 0
  138.             IF LoadFile_start(i) > 1 THEN LoadFile_previous(i) = -1 ELSE LoadFile_previous(i) = 0
  139.             IF LoadFile_more(i) THEN
  140.                 LINE (i * LoadFile_l + 2, 27 * 16 + 5)-((i + 1) * LoadFile_l - 3, 28 * 16 + 3), &HFFFF0000, BF
  141.                 LINE (i * LoadFile_l + 2, 27 * 16 + 5)-((i + 1) * LoadFile_l - 3, 28 * 16 + 3), BoxColor, B
  142.                 COLOR &HFFFFFF00: _PRINTSTRING (i * LoadFile_l + (LoadFile_l - 8 * 11) / 2, 27 * 16 + 5), "SCROLL DOWN"
  143.                 COLOR LoadFile_FileColor
  144.             END IF
  145.             IF LoadFile_previous(i) THEN
  146.                 LINE (i * LoadFile_l + 2, 16 + 5)-((i + 1) * LoadFile_l - 3, 2 * 16 + 3), &HFFFF0000, BF
  147.                 LINE (i * LoadFile_l + 2, 16 + 5)-((i + 1) * LoadFile_l - 3, 2 * 16 + 3), BoxColor, B
  148.                 COLOR &HFFFFFF00: _PRINTSTRING (i * LoadFile_l + (LoadFile_l - 8 * 9) / 2, 16 + 5), "SCROLL UP"
  149.                 COLOR LoadFile_FileColor
  150.             END IF
  151.         NEXT
  152.  
  153.         _PUTIMAGE (0 + x, 0 + y)-(640 + x, 480 + y), LoadFile_ws, 0
  154.         _DISPLAY
  155.  
  156.         change = 0
  157.         DO
  158.             _LIMIT 30
  159.             LoadFile_LMB = 0 'This sets the left mouse button as unacceptable.
  160.             a = _KEYHIT
  161.             SELECT CASE a
  162.                 CASE 8 'backspace
  163.                     temp$ = LEFT$(temp$, LEN(temp$) - 1)
  164.                     change = -1
  165.                 CASE 13 'enter
  166.                     DO: LOOP UNTIL INKEY$ = "" 'Clear the keyboard buffer so it doesn't affect the main program.
  167.                     temp$ = LoadFile_Dir$ + temp$
  168.                     COLOR LoadFile_DC, LoadFile_BG: _SOURCE LoadFile_s: _DEST LoadFile_d: PCOPY 1, 0: _DISPLAY: SelectFile$ = temp$ 'Restore our old settings
  169.                     _FONT f
  170.                     EXIT SUB 'And leave
  171.                 CASE 27 'If ESC is pressed then...
  172.                     DO: LOOP UNTIL INKEY$ = "" 'Clear the keyboard buffer so it doesn't affect the main program.
  173.                     COLOR LoadFile_DC, LoadFile_BG: _SOURCE LoadFile_s: _DEST LoadFile_d: PCOPY 1, 0: _DISPLAY: SelectFile$ = "" 'Restore our old settings
  174.                     _FONT f
  175.                     EXIT SUB 'And leave
  176.                 CASE 32 TO 126
  177.                     temp$ = temp$ + CHR$(a)
  178.                     change = -1
  179.             END SELECT
  180.             DO
  181.                 IF _MOUSEBUTTON(1) = 0 THEN LoadFile_LMB = -1 'Only by lifting the mouse, will we count it as down
  182.                 'Note: we ignore LoadFile_LMB for the scroll bars, so we can just hold it down and scroll happily forever and ever...
  183.                 'or until we get to the limit of our file list.
  184.                 'We only check LoadFile_LMB when actually trying to select an item from our list.   No more "OOP!  I held it too long and did something I didn't want to do!"
  185.                 'Now we click once to select, click again to accept that selection.
  186.             LOOP WHILE _MOUSEINPUT
  187.             MX = _MOUSEX: MY = _MOUSEY
  188.             IF _MOUSEBUTTON(2) OR (LoadFile_LMB AND MX > 626 + x AND MX < 638 + x AND MY > 1 + y AND MY < 19 + y AND _MOUSEBUTTON(1)) THEN
  189.                 'restore those old values, and just exit.  Right mouse is an escape
  190.                 COLOR LoadFile_DC, LoadFile_BG: _SOURCE LoadFile_s: _DEST LoadFile_d: PCOPY 1, 0: _DISPLAY: SelectFile$ = ""
  191.                 _FONT f
  192.                 EXIT SUB
  193.             END IF
  194.             IF _MOUSEBUTTON(1) THEN 'Without the mouse being down, we don't need to check squat!
  195.                 'Check the 2 roLoadFile_ws for a click in the proper Y position
  196.                 IF MY >= 16 + 5 + y AND MY <= 2 * 16 + 3 + y THEN 'We're on the top row
  197.                     FOR j = 0 TO UBOUND(LoadFile_label)
  198.                         IF LoadFile_previous(j) AND MX >= j * LoadFile_l + 2 + x AND MX <= (j + 1) * LoadFile_l - 3 + x THEN
  199.                             LoadFile_start(j) = LoadFile_start(j) - 1
  200.                             change = -1: selection = 0: click = 0: temp$ = ""
  201.                             EXIT FOR
  202.                         END IF
  203.                     NEXT
  204.                 ELSEIF MY >= 27 * 16 + 5 + y AND MY <= 28 * 16 + 3 + y THEN 'We're on the bottom row
  205.                     FOR j = 0 TO UBOUND(LoadFile_label)
  206.                         IF LoadFile_more(j) AND MX >= j * LoadFile_l + 2 + x AND MX <= (j + 1) * LoadFile_l - 3 + x THEN
  207.                             LoadFile_start(j) = LoadFile_start(j) + 1
  208.                             change = -1: selection = 0: click = 0: temp$ = ""
  209.                             EXIT FOR
  210.                         END IF
  211.                     NEXT
  212.                 ELSEIF MY >= 37 + y AND MY <= 437 + y AND LoadFile_LMB THEN 'It's in a column somewhere.  Did someone click an item?!
  213.                     FOR j = 0 TO UBOUND(LoadFile_label)
  214.                         IF MX >= j * LoadFile_l + 2 + x AND MX <= (j + 1) * LoadFile_l - 3 + x THEN
  215.                             row = j
  216.                             oldselection = INT((MY - y - 37) / 16) + 1
  217.                             selection = LoadFile_start(j) + oldselection - 1
  218.                             change = -1
  219.                             click = -1
  220.                             EXIT FOR
  221.                         END IF
  222.                     NEXT
  223.                 END IF
  224.             END IF
  225.  
  226.             _DISPLAY
  227.         LOOP UNTIL change
  228.         IF click THEN 'we clicked something besides a scroll bar
  229.             IF LoadFile_Label(row) <> ".*" AND LoadFile_Label(row) <> "DIR" THEN temp1$ = LoadFile_DirList(row, selection) + LoadFile_Label(row) ELSE temp1$ = LoadFile_DirList(row, selection)
  230.             IF temp$ = temp1$ THEN
  231.                 'We picked one!
  232.                 SELECT CASE LoadFile_Label(row)
  233.                     CASE "DIR"
  234.                         IF LoadFile_DirList(row, selection) <> ".." THEN
  235.                             LoadFile_Dir$ = LoadFile_Dir$ + LoadFile_DirList(row, selection) + LoadFile_Slash$
  236.                         ELSE
  237.                             DO
  238.                                 LoadFile_Dir$ = LEFT$(LoadFile_Dir$, LEN(LoadFile_Dir$) - 1)
  239.                             LOOP UNTIL RIGHT$(LoadFile_Dir$, 1) = LoadFile_Slash$ OR LEN(LoadFile_Dir$) = 0
  240.                         END IF
  241.                         FOR i = 1 TO UBOUND(Loadfile_start)
  242.                             LoadFile_start(i) = 1
  243.                         NEXT
  244.                         selection = 0: temp$ = "": oldselection = 0
  245.                     CASE ".*": SelectFile$ = LoadFile_Dir$ + temp$: EXIT DO
  246.                     CASE ELSE: SelectFile$ = LoadFile_Dir$ + temp$: EXIT DO
  247.                 END SELECT
  248.             END IF
  249.             IF row > 0 THEN _DELAY .2: GOTO updatelist
  250.         ELSE
  251.             _DELAY .05
  252.             GOTO updatelist
  253.         END IF
  254.     LOOP
  255.     'restore those old values
  256.     COLOR LoadFile_DC, LoadFile_BG: _SOURCE LoadFile_s: _DEST LoadFile_d: PCOPY 1, 0: _DISPLAY
  257.     _FONT f
  258.  
  259. 'If you don't have a copy of direntry.h in your QB64 folder, then copy the following code into a new IDE window.
  260. 'Then remove the remarks.
  261. 'And save it as direntry.h
  262. 'direntry.h is required for this to work properly with the library files.
  263. 'I thought adding the code here would be a way to make certain that it'd be easy to recover the file
  264. 'in case something ever happened and it was accidently deleted off the drive for some reason.
  265.  
  266. '#include <dirent.h>
  267. '#include <sys/stat.h>
  268. '#include <unistd.h>
  269.  
  270. 'const int IS_DIR_FLAG = 1, IS_FILE_FLAG = 2;
  271.  
  272. 'DIR *pdir;
  273. 'struct dirent *next_entry;
  274. 'struct stat statbuf1;
  275.  
  276. 'char current_dir[FILENAME_MAX];
  277. '#ifdef QB64_WINDOWS
  278. '  #define GetCurrentDir _getcwd
  279. '#else
  280. '  #define GetCurrentDir getcwd
  281. '#endif
  282.  
  283. 'int load_dir (char * path) {
  284. '  struct dirent *pent;
  285. '  struct stat statbuf1;
  286. '//Open current directory
  287. 'pdir = opendir(path);
  288. 'if (!pdir) {
  289. 'return 0; //Didn't open
  290. '}
  291. 'return -1;
  292. '}
  293.  
  294. 'int has_next_entry () {
  295. '  next_entry = readdir(pdir);
  296. '  if (next_entry == NULL) return -1;
  297.  
  298. '  stat(next_entry->d_name, &statbuf1);
  299. '  return strlen(next_entry->d_name);
  300. '}
  301.  
  302. 'void get_next_entry (char * nam, int * flags, int * file_size) {
  303. '  strcpy(nam, next_entry->d_name);
  304. '  if (S_ISDIR(statbuf1.st_mode)) {
  305. '    *flags = IS_DIR_FLAG;
  306. '  } else {
  307. '    *flags = IS_FILE_FLAG;
  308. '  }
  309. '  *file_size = statbuf1.st_size;
  310. '  return ;
  311. '}
  312.  
  313. 'void close_dir () {
  314. '  closedir(pdir);
  315. '  pdir = NULL;
  316. '  return ;
  317. '}
  318.  
  319. 'int current_dir_length () {
  320. '  GetCurrentDir(current_dir, sizeof(current_dir));
  321. '  return strlen(current_dir);
  322. '}
  323.  
  324. 'void get_current_dir(char *dir) {
  325. '  memcpy(dir, current_dir, strlen(current_dir));
  326. '  return ;
  327. '}
  328.  
  329.  
  330.  

Read the comments at the end of the file to create the direntry.h text/header file in your QB64 folder for it to run properly.
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: How to load system fileselector
« Reply #12 on: December 08, 2021, 11:40:31 am »
Windows only, like the InForm version, I wasn't attempting cross platform file access then. (Probably a waste of time without another OS to test yourself.)
https://www.qb64.org/forum/index.php?topic=1876.msg111064#msg111064

My nascent GUI might be tough to follow, hell it's probably god awful. :)

My SelectFile GUI above is cross-platform, but probably more devil awe-full than yours.  My daughter has color issues, so, from what I remember, this was coded from my old IDE and is a high color-contrast theme.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: How to load system fileselector
« Reply #13 on: December 08, 2021, 11:55:55 am »
Yeah, @cfalcon030

Steve's is pretty good for Windows I have been playing with that since Fetch Text apps. Most recently making lists of all my .bas files in main folders of hard drive.

But never really got solid confirmation it works for Linux people, that I can recall which is the only reason I waste time with cross platform.

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: How to load system fileselector
« Reply #14 on: December 08, 2021, 12:21:32 pm »
Yeah, @cfalcon030

Steve's is pretty good for Windows I have been playing with that since Fetch Text apps. Most recently making lists of all my .bas files in main folders of hard drive.

But never really got solid confirmation it works for Linux people, that I can recall which is the only reason I waste time with cross platform.

It works on Linux and Mac all.  It's a cross-platform utility.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!