Save/Load Window

BlitzMax Forums/MaxGUI Module/Save/Load Window

BLaBZ(Posted 2010) [#1]
I'm wondering how I'd go about creating/implementing the standard windows save/load window.

If I had to create the window myself, how would I got about displaying a a folders contents?


degac(Posted 2010) [#2]
Hi

Do you mean the RequestFile() / RequestDir() function or something similar you want to build with standard gadgets?

And these commands are not MaxGUI related but are in the BlitzMax core functions (BRL.system or something - I dont' remember)


SebHoll(Posted 2010) [#3]
I guess you would use a few text-fields, a listbox for displaying filenames, some buttons and a combobox maybe for bookmarked locations and file filters.

You could use the LoadDir$[]() command to retrieve an array of the filenames in a folder, and use this array to populate the listbox yourself.

It's biting off quite a lot though, as file systems work differently on each OS and the built-in file requesters are quite complex and provide lots of useful shell functionality you would have to try and emulate.


Crovean(Posted 2010) [#4]
I found this...

SuperStrict

?Win32
Import PUB.Win32

Private

Const MAX_BUFFER_SIZE:Int = 8192

Const OFN_ALLOWMULTISELECT:Int = 512
Const OFN_CREATEPROMPT:Int = $2000
Const OFN_ENABLEHOOK:Int = 32
Const OFN_ENABLESIZING:Int = $800000
Const OFN_ENABLETEMPLATE:Int = 64
Const OFN_ENABLETEMPLATEHANDLE:Int = 128
Const OFN_EXPLORER:Int = $80000
Const OFN_EXTENSIONDIFFERENT:Int = $400
Const OFN_FILEMUSTEXIST:Int = $1000
Const OFN_HIDEREADONLY:Int = 4
Const OFN_LONGNAMES:Int = $200000
Const OFN_NOCHANGEDIR:Int = 8
Const OFN_NODEREFERENCELINKS:Int = $100000
Const OFN_NOLONGNAMES:Int = $40000
Const OFN_NONETWORKBUTTON:Int = $20000
Const OFN_NOREADONLYRETURN:Int = $8000
Const OFN_NOTESTFILECREATE:Int = $10000
Const OFN_NOVALIDATE:Int = 256
Const OFN_OVERWRITEPROMPT:Int = 2
Const OFN_PATHMUSTEXIST:Int = $800
Const OFN_READONLY:Int = 1
Const OFN_SHAREAWARE:Int = $4000
Const OFN_SHOWHELP:Int = 16
Const OFN_SHAREFALLTHROUGH:Int = 2
Const OFN_SHARENOWARN:Int = 1
Const OFN_SHAREWARN:Int = 0

Type TOpenFileNameA
	Field lStructSize:Int
	Field hwndOwner:Int
	Field hInstance:Int
	Field lpstrFilter:Byte Ptr
	Field lpstrCustomFilter:Int
	Field nMaxCustFilter:Int
	Field nFilterIndex:Int
	Field lpstrFile:Byte Ptr
	Field nMaxFile:Int
	Field lpstrFileTitle:Byte Ptr
	Field nMaxFileTitle:Int
	Field lpstrInitialDir:Byte Ptr
	Field lpstrTitle:Byte Ptr
	Field Flags:Int
	Field nFileOffset:Short
	Field nFileExtension:Short
	Field lpstrDefExt:Byte Ptr
	Field lCustData:Int
	Field lpfnHook:Byte Ptr
	Field lpTemplateName:Byte Ptr
EndType

Extern "Win32"
	Function GetOpenFileName:Int( of:Byte Ptr) = "GetOpenFileNameA@4"
EndExtern

Extern "C"
	Function memcpy( dst:Byte Ptr, src$z, sz:Int)
EndExtern

Public
?

Function RequestMultiFile:String[]( text:String, exts:String = Null, path:String = Null)
	?Not win32
	Local res:String = RequestFile( text, exts, False, path)
	If res.Length <= 0 Then Return Null
	Return [res]
	?
	?Win32
	Global hwndFocus:Int

	' prepare filename / path
	Local file:String, dir:String
	path = path.Replace( "/","\" )
	Local i:Int = path.FindLast( "\" )
	If i <> -1 Then
		dir = path[..i]
		file = path[i+1..]
	Else
		file = path
	EndIf
	' calculate default index of extension in extension list from path name
	Local ext:String, defext:Int,p:Int,q:Int
	p = path.Find(".")
	If (p>-1) Then
		ext = "," + path[p+1..].toLower() + ","
		Local exs:String = exts.toLower()
		exs = exs.Replace(":",":,")
		exs = exs.Replace(";",",;")
		p = exs.find(ext)
		If p >-1 Then
			Local q:Int = -1
			defext = 1
			While True
				q = exs.find(";",q+1)
				If q > p Then Exit
				If q = -1 Then
					defext = 0
					Exit
				EndIf
				defext :+ 1
			Wend
		EndIf
	EndIf
	If exts Then
		If exts.Find(":") = -1 Then
			exts = "Files~0*." + exts
		Else
			exts = exts.Replace(":","~0*.")
		EndIf
		exts = exts.Replace(";","~0")
		exts = exts.Replace(",",";*.") + "~0"
	EndIf

	' allocate cstrings
	Local textp:Byte Ptr = text.ToCString()
	Local extsp:Byte Ptr = exts.ToCString()
	Local dirp:Byte Ptr
	If dir.Length > 0 Then dirp = dir.ToCString()

	' prepare file buffer
	Local buf:Byte[MAX_BUFFER_SIZE]
	memcpy( buf, file, file.Length)

	' initialize dialog options
	Local of:TOpenFileNameA = New TOpenFileNameA
	of.lStructSize = SizeOf(TOpenFileNameA)
	of.hwndOwner = GetActiveWindow()
	of.lpstrTitle = textp
	of.lpstrFilter = extsp
	of.nFilterIndex = defext
	of.lpstrFile = buf
	of.lpstrInitialDir = dirp
	of.nMaxFile = buf.Length
	of.Flags = OFN_HIDEREADONLY | OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT | OFN_EXPLORER ' | OFN_LONGNAMES

	' display dialog
	hwndFocus = GetFocus()
	Local n:Int = GetOpenFileName( of)
	SetFocus( hwndFocus)

	' free cstrings
	MemFree textp
	MemFree extsp
	If dirp Then MemFree dirp

	' failure ?
	If n <= 0 Then Return Null

	' count the number of files
	Local s:Byte Ptr = buf
	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

	' extract filenames into String array
	If count = 1 Then
		Return [ String.FromCString( buf) ]
	Else
		Local result:String[] = New String[count]
		s = buf
		For Local i:Int = 0 Until count
			result[i] = String.FromCString( s)
			s :+ result[i].Length + 1
		Next
		result[0] :+ "\"
		Return result
	EndIf
	?
EndFunction