=====Selecting multiple files=====
//by Richard Russell, March 2010//\\ \\ The main [[http://www.bbcbasic.co.uk/bbcwin/manual/bbcwine.html#opensave|Help documentation]] describes how to use the Windows **GetOpenFileName** common dialogue to select a file (usually so it can subsequently be opened). That dialogue also permits the selection of **multiple files** (using the optional **OFN_ALLOWMULTISELECT** flag), but the format in which the filenames and paths are returned is quite tricky to deal with. The format also differs according to whether only one file, or multiple files, are selected.\\ \\ The function listed below makes the selection of multiple files straightforward. It takes as parameters the **title** of the dialogue box, a file **filter** string and a string **array** in which to return the selected file(s); the function returns the number of files selected (or zero if the user clicked Cancel). The filter string contains the description(s) and extension(s) of the file types from which the user can make a selection. The array must be created before the function is called, and be sufficiently large to contain the maximum number of files that need to be selected; the first filename is returned in index 1 (not 0) of the array. An example of calling the function is as follows:
DIM files$(100)
filter$ = "All files"+CHR$(0)+"*.*"
num% = FNselectfiles("Select multiple files", filter$, files$())
IF num% THEN
FOR i% = 1 TO num%
PRINT files$(i%)
NEXT
ENDIF
If you want to sort the returned filenames into ascending alphabetical order you can easily do that using the SORTLIB library:
INSTALL @lib$+"SORTLIB"
sort% = FN_sortinit(0,0)
C% = num%
CALL sort%, files$(1)
Here is the function itself:
DEF FNselectfiles(title$, filter$, file$())
LOCAL fs{}, fp%, res%, nfiles%, P%, J%
DIM fs{lStructSize%, hwndOwner%, hInstance%, lpstrFilter%, \
\ lpstrCustomFilter%, nMaxCustFilter%, nFilterIndex%, \
\ lpstrFile%, nMaxFile%, lpstrFileTitle%, \
\ nMaxFileTitle%, lpstrInitialDir%, lpstrTitle%, \
\ flags%, nFileOffset{l&,h&}, nFileExtension{l&,h&}, \
\ lpstrDefExt%, lCustData%, lpfnHook%, lpTemplateName%}
DIM fp% LOCAL 65535
OFN_ALLOWMULTISELECT = &200
OFN_EXPLORER = &80000
title$ += CHR$0
filter$ += CHR$0+CHR$0
fs.lStructSize% = DIM(fs{})
fs.hwndOwner% = @hwnd%
fs.lpstrFilter% = !^filter$
fs.lpstrTitle% = !^title$
fs.lpstrFile% = fp%
fs.nMaxFile% = 65535
fs.flags% = OFN_ALLOWMULTISELECT OR OFN_EXPLORER
SYS "GetOpenFileName", fs{} TO res%
IF res% THEN
P% = fp%
WHILE ($$P% <> "") AND (nfiles% <= DIM(file$(),1))
file$(nfiles%) = $$P%
nfiles% += 1
P% += LEN$$P% + 1
ENDWHILE
IF nfiles%>1 THEN
nfiles% -= 1
FOR J% = 1 TO nfiles%
file$(J%) = file$(0)+"\"+file$(J%)
NEXT J%
ELSE
file$(1) = file$(0)
ENDIF
ENDIF
=nfiles%
The maximum number of files which may be returned is limited by the size of the supplied array, and by the total size of all the filenames not exceeding 65535 bytes.