MaxGUI: Select multiple files in Filerequester?

BlitzMax Forums/BlitzMax Programming/MaxGUI: Select multiple files in Filerequester?

maverick69(Posted 2005) [#1]
I know there is the RequestFile Command to let the user select a file to open. Is it possible to open a requester who lets the user select multiple files? I didn't find anything in the docs!


Perturbatio(Posted 2005) [#2]
In win32, the default requestfile function doesn't support this, but you can add the option to it.

It requires some changes to several files:
BACKUP THE FILES YOU ARE ABOUT TO CHANGE BEFORE DOING THIS!!!
in system.bmx change the RequestFile function to:
Function RequestFile$( text$,extensions$="",save_flag=False,initial_path$="",allow_multiselect = False )
	Return Driver.RequestFile( text,extensions,save_flag,initial_path, allow_multiselect )
End Function

in system.win32.bmx, in the extern block, change the bbSystemRequestFile line to:
Function bbSystemRequestFile( text$z,exts$z,save,file$z,dir$z,buf:Byte Ptr,bufsz, multisel:Int )

in system.win32.bmx change the RequestFile Method of TWin32SystemDriver to:
	Method RequestFile$( text$,exts$,save,path$, allow_multiselect:Int )
		Local file$,dir$
		
		path=path.Replace( "/","\" )
		
		Local i=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[4096]
		
		If bbSystemRequestFile( text,exts,save,file,dir,buf,buf.length,allow_multiselect) 
			For Local count:Int = 0 To Len(Buf)-1
				If buf[count] = 0 Then 'last two should be null
					If buf[count+1] <> 0 Then buf[count] = 59 'asc(";") 
				EndIf
			Next
			Return String.FromCString(buf).Replace(Chr(0), ";")
		EndIf

	End Method

in system.win32.c change bbSystemRequestFile to:
int bbSystemRequestFile( const char *text,const char *exts,int save,const char *file,const char *dir,char *buf,int bufsz, int multisel){
	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;
	
	beginPanel();
	
	if( save ){
		of.Flags|=OFN_OVERWRITEPROMPT;
		n=GetSaveFileName( &of );
	}else{
		of.Flags|=OFN_FILEMUSTEXIST;
		if (multisel){
			of.Flags|=OFN_ALLOWMULTISELECT;
		}
		n=GetOpenFileName( &of );
	}
	
	endPanel();
	
	return n ? 1 : 0;
}

in driver.bmx change Method RequestFile to:
	Method RequestFile$( text$,exts$,save,file$,allow_multiselect ) Abstract


If you have multiple files selected, it will return a string containing the base path of the files chosen followed by the names of all the chosen files separated by semi-colons.

You will need to loop through this string to get the individual files (you can use the code archives to get code to do this quickly).

------------------------------------------------


Sample usage:
' requestfile.bmx

filter$="Image Files:png,jpg,bmp;Text Files:txt;All Files:*"
filename$=RequestFile( "Select graphic file to open",filter$,False, "", True)

Print filename




Perturbatio(Posted 2005) [#3]
note that driver.bmx is used by all three OS's so the change will probably break something if this is done to a non-win32 platform.

(I suppose you could encapsulate the change in the abstract type within a ?Win32 ? block and have the old one defined for the others OS's)

The same applies to system.bmx


Jake L.(Posted 2007) [#4]
It would be really nice to get this working - maybe the tweak got broken due to newer max-versions.

I tweaked the above files and ran a "bmk makemods brl.system" without errors. Trying to use this from within Max gives me an error:

c:/BlitzMax/mod/brl.mod/system.mod/system.release.win32.x86.a(system.win32.bmx.release.win32.x86.o)(code+0x1b5): undefined reference to `bbSystemProceed'

Anyone using this tweak with the current bmax-release?

Jake