I needed some more functionality than Openfilerequester so i did this, maybe someone finds it useful. only for windows
extra features are:
you can set parent window
you can set a default extension
it can return the index of the selected file type filter
it can return the file title (filename+ext without path)
you can set any api flag for extra features
you can use multiselection in Save style
i have set the max buffer size to 2048 if is too small returns an empty string
multiselection is done in a similar way of Openfilereq.. but using a handle,
see example
the are 3 main functions
GetOpenFileName()
GetSaveFileName()
NextFileName()
the rest are helpers
Code: Select all
;GetOpenFilename()
;Justin 01/05
#OFN_ENABLESIZING = $800000
Structure _COMMDLG_MULTI_DATA_
BufOffset.l
FileBuf.l
Dir.s
EndStructure
Procedure.s AddBackSlash(dir$)
If dir$
If Right(dir$, 1)<>"\" : dir$ + "\" : EndIf
EndIf
ProcedureReturn dir$
EndProcedure
Procedure cdgMakeFilter(*filter.BYTE)
While *filter\b<>0
If *filter\b = '|' : *filter\b= 0 : EndIf
*filter + 1
Wend
EndProcedure
Procedure.s cdgAskFileName(hwndOwner, Title$, InitialDir$, filter$, FilterIndex, defFile$, defExt$, *hMulti.LONG, *iFilter.LONG, *FileTitle, flags.l, mode)
of.OPENFILENAME
bufSize = 2048
of\lpstrFile = AllocateMemory(bufSize)
ret$ = ""
of\lStructSize = SizeOf(OPENFILENAME)
of\hwndOwner = hwndOwner
If filter$
tmpFilter$ = filter$ + "|"
cdgMakeFilter(@tmpFilter$)
of\lpstrFilter = @tmpFilter$
EndIf
of\nFilterIndex = FilterIndex
If defFile$ : lstrcpy_(of\lpstrFile, defFile$) : EndIf
of\nMaxFile = bufSize
If InitialDir$ : of\lpstrInitialDir = @InitialDir$ : EndIf
If *FileTitle
of\lpstrFileTitle = *FileTitle
of\nMaxFileTitle = lstrlen_(*FileTitle)
EndIf
If Title$ : of\lpstrTitle = @Title$ : EndIf
of\Flags = #OFN_EXPLORER | #OFN_ENABLESIZING
If flags : of\Flags | flags : EndIf
If *hMulti : of\Flags | #OFN_ALLOWMULTISELECT : EndIf
If defExt$ : of\lpstrDefExt = @defExt$ : EndIf
If mode=1
r = GetOpenFileName_(@of)
ElseIf mode=2
r = GetSaveFileName_(@of)
EndIf
If r ;Ok
ret$ = PeekS(of\lpstrFile)
If *iFilter : *iFilter\l = of\nFilterIndex : EndIf
If *hMulti
*multiDat._COMMDLG_MULTI_DATA_ = AllocateMemory(SizeOf(_COMMDLG_MULTI_DATA_))
*multiDat\BufOffset = 0
*multiDat\FileBuf = of\lpstrFile
*hMulti\l = *multiDat
*multiDat\BufOffset + lstrlen_(ret$) + 1 ;null terminated
*pChar.BYTE = of\lpstrFile + *multiDat\BufOffset
If *pChar\b<>0 ;more than one selected
*multiDat\Dir = AddBackSlash(ret$)
fileTitle$ = PeekS(*multiDat\FileBuf + *multiDat\BufOffset)
*multiDat\BufOffset + lstrlen_(fileTitle$) + 1
ret$ = *multiDat\Dir + filetitle$
EndIf
EndIf
Else ;Cancel or error
ret$ = ""
EndIf
;Single selection
If *hMulti=0 : FreeMemory(of\lpstrFile) : EndIf
ProcedureReturn ret$
EndProcedure
;*hMulti : handle obtained by GetOpenFileName() or GetSaveFileName()
;Returns : next Filename or "". Used in multiple selection.
Procedure.s NextFilename(*hMulti._COMMDLG_MULTI_DATA_)
ret$ = PeekS(*hMulti\FileBuf + *hMulti\BufOffset)
If ret$
*hMulti\BufOffset + lstrlen_(ret$) + 1
ProcedureReturn *hMulti\Dir + ret$
Else ;End
FreeMemory(*hMulti\FileBuf)
FreeMemory(*hMulti)
ProcedureReturn ""
EndIf
EndProcedure
;hwndOwner : window handle of parent window or 0
;title$ : title to be displayed in the caption dialog
;InitialDir$ : initial directory
;filter$ : same as Pattern$ Openfilerequester() parameter
;FilterIndex : 1 based index of the filter to display
;defFile$ : file name used to initialize the File Name edit control, or ""
;defExt$ : extension that will be appended to the file name if the user fails to type an extension, or ""
;*hMulti : controls multi selection, address of a long value. it will be filled on function return with a handle used by NextFileName(), #NULL for single selection
;*iFilter : address of a long value, on function return will be filled by the filter index the user selected, or #NULL.
;*FileTitle : address of a string created with Space(), on function return contains the file title (file name and extension without path information), or #NULL. It only applies to single selection.
;flags : api flags for extra features, some common values: #OFN_FILEMUSTEXIST, #OFN_OVERWRITEPROMPT, or 0
;Returns : first filename selected
Procedure.s GetOpenFileName(hwndOwner, Title$, InitialDir$, filter$, FilterIndex, defFile$, defExt$, *hMulti.LONG, *iFilter.LONG, *FileTitle, flags)
ProcedureReturn cdgAskFileName(hwndOwner, Title$, InitialDir$, filter$, FilterIndex, defFile$, defExt$, *hMulti, *iFilter, *FileTitle, flags, 1)
EndProcedure
Procedure.s GetSaveFileName(hwndOwner, Title$, InitialDir$, filter$, FilterIndex, defFile$, defExt$, *hMulti.LONG, *iFilter.LONG, *FileTitle, flags.l)
ProcedureReturn cdgAskFileName(hwndOwner, Title$, InitialDir$, filter$, FilterIndex, defFile$, defExt$, *hMulti, *iFilter, *FileTitle, flags, 2)
EndProcedure
;- #TEST
;Single
fileTitle$ = Space(#MAX_PATH)
file$ = GetOpenFileName(0, "", "", "All files (*.*)|*.*|MP3 (*.mp3)|*.mp3", 1, "", "", #Null, @iFilter, @fileTitle$, #OFN_FILEMUSTEXIST)
Debug file$
Debug fileTitle$
Debug iFilter
;Multi
file$ = GetOpenFileName(0, "", "", "All files (*.*)|*.*|MP3 (*.mp3)|*.mp3", 1, "", "", @hMulti, #Null, #Null, #OFN_FILEMUSTEXIST)
While file$
Debug file$
file$ = NextFilename(hMulti)
Wend