Files

95 lines
2.2 KiB
C#

using System;
using System.Runtime.InteropServices;
namespace FontPreview;
internal static class NativeFolderDialog
{
private const uint FOS_PICKFOLDERS = 32u;
private const int SIGDN_FILESYSPATH = -2147123200;
[DllImport("shell32.dll", CharSet = CharSet.Unicode)]
private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IntPtr pbc, ref Guid riid, out IntPtr ppv);
private static void AddNavPlace(IFileOpenDialog dlg, string clsidPath)
{
try
{
IntPtr ppv = IntPtr.Zero;
Guid riid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
if (SHCreateItemFromParsingName(clsidPath, IntPtr.Zero, ref riid, out ppv) == 0 && ppv != IntPtr.Zero)
{
IShellItem psi = (IShellItem)Marshal.GetObjectForIUnknown(ppv);
try
{
dlg.AddPlace(psi, 1);
return;
}
catch
{
return;
}
}
}
catch
{
}
}
internal static string PickFolder(IntPtr owner, string title, string initialPath)
{
IFileOpenDialog fileOpenDialog = (IFileOpenDialog)new FileOpenDialogRCW();
try
{
fileOpenDialog.SetTitle(title);
fileOpenDialog.SetOptions(32u);
AddNavPlace(fileOpenDialog, "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}");
AddNavPlace(fileOpenDialog, "::{208D2C60-3AEA-1069-A2D8-08002B30309D}");
if (!string.IsNullOrEmpty(initialPath))
{
try
{
IntPtr ppv = IntPtr.Zero;
Guid riid = new Guid("43826d1e-e718-42ee-bc55-a1e261c37bfe");
if (SHCreateItemFromParsingName(initialPath, IntPtr.Zero, ref riid, out ppv) == 0 && ppv != IntPtr.Zero)
{
IShellItem folder = (IShellItem)Marshal.GetObjectForIUnknown(ppv);
fileOpenDialog.SetFolder(folder);
}
}
catch
{
}
}
if (fileOpenDialog.Show(owner) != 0)
{
return null;
}
fileOpenDialog.GetResult(out var ppsi);
if (ppsi == null)
{
return null;
}
ppsi.GetDisplayName(-2147123200, out var ppszName);
if (ppszName == IntPtr.Zero)
{
return null;
}
string result = Marshal.PtrToStringUni(ppszName);
Marshal.FreeCoTaskMem(ppszName);
return result;
}
finally
{
try
{
Marshal.FinalReleaseComObject(fileOpenDialog);
}
catch
{
}
}
}
}