/// <summary> /// Specifies which properties will be collected in the save dialog. /// </summary> /// <param name="appendDefault">True to show default properties for the currently selected /// filetype in addition to the properties specified by propertyList. False to show only properties /// specified by pList. /// <param name="propertyList">List of properties to collect. This parameter can be null.</param> /// </param> /// <remarks> /// SetCollectedPropertyKeys can be called at any time before the dialog is displayed or while it /// is visible. If different properties are to be collected depending on the chosen filetype, /// then SetCollectedProperties can be called in response to CommonFileDialog::FileTypeChanged event. /// Note: By default, no properties are collected in the save dialog. /// </remarks> public void SetCollectedPropertyKeys(bool appendDefault, params PropertyKey[] propertyList) { // Loop through all our property keys and create a semicolon-delimited property list string. // The string we pass to PSGetPropertyDescriptionListFromString must // start with "prop:", followed a list of canonical names for each // property that is to collected. #pragma warning disable CS8073 // The result of the expression is always 'true' since a value of type 'PropertyKey' is never equal to 'null' of type 'PropertyKey?' if (propertyList != null && propertyList.Length > 0 && propertyList[0] != null) #pragma warning restore CS8073 // The result of the expression is always 'true' since a value of type 'PropertyKey' is never equal to 'null' of type 'PropertyKey?' { StringBuilder sb = new StringBuilder("prop:"); foreach (PropertyKey key in propertyList) { string canonicalName = ShellPropertyDescriptionsCache.Cache.GetPropertyDescription(key).CanonicalName; if (!string.IsNullOrEmpty(canonicalName)) { sb.AppendFormat("{0};", canonicalName); } } Guid guid = new Guid(ShellIIDGuid.IPropertyDescriptionList); IPropertyDescriptionList propertyDescriptionList = null; try { int hr = PropertySystemNativeMethods.PSGetPropertyDescriptionListFromString( sb.ToString(), ref guid, out propertyDescriptionList); // If we get a IPropertyDescriptionList, setit on the native dialog. if (CoreErrorHelper.Succeeded(hr)) { InitializeNativeFileDialog(); IFileSaveDialog nativeDialog = GetNativeFileDialog() as IFileSaveDialog; if (nativeDialog != null) { hr = nativeDialog.SetCollectedProperties(propertyDescriptionList, appendDefault); if (!CoreErrorHelper.Succeeded(hr)) { throw new ShellException(hr); } } } } finally { if (propertyDescriptionList != null) { Marshal.ReleaseComObject(propertyDescriptionList); } } } }
/// <summary> /// Sets an item to appear as the initial entry in a <b>Save As</b> dialog. /// </summary> /// <param name="item">The initial entry to be set in the dialog.</param> /// <remarks>The name of the item is displayed in the file name edit box, /// and the containing folder is opened in the view. This would generally be /// used when the application is saving an item that already exists.</remarks> public void SetSaveAsItem(ShellObject item) { if (item == null) { throw new ArgumentNullException("item"); } InitializeNativeFileDialog(); IFileSaveDialog nativeDialog = GetNativeFileDialog() as IFileSaveDialog; // Get the native IShellItem from ShellObject if (nativeDialog != null) { nativeDialog.SetSaveAsItem(item.NativeShellItem); } }
/// <summary> /// Sets an item to appear as the initial entry in a <b>Save As</b> dialog. /// </summary> /// <param name="item">The initial entry to be set in the dialog.</param> /// <remarks>The name of the item is displayed in the file name edit box, /// and the containing folder is opened in the view. This would generally be /// used when the application is saving an item that already exists.</remarks> public void SetSaveAsItem(ShellObject item) { IFileSaveDialog nativeDialog = null; if (nativeDialog == null) { InitializeNativeFileDialog(); nativeDialog = GetNativeFileDialog() as IFileSaveDialog; } // Get the native IShellItem from ShellObject if (nativeDialog != null) { nativeDialog.SetSaveAsItem(item.NativeShellItem); } }
protected override void PerformAction(object parameter) { var photo = parameter as FacebookPhoto; if (photo == null) { return; } string defaultFileName = "Facebook Photo"; if (photo.Album != null) { defaultFileName = photo.Album.Title + " (" + (photo.Album.Photos.IndexOf(photo) + 1) + ")"; } string filePath = null; if (Utility.IsOSVistaOrNewer) { IFileSaveDialog pFileSaveDialog = null; try { pFileSaveDialog = CLSID.CoCreateInstance <IFileSaveDialog>(CLSID.FileSaveDialog); pFileSaveDialog.SetOptions(pFileSaveDialog.GetOptions() | FOS.FORCEFILESYSTEM | FOS.OVERWRITEPROMPT); pFileSaveDialog.SetTitle("Select where to save the photo"); pFileSaveDialog.SetOkButtonLabel("Save Photo"); var filterspec = new COMDLG_FILTERSPEC { pszName = "Images", pszSpec = "*.jpg;*.png;*.bmp;*.gif" }; pFileSaveDialog.SetFileTypes(1, ref filterspec); pFileSaveDialog.SetFileName(defaultFileName); Guid clientId = _SavePhotoId; pFileSaveDialog.SetClientGuid(ref clientId); IShellItem pItem = null; try { pItem = ShellUtil.GetShellItemForPath(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)); pFileSaveDialog.SetDefaultFolder(pItem); } finally { Utility.SafeRelease(ref pItem); } HRESULT hr = pFileSaveDialog.Show(new WindowInteropHelper(Application.Current.MainWindow).Handle); if (hr.Failed) { Assert.AreEqual((HRESULT)Win32Error.ERROR_CANCELLED, hr); return; } pItem = null; try { pItem = pFileSaveDialog.GetResult(); filePath = ShellUtil.GetPathFromShellItem(pItem); } finally { Utility.SafeRelease(ref pItem); } } finally { Utility.SafeRelease(ref pFileSaveDialog); } } else { var saveFileDialog = new Microsoft.Win32.SaveFileDialog { Filter = "Image Files|*.jpg;*.png;*.bmp;*.gif", FileName = defaultFileName, InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), }; if (saveFileDialog.ShowDialog(Application.Current.MainWindow) != true) { return; } filePath = saveFileDialog.FileName; } FacebookImageSaveOptions fiso = FacebookImageSaveOptions.FindBetterName; // We told the file dialog to prompt about overwriting, so if the user specified a location // with a file extension and the file already exists, prepare to overwrite. // This isn't quite right because the file extension may be different, so we may overwrite a jpg // when it was asked to be a gif, but it's not a likely scenario. if (System.IO.File.Exists(filePath)) { fiso = FacebookImageSaveOptions.Overwrite; } photo.Image.SaveToFile(FacebookImageDimensions.Big, filePath, true, fiso, _OnPhotoSaveProgressCallback, null); }
private static String ShowDialogInner(IFileSaveDialog dialog, IntPtr parentHWnd, String title, String initialDirectory, String defaultFileName, IReadOnlyCollection <Filter> filters, Int32 selectedFilterZeroBasedIndex = -1) { FileOpenOptions flags = FileOpenOptions.NoTestFileCreate | FileOpenOptions.PathMustExist | FileOpenOptions.ForceFilesystem | FileOpenOptions.OverwritePrompt; dialog.SetOptions(flags); if (title != null) { dialog.SetTitle(title); } if (initialDirectory != null) { IShellItem2 initialDirectoryShellItem = Utility.ParseShellItem2Name(initialDirectory); if (initialDirectoryShellItem != null) { dialog.SetFolder(initialDirectoryShellItem); } } // if( initialSaveAsItem != null ) // { // IShellItem2 initialSaveAsItemShellItem = Utility.ParseShellItem2Name( initialDirectory ); // if( initialSaveAsItemShellItem != null ) // { // dialog.SetSaveAsItem( initialSaveAsItemShellItem ); // } // } if (defaultFileName != null) { dialog.SetFileName(defaultFileName); } Utility.SetFilters(dialog, filters, selectedFilterZeroBasedIndex); HResult result = dialog.Show(parentHWnd); HResult cancelledAsHResult = Utility.HResultFromWin32((int)HResult.Win32ErrorCanceled); if (result == cancelledAsHResult) { // Cancelled return(null); } else { // OK IShellItem selectedItem; dialog.GetResult(out selectedItem); if (selectedItem != null) { return(Utility.GetFileNameFromShellItem(selectedItem)); } else { return(null); } } }
private static String ShowDialogInner(IFileSaveDialog dialog, IntPtr parentWindowHandle, String title, String initialDirectory, String defaultFileName, IReadOnlyCollection <Filter> filters, Int32 selectedFilterZeroBasedIndex = -1) { FileOpenOptions flags = FileOpenOptions.NoTestFileCreate | FileOpenOptions.PathMustExist | FileOpenOptions.ForceFilesystem | FileOpenOptions.OverwritePrompt; dialog.SetOptions(flags); if (title != null) { dialog.SetTitle(title); } if (initialDirectory != null) { IShellItem2 initialDirectoryShellItem = Utility.ParseShellItem2Name(initialDirectory); if (initialDirectoryShellItem != null) { dialog.SetFolder(initialDirectoryShellItem); } } // if( initialSaveAsItem != null ) // { // IShellItem2 initialSaveAsItemShellItem = Utility.ParseShellItem2Name( initialDirectory ); // if( initialSaveAsItemShellItem != null ) // { // dialog.SetSaveAsItem( initialSaveAsItemShellItem ); // } // } if (defaultFileName != null) { dialog.SetFileName(defaultFileName); } Utility.SetFilters(dialog, filters, selectedFilterZeroBasedIndex); HResult result = dialog.Show(parentWindowHandle); if (result == HResult.Ok) { IShellItem selectedItem; dialog.GetResult(out selectedItem); if (selectedItem != null) { return(Utility.GetFileNameFromShellItem(selectedItem)); } else { return(null); } } else if (result == HResult_Win32_Canceled) { // Cancelled by user. return(null); } else { UInt32 win32ErrorCode = Utility.Win32ErrorFromHResult((UInt32)result); throw new Win32Exception(error: (Int32)win32ErrorCode); } }
/// <summary> /// Specifies which properties will be collected in the save dialog. /// </summary> /// <param name="appendDefault">True to show default properties for the currently selected /// filetype in addition to the properties specified by propertyList. False to show only properties /// specified by pList. /// <param name="propertyList">List of properties to collect. This parameter can be null.</param> /// </param> /// <remarks> /// SetCollectedPropertyKeys can be called at any time before the dialog is displayed or while it /// is visible. If different properties are to be collected depending on the chosen filetype, /// then SetCollectedProperties can be called in response to CommonFileDialog::FileTypeChanged event. /// Note: By default, no properties are collected in the save dialog. /// </remarks> public void SetCollectedPropertyKeys(bool appendDefault, params PropertyKey[] propertyList) { string propertyListStr = null; // Loop through all our property keys and create a semicolon-delimited property list string. if (propertyList != null && propertyList.Length > 0 && propertyList[0] != null) { foreach (PropertyKey key in propertyList) { string canonicalName = ShellPropertyDescriptionsCache.Cache.GetPropertyDescription(key).CanonicalName; // The string we pass to PSGetPropertyDescriptionListFromString must // start with "prop:", followed a list of canonical names for each // property that is to collected. // // Add "prop:" at the start of the string if we are starting our for loop. if (propertyListStr == null) { propertyListStr = "prop:"; } // For each property, append the canonical name, followed by a semicolon if (!string.IsNullOrEmpty(canonicalName)) { propertyListStr += canonicalName + ";"; } } } // If the string was created correctly, get IPropertyDescriptionList for it if (!string.IsNullOrEmpty(propertyListStr)) { Guid guid = new Guid(ShellIIDGuid.IPropertyDescriptionList); IPropertyDescriptionList propertyDescriptionList = null; try { int hr = PropertySystemNativeMethods.PSGetPropertyDescriptionListFromString(propertyListStr, ref guid, out propertyDescriptionList); // If we get a IPropertyDescriptionList, setit on the native dialog. if (CoreErrorHelper.Succeeded(hr)) { IFileSaveDialog nativeDialog = null; if (nativeDialog == null) { InitializeNativeFileDialog(); nativeDialog = GetNativeFileDialog() as IFileSaveDialog; } if (nativeDialog != null) { hr = nativeDialog.SetCollectedProperties(propertyDescriptionList, appendDefault); if (!CoreErrorHelper.Succeeded(hr)) { Marshal.ThrowExceptionForHR(hr); } } } } finally { if (propertyDescriptionList != null) { Marshal.ReleaseComObject(propertyDescriptionList); } } } }
private static String ShowDialogInner(IFileSaveDialog dialog, IntPtr parentHWnd, String title, String initialDirectory, String defaultFileName, IReadOnlyCollection <Filter> filters, Int32 selectedFilterZeroBasedIndex = -1) #endif { FileOpenOptions flags = FileOpenOptions.NoTestFileCreate | FileOpenOptions.PathMustExist | FileOpenOptions.ForceFilesystem | FileOpenOptions.OverwritePrompt; dialog.SetOptions(flags); if (title != null) { dialog.SetTitle(title); } if (initialDirectory != null) { #if NETCOREAPP3_1_OR_GREATER IShellItem2?initialDirectoryShellItem = Utility.ParseShellItem2Name(initialDirectory); #else IShellItem2 initialDirectoryShellItem = Utility.ParseShellItem2Name(initialDirectory); #endif if (initialDirectoryShellItem != null) { dialog.SetFolder(initialDirectoryShellItem); } } // if( initialSaveAsItem != null ) // { // IShellItem2 initialSaveAsItemShellItem = Utility.ParseShellItem2Name( initialDirectory ); // if( initialSaveAsItemShellItem != null ) // { // dialog.SetSaveAsItem( initialSaveAsItemShellItem ); // } // } if (defaultFileName != null) { dialog.SetFileName(defaultFileName); } Utility.SetFilters(dialog, filters, selectedFilterZeroBasedIndex); // HResult hr = dialog.Show(parentHWnd); if (hr.ValidateDialogShowHResult()) { dialog.GetResult(out IShellItem selectedItem); if (selectedItem != null) { return(Utility.GetFileNameFromShellItem(selectedItem)); } else { return(null); } } else { // User cancelled. return(null); } }
private static String?ShowDialogInner(IFileSaveDialog dialog, IntPtr parentHWnd, String?title, String?initialDirectory, String?defaultFileName, IReadOnlyCollection <Filter>?filters, Int32 selectedFilterZeroBasedIndex = -1)