Silverfrost Forums

Welcome to our forums

Add support for Common Item Dialog

23 Aug 2014 7:13 #14489

It would be nice to have access to more modern looking file dialogs from FTN95. Using IFileDialog interface is not as complicated as it first seems and should give programs more consistent and modern look.

Below is a minimum example for a simple folder selection dialog in MiniBASIC syntax and sample project available here.

export GetFolder
func GetFolder(string title, string buffer)
	CoInitialize(NULL)
	IFileOpenDIalog *pfd = NULL
	HRESULT hr = CoCreateInstance(_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, _IID_IFileOpenDialog, &pfd)
	if hr >= 0
		FILEOPENDIALOGOPTIONS options
		hr = pfd->GetOptions(&options)
		hr = pfd->SetOptions(options|FOS_PICKFOLDERS)
		hr = pfd->SetTitle(A2W(title))
		hr = pfd->Show(0)
		if hr >= 0
			IShellItem *psi
			wstring *pwszName
			hr = pfd->GetResult(&psi)
			if hr >= 0
				hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pwszName)
				buffer = W2A(#pwszName)
				CoTaskMemFree(pwszName)
				psi->Release()
			endif
		endif
		hr = pfd->Release()
	endif
	CoUninitialize()
endf
23 Aug 2014 9:56 #14490

Thanks for the feedback. I will add this to the wish list.

24 Aug 2014 6:54 #14493

I updated FTN95 sample project to support open/select file dialog.

Only difficulty was that SetFileTypes() method expects to get pointers to file filter information and only supports wide character arrays.

type wstr
	wstring str
endtype


type COMDLG_FILTERSPEC
	wstring *name
	wstring *spec
endtype


func count(string str), int
	int pos = instrr(str,',')
	int pos2 = len(str)
	int count = 0
	if len(str) > 0
		count += 1
		while pos
			count += 1
			pos2 = pos-1
			pos = instrr(pos-1, str, ',')
		endwhile
	endif

	return count
endf


export GetFile
func GetFile(string title, string buffer, string names, string specs)
	CoInitialize(NULL)

	' Calculate required array dimensions
	int c = count(names)
	if count(specs) <> c
		buffer = ''
		return
	endif

	' Allocate memory for the array of COMDLG_FILTERSPEC information
	COMDLG_FILTERSPEC *rgFileTypes = new(COMDLG_FILTERSPEC, c)
	' Alllocate memory for the two arrays of wide character strings
	wstr *n = new(wstr, c)
	wstr *s = new(wstr, c)

	' Next split the input character strings, 
	' convert to wide character strings and store into allocated arrays.
	' Also need to set pointers in COMDLG_FILTERSPEC structure array to point
	' into corresponding wide character array indices.
	int pos = instrr(names,',')
	int pos2 = len(names)
	int i = 0
	while pos
		#n[i].str = a2w(ltrim$(mid$(names,pos+1,pos2-pos)))
		i += 1 
		pos2 = pos-1
		pos = instrr(pos-1,names,',')
	endwhile
	#n[i].str = a2w(ltrim$(mid$(names,pos+1,pos2-pos)))

	for i = 0 to c-1
		#rgFileTypes[c-1-i].name = #n[i].str
	next i

	pos = instrr(specs,',')
	pos2 = len(specs)
	i = 0
	while pos
		#s[i].str = a2w(ltrim$(mid$(specs,pos+1,pos2-pos)))
		i += 1 
		pos2 = pos-1
		pos = instrr(pos-1,specs,',')
	endwhile
	#s[i].str = a2w(ltrim$(mid$(specs,pos+1,pos2-pos)))

	for i = 0 to c-1
		#rgFileTypes[c-1-i].spec = #s[i].str
	next i

	IFileOpenDIalog *pfd = NULL
	HRESULT hr = CoCreateInstance(_CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, _IID_IFileOpenDialog, &pfd)
	if hr >= 0
		hr = pfd->SetFileTypes(c,#rgFileTypes[0])
		hr = pfd->SetTitle(a2w(title)) ' Need to convert char to wchar
		hr = pfd->Show(0)
		if hr >= 0
			IShellItem *psi
			wstring *pwszName
			hr = pfd->GetResult(&psi)
			if hr >= 0
				hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pwszName)
				buffer = w2a(#pwszName) ' Convert from wchar to char and store into buffer
				CoTaskMemFree(pwszName)
				psi->Release()
			endif
		endif
		hr = pfd->Release()
	endif

	' Delete allocated memory and cleanup
	delete n
	delete s
	delete rgFileTypes

	CoUninitialize()
endf
25 Aug 2014 3:54 #14498

Does this address the file open dialogue problem that occurred with the introduction of Windows 7 ? If it does, it would be a very welcome change.

There are numerous posts from around 2011 which addressed this problem, which I overcame by reducing the used memory to about 1.4gb for programs using the old windows file open dialogue that clearwin used.

John

Please login to reply.