a$ = SelectFile$("*.*", 100, 100)
PRINT "You selected:"; a$
  
 
    'save some old values
    'some variables
 
    LoadFile_BoxColor = &HFFAAAAFF
    LoadFile_FolderColor = &HFFFFFF00
    LoadFile_FileColor = &HFFFFFFFF
    LoadFile_Dir$ 
= SPACE$(FILE_current_dir_length
)    FILE_get_current_dir LoadFile_Dir$
    LoadFile_Dir$ = LoadFile_Dir$ + LoadFile_Slash$
    'LoadFile_Dir$ = "." + LoadFile_Slash$
    LoadFile_w = 639: LoadFile_h = 479
    LoadFile_last = 1
    FolderDeep = 1
 
    'some error checking
 
    'Copy background
    'set workscreen
 
    'Count our filetypes to display
    LoadFile_TypeCount = 0
        LoadFile_TypeCount = LoadFile_TypeCount + 1
        LoadFile_l 
= INSTR(LoadFile_l 
+ 1, search$
, ";") ' look for ; to denote more files        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
)         LoadFile_last = LoadFile_l + 1
    LoadFile_l = 640 / (LoadFile_TypeCount + 1)
    REDIM LoadFile_start
(LoadFile_TypeCount
), LoadFile_previous
(LoadFile_TypeCount
), LoadFile_more
(LoadFile_TypeCount
), LoadFile_Count
(LoadFile_TypeCount
)     FOR i 
= 0 TO LoadFile_TypeCount: LoadFile_start
(i
) = 1: 
NEXT  
        FOR i 
= 0 TO LoadFile_TypeCount
             LoadFile_Count(i) = 0
                LoadFile_DirList(i, j) = ""
        'Generate our updated directory listings.
 
                LoadFile_length = FILE_has_next_entry 'Get length of next entry
                IF LoadFile_length 
> -1 THEN 'If we have a next entry                     LoadFile_nam$ 
= SPACE$(LoadFile_length
) 'Set the size of our string                    FILE_get_next_entry LoadFile_nam$, LoadFile_flags, LoadFile_file_size 'Get the file's name, size, and 'flags'
                    'Check if it's a file or a directory
 
                            LoadFile_Count(0) = LoadFile_Count(0) + 1
                            LoadFile_DirList(0, LoadFile_Count(0)) = LoadFile_nam$
                        FOR i 
= 1 TO LoadFile_TypeCount
                             LoadFile_ext$ 
= RIGHT$(LoadFile_nam$
, LEN(LoadFile_Label
(i
)))                                LoadFile_Count(i) = LoadFile_Count(i) + 1
                                LoadFile_DirList
(i
, LoadFile_Count
(i
)) = LEFT$(LoadFile_nam$
, LEN(LoadFile_nam$
) - LEN(LoadFile_Label
(i
)))                                LoadFile_Count(i) = LoadFile_Count(i) + 1
                                LoadFile_DirList(i, LoadFile_Count(i)) = LoadFile_nam$
            FILE_close_dir
 
        updatelist:
 
 
        CLS , &HFF005050 'Draw a nice display box         LINE (0, 0)-(LoadFile_w
, LoadFile_h 
+ 5 - 2 * 16), LoadFile_BoxColor
, B
         LINE (1, 1)-(LoadFile_w 
- 1, LoadFile_h 
+ 6 - 2 * 16), LoadFile_BoxColor
, B
         LINE (0, 0)-(LoadFile_w
, LoadFile_h
), LoadFile_BoxColor
, B
         LINE (1, 1)-(LoadFile_w 
- 1, LoadFile_h 
- 1), LoadFile_BoxColor
, B
  
        LINE (0, 16 + 3)-(LoadFile_w
, 16 + 3), LoadFile_BoxColor
         LINE (0, 16 + 4)-(LoadFile_w
, 16 + 4), LoadFile_BoxColor
         FOR i 
= 0 TO LoadFile_TypeCount
             _PRINTSTRING (i 
* LoadFile_l 
+ (LoadFile_l 
- 8 * LEN(LoadFile_Label
(i
))) / 2, 2), LoadFile_Label
(i
)             LINE (i 
* LoadFile_l
, 0)-(i 
* LoadFile_l
, LoadFile_h 
+ 5 - 2 * 16), LoadFile_BoxColor
  
        LINE (627, 2)-(637, 18), &HFFFF0000, BF
         LINE (626, 2)-(637, 18), &HFF000000, B
  
            IF LoadFile_Label
(row
) <> ".*" AND LoadFile_Label
(row
) <> "DIR" THEN temp$ 
= LoadFile_DirList
(row
, selection
) + LoadFile_Label
(row
) ELSE temp$ 
= LoadFile_DirList
(row
, selection
)             IF LoadFile_DirList
(row
, selection
) = "" THEN temp$ 
= ""             selection = 0
        IF temp$ 
= "" THEN oldselection 
= 0         IF oldselection 
> 0 THEN LINE (row 
* LoadFile_l
, (oldselection 
+ 1) * 16 + 5)-((row 
+ 1) * LoadFile_l
, (oldselection 
+ 2) * 16 + 5), &HAAAAA000, BF
  
            counter = 0
            FOR j 
= LoadFile_start
(i
) TO LoadFile_start
(i
) + 24                 counter = counter + 1
                _PRINTSTRING (i 
* LoadFile_l 
+ 5, (counter 
+ 1) * 16 + 7), LEFT$(LoadFile_DirList
(i
, j
), LoadFile_l 
/ 8 - 2)             IF j 
= LoadFile_start
(i
) + 25 THEN LoadFile_more
(i
) = -1 ELSE LoadFile_more
(i
) = 0             IF LoadFile_start
(i
) > 1 THEN LoadFile_previous
(i
) = -1 ELSE LoadFile_previous
(i
) = 0                 LINE (i 
* LoadFile_l 
+ 2, 27 * 16 + 5)-((i 
+ 1) * LoadFile_l 
- 3, 28 * 16 + 3), &HFFFF0000, BF
                 LINE (i 
* LoadFile_l 
+ 2, 27 * 16 + 5)-((i 
+ 1) * LoadFile_l 
- 3, 28 * 16 + 3), BoxColor
, B
                 COLOR &HFFFFFF00: 
_PRINTSTRING (i 
* LoadFile_l 
+ (LoadFile_l 
- 8 * 11) / 2, 27 * 16 + 5), "SCROLL DOWN"                 LINE (i 
* LoadFile_l 
+ 2, 16 + 5)-((i 
+ 1) * LoadFile_l 
- 3, 2 * 16 + 3), &HFFFF0000, BF
                 LINE (i 
* LoadFile_l 
+ 2, 16 + 5)-((i 
+ 1) * LoadFile_l 
- 3, 2 * 16 + 3), BoxColor
, B
                 COLOR &HFFFFFF00: 
_PRINTSTRING (i 
* LoadFile_l 
+ (LoadFile_l 
- 8 * 9) / 2, 16 + 5), "SCROLL UP"  
        _PUTIMAGE (0 + x
, 0 + y
)-(640 + x
, 480 + y
), LoadFile_ws
, 0  
        change = 0
            LoadFile_LMB = 0 'This sets the left mouse button as unacceptable.
                    change = -1
                    DO: 
LOOP UNTIL INKEY$ = "" 'Clear the keyboard buffer so it doesn't affect the main program.                     temp$ = LoadFile_Dir$ + temp$
                CASE 27 'If ESC is pressed then...                     DO: 
LOOP UNTIL INKEY$ = "" 'Clear the keyboard buffer so it doesn't affect the main program.                     change = -1
                IF _MOUSEBUTTON(1) = 0 THEN LoadFile_LMB 
= -1 'Only by lifting the mouse, will we count it as down                 'Note: we ignore LoadFile_LMB for the scroll bars, so we can just hold it down and scroll happily forever and ever...
                'or until we get to the limit of our file list.
                '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!"
                'Now we click once to select, click again to accept that selection.
                'restore those old values, and just exit.  Right mouse is an escape
                'Check the 2 roLoadFile_ws for a click in the proper Y position
                IF MY 
>= 16 + 5 + y 
AND MY 
<= 2 * 16 + 3 + y 
THEN 'We're on the top row                         IF LoadFile_previous
(j
) AND MX 
>= j 
* LoadFile_l 
+ 2 + x 
AND MX 
<= (j 
+ 1) * LoadFile_l 
- 3 + x 
THEN                             LoadFile_start(j) = LoadFile_start(j) - 1
                            change = -1: selection = 0: click = 0: temp$ = ""
                ELSEIF MY 
>= 27 * 16 + 5 + y 
AND MY 
<= 28 * 16 + 3 + y 
THEN 'We're on the bottom row                         IF LoadFile_more
(j
) AND MX 
>= j 
* LoadFile_l 
+ 2 + x 
AND MX 
<= (j 
+ 1) * LoadFile_l 
- 3 + x 
THEN                             LoadFile_start(j) = LoadFile_start(j) + 1
                            change = -1: selection = 0: click = 0: temp$ = ""
                ELSEIF MY 
>= 37 + y 
AND MY 
<= 437 + y 
AND LoadFile_LMB 
THEN 'It's in a column somewhere.  Did someone click an item?!                         IF MX 
>= j 
* LoadFile_l 
+ 2 + x 
AND MX 
<= (j 
+ 1) * LoadFile_l 
- 3 + x 
THEN                             row = j
                            oldselection 
= INT((MY 
- y 
- 37) / 16) + 1                            selection = LoadFile_start(j) + oldselection - 1
                            change = -1
                            click = -1
 
        IF click 
THEN 'we clicked something besides a scroll bar             IF LoadFile_Label
(row
) <> ".*" AND LoadFile_Label
(row
) <> "DIR" THEN temp1$ 
= LoadFile_DirList
(row
, selection
) + LoadFile_Label
(row
) ELSE temp1$ 
= LoadFile_DirList
(row
, selection
)                 'We picked one!
                        IF LoadFile_DirList
(row
, selection
) <> ".." THEN                             LoadFile_Dir$ = LoadFile_Dir$ + LoadFile_DirList(row, selection) + LoadFile_Slash$
                                LoadFile_Dir$ 
= LEFT$(LoadFile_Dir$
, LEN(LoadFile_Dir$
) - 1)                            LoadFile_start(i) = 1
                        selection = 0: temp$ = "": oldselection = 0
                    CASE ".*": SelectFile$ 
= LoadFile_Dir$ 
+ temp$: 
EXIT DO     'restore those old values
 
'If you don't have a copy of direntry.h in your QB64 folder, then copy the following code into a new IDE window.
'Then remove the remarks.
'And save it as direntry.h
'direntry.h is required for this to work properly with the library files.
'I thought adding the code here would be a way to make certain that it'd be easy to recover the file
'in case something ever happened and it was accidently deleted off the drive for some reason.
 
'#include <dirent.h>
'#include <sys/stat.h>
'#include <unistd.h>
 
'const int IS_DIR_FLAG = 1, IS_FILE_FLAG = 2;
 
'DIR *pdir;
'struct dirent *next_entry;
'struct stat statbuf1;
 
'char current_dir[FILENAME_MAX];
'#ifdef QB64_WINDOWS
'  #define GetCurrentDir _getcwd
'#else
'  #define GetCurrentDir getcwd
'#endif
 
'int load_dir (char * path) {
'  struct dirent *pent;
'  struct stat statbuf1;
'//Open current directory
'pdir = opendir(path);
'if (!pdir) {
'return 0; //Didn't open
'}
'return -1;
'}
 
'int has_next_entry () {
'  next_entry = readdir(pdir);
'  if (next_entry == NULL) return -1;
 
'  stat(next_entry->d_name, &statbuf1);
'  return strlen(next_entry->d_name);
'}
 
'void get_next_entry (char * nam, int * flags, int * file_size) {
'  strcpy(nam, next_entry->d_name);
'  if (S_ISDIR(statbuf1.st_mode)) {
'    *flags = IS_DIR_FLAG;
'  } else {
'    *flags = IS_FILE_FLAG;
'  }
'  *file_size = statbuf1.st_size;
'  return ;
'}
 
'void close_dir () {
'  closedir(pdir);
'  pdir = NULL;
'  return ;
'}
 
'int current_dir_length () {
'  GetCurrentDir(current_dir, sizeof(current_dir));
'  return strlen(current_dir);
'}
 
'void get_current_dir(char *dir) {
'  memcpy(dir, current_dir, strlen(current_dir));
'  return ;
'}