Created
June 23, 2013 08:26
-
-
Save michaelij/5844287 to your computer and use it in GitHub Desktop.
A dialog the can select either a folder or a file.
Only one selection is possible.
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.Text; | |
using System.Windows.Forms; | |
using System.Runtime.InteropServices; | |
public class DirectoryDialog | |
{ | |
/// <summary> | |
/// The BROWSEINFO structure used by SHBrowseForFolder. | |
/// See http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205%28v=vs.85%29.aspx | |
/// </summary> | |
public struct BROWSEINFO | |
{ | |
public IntPtr hWndOwner; | |
public int pIDLRoot; | |
public string pszDisplayName; | |
public string lpszTitle; | |
public int ulFlags; | |
public int lpfnCallback; | |
public int lParam; | |
public int iImage; | |
} | |
/// <summary> | |
/// What to show in the directory dialog | |
/// See 'ulFlags' at http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205%28v=vs.85%29.aspx | |
/// </summary> | |
public enum BrowseForTypes : int | |
{ | |
Directories = 1, // BIF_RETURNONLYFSDIRS (0x00000001) | |
FileSystemAncestors = 8, // BIF_RETURNFSANCESTORS (0x00000008) | |
Computers = 4096, // BIF_BROWSEFORCOMPUTER (0x00001000) | |
FilesAndDirectories = 16384 // BIF_BROWSEINCLUDEFILES (0x00004000) | |
} | |
/// <summary> | |
/// The maximum path length. | |
/// A value of 260 matches the value used in the Windows API. | |
/// </summary> | |
const int MAX_PATH = 260; | |
private BrowseForTypes browseFor = BrowseForTypes.Directories; | |
private string title = ""; | |
private string selected = ""; | |
/// <summary> | |
/// The title of the dialog | |
/// </summary> | |
public string Title | |
{ | |
get | |
{ | |
return title; | |
} | |
set | |
{ | |
if (object.ReferenceEquals(value, DBNull.Value)) | |
{ | |
throw new ArgumentNullException(); | |
} | |
title = value; | |
} | |
} | |
/// <summary> | |
/// The selected item | |
/// </summary> | |
public string Selected | |
{ | |
get | |
{ | |
return selected; | |
} | |
} | |
/// <summary> | |
/// What the dialog is browsing for | |
/// </summary> | |
public BrowseForTypes BrowseFor | |
{ | |
get | |
{ | |
return browseFor; | |
} | |
set | |
{ | |
browseFor = value; | |
} | |
} | |
/// <summary> | |
/// DirectoryDialog constructor | |
/// </summary> | |
public DirectoryDialog() | |
{ | |
} | |
[DllImport("ole32", EntryPoint = "CoTaskMemFree", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] | |
public static extern int CoTaskMemFree(IntPtr hMem); | |
[DllImport("kernel32", EntryPoint = "lstrcat", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] | |
public static extern IntPtr lstrcat(string lpString1, string lpString2); | |
[DllImport("shell32", EntryPoint = "SHBrowseForFolder", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] | |
public static extern IntPtr SHBrowseForFolder(ref BROWSEINFO lpbi); | |
[DllImport("shell32", EntryPoint = "SHGetPathFromIDList", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)] | |
public static extern int SHGetPathFromIDList(IntPtr pidList, StringBuilder lpBuffer); | |
/// <summary> | |
/// Show the directory dialog | |
/// The PInvoke for SHBrowseForFolder and friends is required for this | |
/// </summary> | |
/// <param name="hMem"></param> | |
/// <returns></returns> | |
protected bool RunDialog(IntPtr hWndOwner) | |
{ | |
BROWSEINFO udtBI = new BROWSEINFO(); | |
IntPtr lpIDList = default(IntPtr); | |
GCHandle hTitle = GCHandle.Alloc(Title, GCHandleType.Pinned); | |
udtBI.hWndOwner = hWndOwner; | |
udtBI.lpszTitle = Title; | |
udtBI.ulFlags = (int)BrowseFor; | |
StringBuilder buffer = new StringBuilder(MAX_PATH); | |
buffer.Length = MAX_PATH; | |
udtBI.pszDisplayName = buffer.ToString(); | |
lpIDList = SHBrowseForFolder(ref udtBI); | |
hTitle.Free(); | |
if (lpIDList.ToInt64() == 0) | |
{ | |
return false; | |
} | |
if (BrowseFor == BrowseForTypes.Computers) | |
{ | |
selected = udtBI.pszDisplayName.Trim(); | |
} | |
else | |
{ | |
StringBuilder path = new StringBuilder(MAX_PATH); | |
SHGetPathFromIDList(lpIDList, path); | |
selected = path.ToString(); | |
} | |
CoTaskMemFree(lpIDList); | |
return true; | |
} | |
/// <summary> | |
/// Show the directory dialog box | |
/// </summary> | |
/// <returns>A DialogResult enum</returns> | |
public DialogResult ShowDialog() | |
{ | |
return ShowDialog(null); | |
} | |
/// <summary> | |
/// Show the directory dialog box | |
/// </summary> | |
/// <param name="owner">The owner window handler</param> | |
/// <returns>A DialogResult enum</returns> | |
public DialogResult ShowDialog(IWin32Window owner) | |
{ | |
IntPtr handle = default(IntPtr); | |
if ((owner != null)) | |
{ | |
handle = owner.Handle; | |
} | |
else | |
{ | |
handle = IntPtr.Zero; | |
} | |
if (RunDialog(handle)) | |
{ | |
return DialogResult.OK; | |
} | |
else | |
{ | |
return DialogResult.Cancel; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment