1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-16 23:34:10 +02:00

Merge vista code into main FileDialog

This commit is contained in:
Brian Fiete 2021-12-17 07:12:27 -05:00
parent 77c3ab596f
commit 5cc6f13af4
2 changed files with 124 additions and 138 deletions

View file

@ -451,6 +451,130 @@ namespace System.IO
return 0;
}
//TODO: Add ProcessFileNames for validation
protected abstract Result<Windows.COM_IFileDialog*> CreateVistaDialog();
private Result<DialogResult> TryRunDialogVista(Windows.HWnd hWndOwner)
{
Windows.COM_IFileDialog* dialog;
if (!(CreateVistaDialog() case .Ok(out dialog)))
return .Err;
OnBeforeVistaDialog(dialog);
dialog.VT.Show(dialog, hWndOwner);
List<String> files = scope .();
ProcessVistaFiles(dialog, files);
DeleteContainerAndItems!(mFileNames);
mFileNames = new String[files.Count];
files.CopyTo(mFileNames);
dialog.VT.Release(dialog);
return .Ok(files.IsEmpty ? .Cancel : .OK);
}
private void OnBeforeVistaDialog(Windows.COM_IFileDialog* dialog)
{
dialog.VT.SetDefaultExtension(dialog, DefaultExt.ToScopedNativeWChar!());
if (mFileNames != null && !mFileNames.IsEmpty)
dialog.VT.SetFileName(dialog, mFileNames[0].ToScopedNativeWChar!());
if (!String.IsNullOrEmpty(mInitialDir))
{
Windows.COM_IShellItem* folderShellItem = null;
Windows.SHCreateItemFromParsingName(mInitialDir.ToScopedNativeWChar!(), null, Windows.COM_IShellItem.sIID, (void**)&folderShellItem);
if (folderShellItem != null)
{
dialog.VT.SetDefaultFolder(dialog, folderShellItem);
dialog.VT.SetFolder(dialog, folderShellItem);
folderShellItem.VT.Release(folderShellItem);
}
}
dialog.VT.SetTitle(dialog, mTitle.ToScopedNativeWChar!());
dialog.VT.SetOptions(dialog, GetOptions());
SetFileTypes(dialog);
}
private Windows.COM_IFileDialog.FOS GetOptions()
{
const Windows.COM_IFileDialog.FOS BlittableOptions =
Windows.COM_IFileDialog.FOS.OVERWRITEPROMPT
| Windows.COM_IFileDialog.FOS.NOCHANGEDIR
| Windows.COM_IFileDialog.FOS.NOVALIDATE
| Windows.COM_IFileDialog.FOS.ALLOWMULTISELECT
| Windows.COM_IFileDialog.FOS.PATHMUSTEXIST
| Windows.COM_IFileDialog.FOS.FILEMUSTEXIST
| Windows.COM_IFileDialog.FOS.CREATEPROMPT
| Windows.COM_IFileDialog.FOS.NODEREFERENCELINKS;
const int32 UnexpectedOptions =
(int32)(Windows.OFN_SHOWHELP // If ShowHelp is true, we don't use the Vista Dialog
| Windows.OFN_ENABLEHOOK // These shouldn't be set in options (only set in the flags for the legacy dialog)
| Windows.OFN_ENABLESIZING // These shouldn't be set in options (only set in the flags for the legacy dialog)
| Windows.OFN_EXPLORER); // These shouldn't be set in options (only set in the flags for the legacy dialog)
Debug.Assert((UnexpectedOptions & mOptions) == 0, "Unexpected FileDialog options");
Windows.COM_IFileDialog.FOS ret = (Windows.COM_IFileDialog.FOS)mOptions & BlittableOptions;
// Force no mini mode for the SaveFileDialog
ret |= Windows.COM_IFileDialog.FOS.DEFAULTNOMINIMODE;
// Make sure that the Open dialog allows the user to specify
// non-file system locations. This flag will cause the dialog to copy the resource
// to a local cache (Temporary Internet Files), and return that path instead. This
// also affects the Save dialog by disallowing navigation to these areas.
// An example of a non-file system location is a URL (http://), or a file stored on
// a digital camera that is not mapped to a drive letter.
// This reproduces the behavior of the "classic" Open and Save dialogs.
ret |= Windows.COM_IFileDialog.FOS.FORCEFILESYSTEM;
return ret;
}
protected abstract void ProcessVistaFiles(Windows.COM_IFileDialog* dialog, List<String> files);
private Result<void> SetFileTypes(Windows.COM_IFileDialog* dialog)
{
List<Windows.COMDLG_FILTERSPEC> filterItems = scope .();
// Expected input types
// "Text files (*.txt)|*.txt|All files (*.*)|*.*"
// "Image Files(*.BMP;*.JPG;*.GIF)|*.BMP;*.JPG;*.GIF|All files (*.*)|*.*"
if (!String.IsNullOrEmpty(mFilter))
{
StringView[] tokens = mFilter.Split!('|');
if (0 == tokens.Count % 2)
{
// All even numbered tokens should be labels
// Odd numbered tokens are the associated extensions
for (int i = 1; i < tokens.Count; i += 2)
{
Windows.COMDLG_FILTERSPEC ext;
ext.pszSpec = tokens[i].ToScopedNativeWChar!::(); // This may be a semicolon delimited list of extensions (that's ok)
ext.pszName = tokens[i - 1].ToScopedNativeWChar!::();
filterItems.Add(ext);
}
}
}
if (filterItems.IsEmpty)
return .Ok;
Windows.COM_IUnknown.HResult hr = dialog.VT.SetFileTypes(dialog, (uint32)filterItems.Count, filterItems.Ptr);
if (hr.Failed)
return .Err;
hr = dialog.VT.SetFileTypeIndex(dialog, (uint32)mFilterIndex);
if (hr.Failed)
return .Err;
return .Ok;
}
}
}
#endif