RequestMultiFile

BlitzMax Forums/BlitzMax Programming/RequestMultiFile

Heres a RequestMultiFile() function for those who need it (i got tired of the MaxIDE not having it ;)

WIN32 ONLY!! and you need MinGW to compile the C file.

It is allmost the same code as RequestFile() except it can handle more than 1 file and there is only the OPEN mode.

RequestMultiFile.bmx
SuperStrict

?MacOS
' no multi file requester for you
Function RequestMultiFile:String[]( text:String,exts:String, path:String = "")
	Local res:String = RequestFile( test, exts, False, path)
	If res.Length <= 0 Then Return Null
	Return [res]
EndFunction

?Linux	
' no multi file requester for you either
Function RequestMultiFile:String[]( text:String,exts:String, path:String = "")
	Local res:String = RequestFile( test, exts, False, path)
	If res.Length <= 0 Then Return Null
	Return [res]
EndFunction

?Win32

Import "RequestMultiFile.c"

Private

Extern "C"
	Function request_multi_file:Int( text$z, exts$z, file$z, dir$z, buf:Byte Ptr, bufsz:Int)
EndExtern

Function EatFileNames:String[]( p:Byte Ptr)
	Local s:Byte Ptr = p
	Local count:Int = 0
	While s[0] <> 0
		If s[1] = 0 Then
			count :+ 1
			s :+ 2
			If s[0] = 0 Then Exit
		EndIf
		s :+ 1
	Wend	
	If count <= 0 Then Return Null
	Local result:String[] = New String[count]	
	s = p
	For Local i:Int = 0 Until count
		result[i] = String.FromCString( s)
		s :+ result[i].Length + 1
	Next
	Return result
EndFunction

Public

Function RequestMultiFile:String[]( text:String,exts:String, path:String = "")
	Local file:String,dir:String
	
	path=path.Replace( "/","" )
	
	Local i:Int=path.FindLast( "" )
	If i<>-1
		dir=path[..i]
		file=path[i+1..]
	Else
		file=path
	EndIf

	If exts
		If exts.Find(":")=-1
			exts="Files~0*."+exts
		Else
			exts=exts.Replace(":","~0*.")
		EndIf
		exts=exts.Replace(";","~0")
		exts=exts.Replace(",",";*.")+"~0"		
	EndIf
	
	Local buf:Byte[8192]
	
	If request_multi_file( text,exts, file,dir, buf,buf.length) Then Return EatFileNames( buf)
EndFunction
?

RequestMultiFile.c
#include <shlobj.h>
#include <brl.mod/blitz.mod/blitz.h>

static HWND focHwnd_multi;

int request_multi_file( const char *text,const char *exts,const char *file,const char *dir,char *buf,int bufsz ) {
	int n;
	OPENFILENAME of={sizeof(of)};
	
	strcpy( buf,file );
	
	of.hwndOwner=GetActiveWindow();
	of.lpstrTitle=text;
	of.lpstrFilter=exts;
	of.lpstrFile=buf;
	of.lpstrInitialDir=dir[0] ? dir : 0;
	of.nMaxFile=bufsz;
	of.Flags=OFN_HIDEREADONLY|OFN_NOCHANGEDIR|OFN_PATHMUSTEXIST|OFN_FILEMUSTEXIST|OFN_ALLOWMULTISELECT|OFN_EXPLORER;
	
	focHwnd_multi=GetFocus();
	n=GetOpenFileName( &of );	
	SetFocus( focHwnd_multi );
	
	return n ? 1 : 0;
}


It returns an array of strings. if there is only 1filename selected, the whole path+filename wil be returned
in index 0.
If there is more than 1 filename selected, the path will be at index 0 and the filenames will be at
index 1 -> N

Usage
Local files:String[] = RequestMultiFile( "Open Files", "All Files (*.*):*;Source Files (*.bmx | *.c | *.h):bmx,c,h")
If files.Length = 1 Then
    ' only 1 filename
ElseIf files.Length > 1 Then
    ' path + several filenames
EndIf


Great! It's really usefull, thanks a lot!!

I think it should become an official BMX module/function.
How do you think?

I lost my original copy of this so i had to find it here ;)

Bumping it because i added it to the code archives and updated it with the latest code from RequestFile() and removed the need for MinGW (in the hopes it can be added to the MaxIDE Community Edition some day)

MAXGUI: Multiple file requester

EDIT: this should probably be moved to the MaxGUI category (it was created before its time hehe)