113 lines
3.1 KiB
C#
Raw Normal View History

using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Project;
using Microsoft.VisualStudio.Shell.Interop;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace ANX.Framework.VisualStudio.Controls
{
class BrowseFolderDialog : CommonDialog
{
public override void Reset()
{
}
public string Title
{
get;
set;
}
public string SelectedPath
{
get;
set;
}
public string RootFolder
{
get;
set;
}
protected override bool RunDialog(IntPtr hwndOwner)
{
if (this.Site == null)
throw new InvalidOperationException("No object for Site set.");
IVsUIShell shellService = this.Site.GetService(typeof(SVsUIShell)) as IVsUIShell;
if (shellService == null)
throw new InvalidOperationException(string.Format("Can't find {0} service.", typeof(IVsUIShell)));
string selectedPath = this.SelectedPath;
if (selectedPath == null)
selectedPath = string.Empty;
try
{
Uri selectedPathUri = new Uri(selectedPath, UriKind.RelativeOrAbsolute);
if (!selectedPathUri.IsAbsoluteUri)
selectedPathUri = new Uri(new Uri(RootFolder), selectedPathUri);
selectedPath = selectedPathUri.LocalPath;
}
catch { }
if (selectedPath.Length > NativeMethods.MAX_PATH)
throw new InvalidOperationException(string.Format("SelectedPath is longer than the native limit of {0}.", NativeMethods.MAX_PATH));
VSBROWSEINFOW[] browseInfo = new VSBROWSEINFOW[1];
var info = browseInfo[0];
info.hwndOwner = hwndOwner;
info.pwzDlgTitle = this.Title;
info.pwzInitialDir = selectedPath;
info.nMaxDirName = (uint)NativeMethods.MAX_PATH;
info.lStructSize = (uint)Marshal.SizeOf(typeof(VSBROWSEINFOW));
IntPtr path = Marshal.AllocCoTaskMem(NativeMethods.MAX_PATH);
try
{
info.pwzDirName = path;
browseInfo[0] = info;
int result = shellService.GetDirectoryViaBrowseDlg(browseInfo);
if (result == VSConstants.S_OK)
{
SelectedPath = Marshal.PtrToStringAuto(browseInfo[0].pwzDirName);
return true;
}
else if (result == VSConstants.OLE_E_PROMPTSAVECANCELLED)
{
return false;
}
else
{
ErrorHandler.ThrowOnFailure(result);
return false;
}
}
finally
{
if (path != IntPtr.Zero)
{
Marshal.FreeCoTaskMem(path);
}
}
}
}
}