Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions ShellFileDialogs.Demo/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ internal static class Program
[STAThread] // <-- " If the attribute is not present, the application uses the multithreaded apartment model, which is not supported for Windows Forms."
public static Int32 Main( String[] args )
{
Console.WriteLine( "Now showing a folder browser dialog. Press [Enter] to continue." );
Console.WriteLine( "Now showing a folder browser dialog to select a single folder. Press [Enter] to continue." );
_ = Console.ReadLine();

// FolderBrowserDialog
{
String selectedDirectory = FolderBrowserDialog.ShowDialog( parentHWnd: IntPtr.Zero, title: "Select a folder...", initialDirectory: null );
String selectedDirectory = FolderBrowserDialog.ShowSingleSelectDialog( parentHWnd: IntPtr.Zero, title: "Select a folder...", initialDirectory: null );
if( selectedDirectory != null )
{
Console.WriteLine( "Folder browser. Selected directory: \"{0}\".", selectedDirectory );
Expand All @@ -25,6 +25,26 @@ public static Int32 Main( String[] args )
}
}

Console.WriteLine( "Now showing a folder browser dialog to select multiple folders. Press [Enter] to continue.");
_ = Console.ReadLine();

// FolderBrowserDialog
{
IReadOnlyList<String> selectedDirectories = FolderBrowserDialog.ShowMultiSelectDialog( parentHWnd: IntPtr.Zero, title: "Select multiple folders...", initialDirectory: null );
if ( selectedDirectories != null )
{
Console.WriteLine( "Folder browser. Selected directories:" );
foreach ( String directory in selectedDirectories )
{
Console.WriteLine( directory );
}
}
else
{
Console.WriteLine( "Folder browser. Cancelled." );
}
}

Console.WriteLine( "Now showing an open-file dialog to select multiple files (with multiple extension filters). Press [Enter] to continue." );
_ = Console.ReadLine();

Expand Down
146 changes: 85 additions & 61 deletions ShellFileDialogs/Dialogs/FolderBrowserDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,109 @@

namespace ShellFileDialogs
{
public static class FolderBrowserDialog
{
/// <summary>Shows the folder browser dialog. Returns <see langword="null"/> if the user cancelled the dialog. Otherwise returns the selected path.</summary>
public static class FolderBrowserDialog
{
/// <summary>Shows the folder browser dialog. Returns <see langword="null"/> if the user cancelled the dialog. Otherwise returns the selected path.</summary>
#if NETCOREAPP3_1_OR_GREATER
public static String? ShowDialog(IntPtr parentHWnd, String? title, String? initialDirectory)
public static IReadOnlyList<String>? ShowMultiSelectDialog(IntPtr parentHWnd, String? title, String? initialDirectory)
#else
public static String ShowDialog(IntPtr parentHWnd, String title, String initialDirectory)
public static IReadOnlyList<String> ShowMultiSelectDialog(IntPtr parentHWnd, String title, String initialDirectory)
#endif
{
NativeFileOpenDialog nfod = new NativeFileOpenDialog();
try
{
return ShowDialogInner( nfod, parentHWnd, title, initialDirectory );
}
finally
{
_ = Marshal.ReleaseComObject( nfod );
}
}
{
return ShowDialog(parentHWnd, title, initialDirectory, FileOpenOptions.AllowMultiSelect);
}

/// <summary>Shows the folder browser dialog. Returns <see langword="null"/> if the user cancelled the dialog. Otherwise returns the selected path.</summary>
#if NETCOREAPP3_1_OR_GREATER
private static String? ShowDialogInner(IFileOpenDialog dialog, IntPtr parentHWnd, String? title, String? initialDirectory)
public static String? ShowSingleSelectDialog(IntPtr parentHWnd, String? title, String? initialDirectory)
#else
private static String ShowDialogInner(IFileOpenDialog dialog, IntPtr parentHWnd, String title, String initialDirectory)
public static String ShowSingleSelectDialog(IntPtr parentHWnd, String title, String initialDirectory)
#endif
{
//IFileDialog ifd = dialog;
FileOpenOptions flags =
FileOpenOptions.NoTestFileCreate |
FileOpenOptions.PathMustExist |
FileOpenOptions.PickFolders |
FileOpenOptions.ForceFilesystem;
{
#if NETCOREAPP3_1_OR_GREATER
IReadOnlyList<String>? fileNames = ShowDialog(parentHWnd, title, initialDirectory, FileOpenOptions.None);
#else
IReadOnlyList<String> fileNames = ShowDialog(parentHWnd, title, initialDirectory, FileOpenOptions.None);
#endif
if (fileNames != null && fileNames.Count > 0)
{
return fileNames[0];
}
else
{
return null;
}
}

#if NETCOREAPP3_1_OR_GREATER
private static IReadOnlyList<String>? ShowDialog(IntPtr parentHWnd, String title, String initialDirectory, FileOpenOptions flags)
#else
private static IReadOnlyList<String> ShowDialog(IntPtr parentHWnd, String title, String initialDirectory, FileOpenOptions flags)
#endif
{
NativeFileOpenDialog nfod = new NativeFileOpenDialog();
try
{
return ShowDialogInner(nfod, parentHWnd, title, initialDirectory, flags);
}
finally
{
_ = Marshal.ReleaseComObject(nfod);
}
}

#if NETCOREAPP3_1_OR_GREATER
private static IReadOnlyList<String>? ShowDialogInner(IFileOpenDialog dialog, IntPtr parentHWnd, String? title, String? initialDirectory, FileOpenOptions flags)
#else
private static IReadOnlyList<String> ShowDialogInner(IFileOpenDialog dialog, IntPtr parentHWnd, String title, String initialDirectory, FileOpenOptions flags)
#endif
{
//IFileDialog ifd = dialog;
flags = flags |
FileOpenOptions.NoTestFileCreate |
FileOpenOptions.PathMustExist |
FileOpenOptions.PickFolders |
FileOpenOptions.ForceFilesystem;

dialog.SetOptions(flags);

dialog.SetOptions( flags );

if( title != null )
{
dialog.SetTitle( title );
}
if (title != null)
{
dialog.SetTitle(title);
}

if( initialDirectory != null )
{
if (initialDirectory != null)
{
#if NETCOREAPP3_1_OR_GREATER
IShellItem2? initialDirectoryShellItem = Utility.ParseShellItem2Name( initialDirectory );
#else
IShellItem2 initialDirectoryShellItem = Utility.ParseShellItem2Name( initialDirectory );
IShellItem2 initialDirectoryShellItem = Utility.ParseShellItem2Name(initialDirectory);
#endif
if( initialDirectoryShellItem != null )
{
dialog.SetFolder( initialDirectoryShellItem );
}
}
if (initialDirectoryShellItem != null)
{
dialog.SetFolder(initialDirectoryShellItem);
}
}

//
//

HResult hr = dialog.Show( parentHWnd );
if( hr.ValidateDialogShowHResult() )
{
dialog.GetResults( out IShellItemArray resultsArray );
HResult hr = dialog.Show(parentHWnd);
if (hr.ValidateDialogShowHResult())
{
dialog.GetResults(out IShellItemArray resultsArray);

#if NETCOREAPP3_1_OR_GREATER
IReadOnlyList<String?> fileNames = Utility.GetFileNames( resultsArray );
#else
IReadOnlyList<String> fileNames = Utility.GetFileNames( resultsArray );
IReadOnlyList<String> fileNames = Utility.GetFileNames(resultsArray);
#endif
if( fileNames.Count == 0 )
{
return null;
}
else
{
return fileNames[0];
}
}
else
{
// User cancelled.
return null;
}
}
}
return fileNames;
}
else
{
// User cancelled.
return null;
}
}
}
}
4 changes: 4 additions & 0 deletions ShellFileDialogs/HResults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ public static Boolean TryGetWin32ErrorCode( this HResult hr, out Win32ErrorCodes
return true;
}
}
if(0 <= hr)
{
return true;
}
}
}

Expand Down