95 lines
2.2 KiB
C#
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
|
|
{
|
|
}
|
|
}
|
|
}
|
|
}
|