FILEDIALOG - Path length limited
Description
The path length returned by the file dialog is limited to 128 characters. The path is not truncated, but an error is raised and the command execution fails.
Example code to demonstrate the bug.
filedialog "open ...", "*.*", File$
print len(File$)
' if path is longer than 128 characters you will get
' Runtime error: Wrong Parameter. ( OS error 16r57 )
Example code to work around the bug.
Selecting Multiple Files - by Stefan Pendl
Dir$ = "C:\"
Filter$ = "Textfiles|*.txt;*.bat|All Files|*.*"
Title$ = "Select Files"
print FileExplorer$(Title$, Dir$, Filter$)
end
function FileExplorer$(Caption$, InitialDir$, FilterString$)
' function to select multiple files
'
' Usage:
' FilterString in the form of {description}|{list of extensions}
' extensions are seperated with semicolons (;)
' multiple pairs are supported
' field seperator is the pipe (|)
'
' the returned string consits of the number of files
' and the directory followed by the filenames
' all fields are seperated by semicolons (;)
OFN.EXPLORER = hexdec("80000")
z$ = chr$(0)
struct ofn, _
lStructSize as ulong, _
hwndOwner as ulong, _
hInstance as ulong, _
lpstrFilter$ as ptr, _
lpstrCustomFilter$ as ptr, _
nMaxCustFilter as ulong, _
nFilterIndex as ulong, _
lpstrFile$ as ptr, _
nMaxFile as ulong, _
lpstrFileTitle$ as ptr, _
nMaxFileTitle as ulong, _
lpstrInitialDir$ as ptr, _
lpstrTitle$ as ptr, _
flags as ulong, _
nFileOffset as word, _
nFileExtension as word, _
lpstrDefExt$ as ptr, _
lCustData as ulong, _
lpfnHook as ulong, _
lpTemplateName$ as ptr
Filter$ = ReplaceString$(FilterString$, "|", z$, "ALL", 0) + z$ + z$
ofn.lStructSize.struct = len(ofn.struct)
ofn.lpstrFilter$.struct = Filter$
ofn.lpstrFile$.struct = z$ + space$(3072) + z$
ofn.nMaxFile.struct = 3072
ofn.lpstrFileTitle$.struct = space$(255) + z$
ofn.nMaxFileTitle.struct = 255
ofn.lpstrInitialDir$.struct = InitialDir$ + z$
ofn.lpstrTitle$.struct = Caption$ + z$
ofn.flags.struct = _OFN_PATHMUSTEXIST or _OFN_FILEMUSTEXIST or _OFN_ALLOWMULTISELECT or OFN.EXPLORER
calldll #comdlg32, "GetOpenFileNameA",_
ofn as struct,_
ok as boolean
pointer = ofn.lpstrFile$.struct
count = 0
If ok Then
FileExplorer$ = WinString(pointer)
pointer = pointer + Len(FileExplorer$) + 1
program$ = WinString(pointer)
if program$ = "" then
FileExplorer$ = DirName$(FileExplorer$); ";";BaseName$(FileExplorer$, "", "")
count = 1
else
While program$ <> ""
FileExplorer$ = FileExplorer$; ";"; program$
pointer = pointer + Len(program$) + 1
count = count + 1
program$ = WinString(pointer)
Wend
end if
End If
FileExplorer$ = count; ";"; FileExplorer$
end function
function BaseName$(input$, ext$, sep$)
' returns the name of the given file
' if ext$ matches the last part of
' input$ it will be cut off
if sep$ = "" then sep$ = "\"
if len(ext$) > 0 and right$(input$, len(ext$)) = ext$ then _
input$ = left$(input$,len(input$) - len(ext$))
BaseName$ = input$
bsPos = len(input$)
while mid$(input$, bsPos, 1) <> sep$ and bsPos > 0
bsPos = bsPos - 1
wend
if bsPos <> 0 then BaseName$ = right$(input$,len(input$) - bsPos)
end function
function DirName$(input$)
' returns the path of the given file
DirName$ = input$
bsPos = len(input$)
while mid$(input$, bsPos, 1) <> "\" and bsPos > 0
bsPos = bsPos - 1
wend
if bsPos <> 0 then DirName$ = left$(input$,bsPos - 1)
end function
function ReplaceString$(in$,ere$,repl$,occ$,pos)
' Function to replace expressions in strings
'
' Usage:
'
'
' ReplaceString$({string},{expression},{replacement},{occurrances},{startposition})
'
' string .......... string to be parsed
' expression ...... string to be replaced
' replacement ..... substitute for expression
' occurrances ..... ALL -> replaces all occurrances
' else the specified number
' startposition ... position from where to start substitution
'
' returns altered string
ReplaceString$ = in$
if upper$(occ$) = "ALL" then
number = len(in$)
else
number = val(occ$)
end if
if pos < 0 then pos = 0
while instr(ReplaceString$,ere$,pos) > 0
pos = instr(ReplaceString$,ere$,pos)
ReplaceString$ = left$(ReplaceString$,pos - 1) + repl$ + mid$(ReplaceString$,pos + len(ere$))
if upper$(occ$) = "ALL" and number > 1 then
pos = pos + len(repl$)
number = number - 1
else
pos = len(ReplaceString$)
end if
wend
end function
function uSaveFileDialog$(filter$, defaultExt$, initialDir$, initialFile$, windTitle$)
'Opens dialog to find file name for saving file. Returns full path name+file name+extension
'filter$ specifies the type of file to allow. Sample:
'filter$ = "Text files" + chr$(0) + "*.txt" + chr$(0) + _
' "All files" + chr$(0) + "*.*"
'filter$ is pairs of strings, or null for no filter
'defaultExt$ is the extension to add if the user does not specify one; do not include the period
'initialDir$ is the directory in which to start
'windTitle$ is the title of the dialog window
struct ofn, lStructSize as ulong, hwndOwner as ulong, _
hInstance as ulong, lpstrFilter$ as ptr, lpstrCustomFilter$ as ptr, _
nMaxCustFilter as ulong, nFilterIndex as ulong, lpstrFile$ as ptr, _
nMaxFile as ulong, lpstrFileTitle$ as ptr, nMaxFileTitle as ulong, _
lpstrInitialDir$ as ptr, lpstrTitle$ as ptr, flags as ulong, _
nFileOffset as word, nFileExtension as word, lpstrDefExt$ as ptr, _
lCustData as ulong, lpfnHook as long, lpTemplateName as long
ofn.lStructSize.struct = len(ofn.struct) 'len of this struct
ofn.lpstrFilter$.struct = filter$+ chr$(0) + chr$(0) 'filter for file types
ofn.nFilterIndex.struct = 1 'Filter initially selected
ofn.lpstrFile$.struct = initialFile$+chr$(0) + space$(360) + chr$(0) 'File name used to initialize; receives full selected file path+name
ofn.nMaxFile.struct = 360 'length of lpstrFile$; buffer may actually be longer
ofn.lpstrFileTitle$.struct = space$(260) + chr$(0) 'Receives file name w/o path
ofn.nMaxFileTitle.struct = 260 'len of lpstrFileTitle$
ofn.lpstrInitialDir$.struct = initialDir$ + chr$(0) 'initial directory; null for default directory
ofn.lpstrTitle$.struct = windTitle$ + chr$(0) 'titlebar string for dialog
ofn.flags.struct = _OFN_OVERWRITEPROMPT 'Warn if file exists already
ofn.lpstrDefExt$.struct = defaultExt$ + chr$(0) 'default extension to add if none specified
CallDLL #comdlg32, "GetSaveFileNameA", ofn As struct, ok As boolean
'ofn.lpstrFile.struct returns a long integer memory address.
'Use winstring() to retrieve the string of text
'at that address, as filled by the function. If multiple files were selected,
'this returns only the first
if ok then uSaveFileDialog$=winstring(ofn.lpstrFile$.struct) else uSaveFileDialog$=""
end function
function uOpenFileDialog$(filter$, defaultExt$, initialDir$, initialFile$, windTitle$)
'Opens dialog to find file name for saving a single file. Return full path name+file name+extension
'filter$ specifies the type of file to allow. Sample:
'filter$ = "Text files" + chr$(0) + "*.txt" + chr$(0) + _
' "All files" + chr$(0) + "*.*"
'filter$ is pairs of strings, or null for no filter
'defaultExt$ is the extension to add if the user does not specify one; do not include the period
'initialDir$ is the directory in which to start
'windTitle$ is the title of the dialog window
OFN.EXPLORER = hexdec("80000")
struct ofn, lStructSize as ulong, hwndOwner as ulong, _
hInstance as ulong, lpstrFilter$ as ptr, lpstrCustomFilter$ as ptr, _
nMaxCustFilter as ulong, nFilterIndex as ulong, lpstrFile$ as ptr, _
nMaxFile as ulong, lpstrFileTitle$ as ptr, nMaxFileTitle as ulong, _
lpstrInitialDir$ as ptr, lpstrTitle$ as ptr, flags as ulong, _
nFileOffset as word, nFileExtension as word, lpstrDefExt$ as ptr, _
lCustData as ulong, lpfnHook as long, lpTemplateName as long
ofn.lStructSize.struct = len(ofn.struct) 'len of this struct
ofn.lpstrFilter$.struct = filter$+ chr$(0) + chr$(0) 'filter for file types
ofn.nFilterIndex.struct = 1 'Filter initially selected
ofn.lpstrFile$.struct = initialFile$+chr$(0) + space$(1000) + chr$(0) 'File name used to initialize; receives full selected file path+name
ofn.nMaxFile.struct = 1000 'length of lpstrFile$; buffer may actually be longer
ofn.lpstrFileTitle$.struct = space$(260) + chr$(0) 'Receives file name w/o path
ofn.nMaxFileTitle.struct = 260 'len of lpstrFileTitle$
ofn.lpstrInitialDir$.struct = initialDir$ + chr$(0) 'initial directory; null for default directory
ofn.lpstrTitle$.struct = windTitle$ + chr$(0) 'titlebar string for dialog
ofn.flags.struct = _OFN_PATHMUSTEXIST or _OFN_FILEMUSTEXIST or OFN.EXPLORER
ofn.lpstrDefExt$.struct = defaultExt$ + chr$(0) 'default extension to add if none specified
CallDLL #comdlg32, "GetOpenFileNameA", ofn As struct, ok As boolean
'ofn.lpstrFile.struct returns a long integer memory address.
'Use winstring() to retrieve the string of text
'at that address, as filled by the function. If multiple files were selected,
'this returns only the first
if ok then uOpenFileDialog$=winstring(ofn.lpstrFile$.struct) else uOpenFileDialog$=""
end function