Created
December 16, 2016 15:46
-
-
Save glopesdev/3228290706f714b7258d90488ba7613c to your computer and use it in GitHub Desktop.
Minimalist example for opening a modern UI folder browser dialog in Windows Forms.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.Linq; | |
| using System.Runtime.CompilerServices; | |
| using System.Runtime.InteropServices; | |
| using System.Text; | |
| using System.Threading.Tasks; | |
| using System.Windows.Forms; | |
| namespace CommonDialogs | |
| { | |
| class FolderBrowserDialog : CommonDialog | |
| { | |
| const uint FOS_PICKFOLDERS = 0x20; | |
| const uint FOS_FORCEFILESYSTEM = 0x40; | |
| const uint SIGDN_FILESYSPATH = 0x80058000; | |
| const uint S_OK = 0; | |
| public string SelectedPath { get; set; } | |
| public override void Reset() | |
| { | |
| SelectedPath = null; | |
| } | |
| protected override bool RunDialog(IntPtr hwndOwner) | |
| { | |
| uint options; | |
| var dialog = (IFileDialog)new FileOpenDialogRCW(); | |
| dialog.GetOptions(out options); | |
| options |= FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM; | |
| dialog.SetOptions(options); | |
| if (dialog.Show(hwndOwner) == S_OK) | |
| { | |
| IShellItem shellItem; | |
| if (dialog.GetResult(out shellItem) == S_OK) | |
| { | |
| IntPtr pszName; | |
| if (shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszName) == S_OK && | |
| pszName != IntPtr.Zero) | |
| { | |
| try | |
| { | |
| SelectedPath = Marshal.PtrToStringAuto(pszName); | |
| return true; | |
| } | |
| finally { Marshal.FreeCoTaskMem(pszName); } | |
| } | |
| } | |
| } | |
| return false; | |
| } | |
| #region Com Interop | |
| [ComImport] | |
| [ClassInterface(ClassInterfaceType.None)] | |
| [TypeLibType(TypeLibTypeFlags.FCanCreate)] | |
| [Guid("DC1C5A9C-E88A-4DDE-A5A1-60F82A20AEF7")] | |
| class FileOpenDialogRCW | |
| { | |
| } | |
| [ComImport] | |
| [Guid("42F85136-DB7E-439C-85F1-E4075D135FC8")] | |
| [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
| interface IFileDialog | |
| { | |
| [PreserveSig] | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint Show([In, Optional] IntPtr hwndOwner); //IModalWindow | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetFileTypes([In] uint cFileTypes, [In, MarshalAs(UnmanagedType.LPArray)] IntPtr rgFilterSpec); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetFileTypeIndex([In] uint iFileType); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetFileTypeIndex(out uint piFileType); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint Advise([In, MarshalAs(UnmanagedType.Interface)] IntPtr pfde, out uint pdwCookie); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint Unadvise([In] uint dwCookie); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetOptions([In] uint fos); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetOptions(out uint fos); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| void SetDefaultFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetFolder([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetFolder([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetCurrentSelection([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetFileName([In, MarshalAs(UnmanagedType.LPWStr)] string pszName); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetTitle([In, MarshalAs(UnmanagedType.LPWStr)] string pszTitle); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetOkButtonLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszText); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetFileNameLabel([In, MarshalAs(UnmanagedType.LPWStr)] string pszLabel); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint AddPlace([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, uint fdap); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetDefaultExtension([In, MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint Close([MarshalAs(UnmanagedType.Error)] uint hr); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetClientGuid([In] ref Guid guid); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint ClearClientData(); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter); | |
| } | |
| [ComImport] | |
| [Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")] | |
| [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | |
| interface IShellItem | |
| { | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint BindToHandler([In] IntPtr pbc, [In] ref Guid rbhid, [In] ref Guid riid, [Out, MarshalAs(UnmanagedType.Interface)] out IntPtr ppvOut); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetParent([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetDisplayName([In] uint sigdnName, out IntPtr ppszName); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint GetAttributes([In] uint sfgaoMask, out uint psfgaoAttribs); | |
| [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | |
| uint Compare([In, MarshalAs(UnmanagedType.Interface)] IShellItem psi, [In] uint hint, out int piOrder); | |
| } | |
| #endregion | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment