using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Microsoft.Win32;
using Vanara.Extensions;
using Vanara.InteropServices;
using Vanara.PInvoke;
using Vanara.Resources;
using static Vanara.PInvoke.ComCtl32;
using static Vanara.PInvoke.Kernel32;
using static Vanara.PInvoke.Shell32;
using static Vanara.PInvoke.User32;
namespace Vanara.Windows.Forms
{
///
///
public enum FolderBrowserDialogOptions
{
///
Folders,
///
FoldersAndFiles,
///
Computers,
///
Printers
}
///
/// Standard folders registered with the system as Known Folders. A computer will have only folders appropriate to it installed.
///
public enum KnownFolder
{
/// Account Pictures
AccountPictures = KNOWNFOLDERID.FOLDERID_AccountPictures,
/// Get Programs
AddNewPrograms = KNOWNFOLDERID.FOLDERID_AddNewPrograms,
/// Admin tools
AdminTools = KNOWNFOLDERID.FOLDERID_AdminTools,
/// Application shortcuts
ApplicationShortcuts = KNOWNFOLDERID.FOLDERID_ApplicationShortcuts,
/// Applications
AppsFolder = KNOWNFOLDERID.FOLDERID_AppsFolder,
/// Installed Updates
AppUpdates = KNOWNFOLDERID.FOLDERID_AppUpdates,
/// Camera Roll
CameraRoll = KNOWNFOLDERID.FOLDERID_CameraRoll,
/// Temporary Burn Folder
CDBurning = KNOWNFOLDERID.FOLDERID_CDBurning,
/// Programs and Features
ChangeRemovePrograms = KNOWNFOLDERID.FOLDERID_ChangeRemovePrograms,
/// Administrative Tools
CommonAdminTools = KNOWNFOLDERID.FOLDERID_CommonAdminTools,
/// OEM Links
CommonOEMLinks = KNOWNFOLDERID.FOLDERID_CommonOEMLinks,
/// Programs
CommonPrograms = KNOWNFOLDERID.FOLDERID_CommonPrograms,
/// Start Menu
CommonStartMenu = KNOWNFOLDERID.FOLDERID_CommonStartMenu,
/// Startup
CommonStartup = KNOWNFOLDERID.FOLDERID_CommonStartup,
/// Templates
CommonTemplates = KNOWNFOLDERID.FOLDERID_CommonTemplates,
/// Computer
ComputerFolder = KNOWNFOLDERID.FOLDERID_ComputerFolder,
/// Conflicts
ConflictFolder = KNOWNFOLDERID.FOLDERID_ConflictFolder,
/// Network Connections
ConnectionsFolder = KNOWNFOLDERID.FOLDERID_ConnectionsFolder,
/// Contacts
Contacts = KNOWNFOLDERID.FOLDERID_Contacts,
/// Control Panel
ControlPanelFolder = KNOWNFOLDERID.FOLDERID_ControlPanelFolder,
/// Cookies
Cookies = KNOWNFOLDERID.FOLDERID_Cookies,
/// Desktop
Desktop = KNOWNFOLDERID.FOLDERID_Desktop,
/// DeviceMetadataStore
DeviceMetadataStore = KNOWNFOLDERID.FOLDERID_DeviceMetadataStore,
/// Documents
Documents = KNOWNFOLDERID.FOLDERID_Documents,
/// Documents
DocumentsLibrary = KNOWNFOLDERID.FOLDERID_DocumentsLibrary,
/// Downloads
Downloads = KNOWNFOLDERID.FOLDERID_Downloads,
/// Favorites
Favorites = KNOWNFOLDERID.FOLDERID_Favorites,
/// Fonts
Fonts = KNOWNFOLDERID.FOLDERID_Fonts,
/// Games
Games = KNOWNFOLDERID.FOLDERID_Games,
/// GameExplorer
GameTasks = KNOWNFOLDERID.FOLDERID_GameTasks,
/// History
History = KNOWNFOLDERID.FOLDERID_History,
/// Homegroup
HomeGroup = KNOWNFOLDERID.FOLDERID_HomeGroup,
/// The user's username (%USERNAME%)
HomeGroupCurrentUser = KNOWNFOLDERID.FOLDERID_HomeGroupCurrentUser,
/// ImplicitAppShortcuts
ImplicitAppShortcuts = KNOWNFOLDERID.FOLDERID_ImplicitAppShortcuts,
/// Temporary Internet Files
InternetCache = KNOWNFOLDERID.FOLDERID_InternetCache,
/// The Internet
InternetFolder = KNOWNFOLDERID.FOLDERID_InternetFolder,
/// Libraries
Libraries = KNOWNFOLDERID.FOLDERID_Libraries,
/// Links
Links = KNOWNFOLDERID.FOLDERID_Links,
/// Local
LocalAppData = KNOWNFOLDERID.FOLDERID_LocalAppData,
/// LocalLow
LocalAppDataLow = KNOWNFOLDERID.FOLDERID_LocalAppDataLow,
/// None
LocalizedResourcesDir = KNOWNFOLDERID.FOLDERID_LocalizedResourcesDir,
/// Music
Music = KNOWNFOLDERID.FOLDERID_Music,
/// Music
MusicLibrary = KNOWNFOLDERID.FOLDERID_MusicLibrary,
/// Network Shortcuts
NetHood = KNOWNFOLDERID.FOLDERID_NetHood,
/// Network
NetworkFolder = KNOWNFOLDERID.FOLDERID_NetworkFolder,
/// Original Images
OriginalImages = KNOWNFOLDERID.FOLDERID_OriginalImages,
/// Slide Shows
PhotoAlbums = KNOWNFOLDERID.FOLDERID_PhotoAlbums,
/// Pictures
PicturesLibrary = KNOWNFOLDERID.FOLDERID_PicturesLibrary,
/// Pictures
Pictures = KNOWNFOLDERID.FOLDERID_Pictures,
/// Playlists
Playlists = KNOWNFOLDERID.FOLDERID_Playlists,
/// Printers
PrintersFolder = KNOWNFOLDERID.FOLDERID_PrintersFolder,
/// Printer Shortcuts
PrintHood = KNOWNFOLDERID.FOLDERID_PrintHood,
/// The user's username (%USERNAME%)
Profile = KNOWNFOLDERID.FOLDERID_Profile,
/// ProgramData
ProgramData = KNOWNFOLDERID.FOLDERID_ProgramData,
/// Program Files
ProgramFiles = KNOWNFOLDERID.FOLDERID_ProgramFiles,
/// Program Files
ProgramFilesX64 = KNOWNFOLDERID.FOLDERID_ProgramFilesX64,
/// Program Files
ProgramFilesX86 = KNOWNFOLDERID.FOLDERID_ProgramFilesX86,
/// Common Files
ProgramFilesCommon = KNOWNFOLDERID.FOLDERID_ProgramFilesCommon,
/// Common Files
ProgramFilesCommonX64 = KNOWNFOLDERID.FOLDERID_ProgramFilesCommonX64,
/// Common Files
ProgramFilesCommonX86 = KNOWNFOLDERID.FOLDERID_ProgramFilesCommonX86,
/// Programs
Programs = KNOWNFOLDERID.FOLDERID_Programs,
/// Public
Public = KNOWNFOLDERID.FOLDERID_Public,
/// Public Desktop
PublicDesktop = KNOWNFOLDERID.FOLDERID_PublicDesktop,
/// Public Documents
PublicDocuments = KNOWNFOLDERID.FOLDERID_PublicDocuments,
/// Public Downloads
PublicDownloads = KNOWNFOLDERID.FOLDERID_PublicDownloads,
/// GameExplorer
PublicGameTasks = KNOWNFOLDERID.FOLDERID_PublicGameTasks,
/// Libraries
PublicLibraries = KNOWNFOLDERID.FOLDERID_PublicLibraries,
/// Public Music
PublicMusic = KNOWNFOLDERID.FOLDERID_PublicMusic,
/// Public Pictures
PublicPictures = KNOWNFOLDERID.FOLDERID_PublicPictures,
/// Ringtones
PublicRingtones = KNOWNFOLDERID.FOLDERID_PublicRingtones,
/// Public Account Pictures
PublicUserTiles = KNOWNFOLDERID.FOLDERID_PublicUserTiles,
/// Public Videos
PublicVideos = KNOWNFOLDERID.FOLDERID_PublicVideos,
/// Quick Launch
QuickLaunch = KNOWNFOLDERID.FOLDERID_QuickLaunch,
/// Recent Items
Recent = KNOWNFOLDERID.FOLDERID_Recent,
/// Recorded TV
RecordedTVLibrary = KNOWNFOLDERID.FOLDERID_RecordedTVLibrary,
/// Recycle Bin
RecycleBinFolder = KNOWNFOLDERID.FOLDERID_RecycleBinFolder,
/// Resources
ResourceDir = KNOWNFOLDERID.FOLDERID_ResourceDir,
/// Ringtones
Ringtones = KNOWNFOLDERID.FOLDERID_Ringtones,
/// Roaming
RoamingAppData = KNOWNFOLDERID.FOLDERID_RoamingAppData,
/// RoamedTileImages
RoamedTileImages = KNOWNFOLDERID.FOLDERID_RoamedTileImages,
/// RoamingTiles
RoamingTiles = KNOWNFOLDERID.FOLDERID_RoamingTiles,
/// Sample Music
SampleMusic = KNOWNFOLDERID.FOLDERID_SampleMusic,
/// Sample Pictures
SamplePictures = KNOWNFOLDERID.FOLDERID_SamplePictures,
/// Sample Playlists
SamplePlaylists = KNOWNFOLDERID.FOLDERID_SamplePlaylists,
/// Sample Videos
SampleVideos = KNOWNFOLDERID.FOLDERID_SampleVideos,
/// Saved Games
SavedGames = KNOWNFOLDERID.FOLDERID_SavedGames,
/// Saved Pictures
SavedPictures = KNOWNFOLDERID.FOLDERID_SavedPictures,
/// Saved Pictures Library
SavedPicturesLibrary = KNOWNFOLDERID.FOLDERID_SavedPicturesLibrary,
/// Searches
SavedSearches = KNOWNFOLDERID.FOLDERID_SavedSearches,
/// Screenshots
Screenshots = KNOWNFOLDERID.FOLDERID_Screenshots,
/// Offline Files
SEARCH_CSC = KNOWNFOLDERID.FOLDERID_SEARCH_CSC,
/// History
SearchHistory = KNOWNFOLDERID.FOLDERID_SearchHistory,
/// Search Results
SearchHome = KNOWNFOLDERID.FOLDERID_SearchHome,
/// Microsoft Office Outlook
SEARCH_MAPI = KNOWNFOLDERID.FOLDERID_SEARCH_MAPI,
/// Templates
SearchTemplates = KNOWNFOLDERID.FOLDERID_SearchTemplates,
/// SendTo
SendTo = KNOWNFOLDERID.FOLDERID_SendTo,
/// Gadgets
SidebarDefaultParts = KNOWNFOLDERID.FOLDERID_SidebarDefaultParts,
/// Gadgets
SidebarParts = KNOWNFOLDERID.FOLDERID_SidebarParts,
/// OneDrive
SkyDrive = KNOWNFOLDERID.FOLDERID_SkyDrive,
/// Camera Roll
SkyDriveCameraRoll = KNOWNFOLDERID.FOLDERID_SkyDriveCameraRoll,
/// Documents
SkyDriveDocuments = KNOWNFOLDERID.FOLDERID_SkyDriveDocuments,
/// Pictures
SkyDrivePictures = KNOWNFOLDERID.FOLDERID_SkyDrivePictures,
/// Start Menu
StartMenu = KNOWNFOLDERID.FOLDERID_StartMenu,
/// Startup
Startup = KNOWNFOLDERID.FOLDERID_Startup,
/// Sync Center
SyncManagerFolder = KNOWNFOLDERID.FOLDERID_SyncManagerFolder,
/// Sync Results
SyncResultsFolder = KNOWNFOLDERID.FOLDERID_SyncResultsFolder,
/// Sync Setup
SyncSetupFolder = KNOWNFOLDERID.FOLDERID_SyncSetupFolder,
/// System32
System = KNOWNFOLDERID.FOLDERID_System,
/// System32
SystemX86 = KNOWNFOLDERID.FOLDERID_SystemX86,
/// Templates
Templates = KNOWNFOLDERID.FOLDERID_Templates,
/// User Pinned
UserPinned = KNOWNFOLDERID.FOLDERID_UserPinned,
/// Users
UserProfiles = KNOWNFOLDERID.FOLDERID_UserProfiles,
/// Programs
UserProgramFiles = KNOWNFOLDERID.FOLDERID_UserProgramFiles,
/// Programs
UserProgramFilesCommon = KNOWNFOLDERID.FOLDERID_UserProgramFilesCommon,
/// The user's full name (for instance, Jean Philippe Bagel) entered when the user account was created.
UsersFiles = KNOWNFOLDERID.FOLDERID_UsersFiles,
/// Libraries
UsersLibraries = KNOWNFOLDERID.FOLDERID_UsersLibraries,
/// Videos
Videos = KNOWNFOLDERID.FOLDERID_Videos,
/// Videos
VideosLibrary = KNOWNFOLDERID.FOLDERID_VideosLibrary,
/// Windows
Windows = KNOWNFOLDERID.FOLDERID_Windows,
/// Undefined
Undefined = 0xFFFF,
}
/// Class to let the user browse for a folder.
[ToolboxBitmap(typeof(FolderBrowserDialog), "Dialog"), Description("Dialog that browses network computers.")]
public class FolderBrowserDialog : System.Windows.Forms.CommonDialog
{
private const KnownFolder defaultComputersFolder = KnownFolder.NetworkFolder;
private const KnownFolder defaultFolderFolder = KnownFolder.ComputerFolder;
private const KnownFolder defaultPrintersFolder = KnownFolder.PrintersFolder;
private FolderBrowserDialogOptions browseOption;
private bool initialized;
private KnownFolder rootFolder;
private PIDL rootPidl;
/// Initializes a new instance of the class.
public FolderBrowserDialog()
{
Reset();
RootFolder = defaultFolderFolder;
}
/// Occurs when dialog box has been initialized and primary values have been set.
public event EventHandler Initialized;
/// Event that is raised when the user selects an invalid folder.
public event EventHandler InvalidFolderSelected;
/// Occurs when property has changed.
public event PropertyChangedEventHandler SelectedItemChanged;
/// Gets or sets the types of items to browse.
[DefaultValue(typeof(FolderBrowserDialogOptions), "Folders"), Localizable(false), Category("Behavior"),
Description("The types of items to browse")]
public FolderBrowserDialogOptions BrowseOption
{
get => browseOption; set
{
if (browseOption != value)
{
browseOption = value;
switch (browseOption)
{
case FolderBrowserDialogOptions.Folders:
case FolderBrowserDialogOptions.FoldersAndFiles:
if (RootFolder == defaultComputersFolder || RootFolder == defaultPrintersFolder)
RootFolder = defaultFolderFolder;
break;
case FolderBrowserDialogOptions.Computers:
RootFolder = defaultComputersFolder;
break;
case FolderBrowserDialogOptions.Printers:
RootFolder = defaultPrintersFolder;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}
}
/// Gets or sets the caption of the dialog box.
[DefaultValue(""), Category("Appearance"), Localizable(true), Description("Caption of the dialog box.")]
public string Caption { get; set; } = "";
/// Gets or sets the description shown to the user.
[DefaultValue(""), Category("Appearance"), Localizable(true), Description("Description shown to the user.")]
public string Description { get; set; } = "";
/// Gets or sets whether to automatically expand the tree when shown.
[DefaultValue(true), Localizable(false), Category("Behavior"), Description("Whether to automatically expand the tree when shown.")]
public bool Expanded { get; set; } = true;
/// Gets or sets whether to hide network folders below the domain level in the tree.
[DefaultValue(false), Localizable(false), Category("Behavior"), Description("Whether to hide network folders below the domain.")]
public bool HideDomainFolders { get; set; }
/// Gets or sets whether to return only file system folders.
[DefaultValue(false), Localizable(false), Category("Behavior"), Description("Whether to return only file system folders.")]
public bool LocalFileSystemOnly { get; set; }
/// Gets or sets the text on the OK button.
[DefaultValue(""), Category("Appearance"), Localizable(true), Description("Text on the OK button.")]
public string OkText { get; set; } = "";
/// Gets or sets the root folder.
[Localizable(false), Category("Data"), Description("Root folder of tree."), DefaultValue(defaultFolderFolder)]
public KnownFolder RootFolder
{
get => rootFolder; set
{
rootFolder = value;
try { rootPidl = ((KNOWNFOLDERID)RootFolder).PIDL(); }
catch
{
System.Diagnostics.Debug.WriteLine($"The known folder '{RootFolder}' is not supported for this OS or application configuration.");
ResetRootFolder();
}
}
}
/// Gets or sets the PIDL associated with the root folder. This can be used to specify a non-known folder as the root.
/// The root folder's PIDL.
[DefaultValue(0), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
// ReSharper disable once InconsistentNaming
public PIDL RootFolderPIDL
{
get => rootPidl; set
{
rootPidl = value;
rootFolder = KnownFolder.Undefined;
}
}
/// Gets or sets the path or name of the folder selected by the user.
[DefaultValue(""), Category("Data"), Localizable(true), Description("The path or name of the selected folder")]
public string SelectedItem { get; set; } = "";
/// Gets the image from the system image list associated with the selected item.
/// The selected item's image.
[DefaultValue(null), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public Icon SelectedItemImage => SelectedItemPIDL.GetIcon(IconSize.Small);
/// Gets the PIDL associated with the selected item.
/// The selected item's PIDL.
[DefaultValue(0), Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
// ReSharper disable once InconsistentNaming
public PIDL SelectedItemPIDL { get; private set; }
/// Gets or sets whether or not to show file junctions, such as a library or compressed file. This only is available in Windows 7 and later.
[DefaultValue(false), Localizable(false), Category("Behavior"), Description("Whether or not to show file junctions.")]
public bool ShowFileJunctions { get; set; }
/// Gets or sets whether or not to show an edit box for the folder path.
[DefaultValue(false), Localizable(false), Category("Behavior"), Description("Whether or not to show an edit box for the folder.")]
public bool ShowFolderPathEditBox { get; set; }
/// Gets or sets whether or not to show the new folder button.
[DefaultValue(false), Localizable(false), Category("Behavior"), Description("Whether or not to show the new folder button.")]
public bool ShowNewFolderButton { get; set; }
/// When overridden in a derived class, resets the properties of a common dialog box to their default values.
public override void Reset()
{
BrowseOption = FolderBrowserDialogOptions.Folders;
Caption = Description = OkText = SelectedItem = string.Empty;
Expanded = true;
RootFolder = defaultFolderFolder;
HideDomainFolders = ShowFileJunctions = LocalFileSystemOnly = ShowFolderPathEditBox = ShowNewFolderButton = initialized = false;
SelectedItemPIDL = null;
}
/// Shows the dialog box to let the user browse for and select a folder.
/// The HWND of the parent window.
/// The selected folder or null if no folder was selected by the user.
protected override bool RunDialog(IntPtr parentWindowHandle)
{
// Setup BROWSEINFO.dwFlag value
EnumFlagIndexer browseInfoFlag = BrowseInfoFlag.BIF_SHAREABLE;
browseInfoFlag[BrowseInfoFlag.BIF_NEWDIALOGSTYLE] = Application.OleRequired() == ApartmentState.STA;
browseInfoFlag[BrowseInfoFlag.BIF_DONTGOBELOWDOMAIN] = HideDomainFolders;
browseInfoFlag[BrowseInfoFlag.BIF_BROWSEFILEJUNCTIONS] = ShowFileJunctions;
browseInfoFlag[BrowseInfoFlag.BIF_RETURNONLYFSDIRS] = LocalFileSystemOnly;
browseInfoFlag[BrowseInfoFlag.BIF_NONEWFOLDERBUTTON] = !ShowNewFolderButton;
browseInfoFlag[BrowseInfoFlag.BIF_EDITBOX | BrowseInfoFlag.BIF_VALIDATE] = ShowFolderPathEditBox;
switch (BrowseOption)
{
case FolderBrowserDialogOptions.Folders:
break;
case FolderBrowserDialogOptions.FoldersAndFiles:
browseInfoFlag |= BrowseInfoFlag.BIF_BROWSEINCLUDEFILES;
break;
case FolderBrowserDialogOptions.Computers:
browseInfoFlag |= BrowseInfoFlag.BIF_BROWSEFORCOMPUTER;
RootFolder = defaultComputersFolder;
break;
case FolderBrowserDialogOptions.Printers:
browseInfoFlag |= BrowseInfoFlag.BIF_BROWSEFORPRINTER;
RootFolder = defaultPrintersFolder;
break;
default:
throw new ArgumentOutOfRangeException();
}
// Setup the BROWSEINFO structure
var dn = new SafeCoTaskMemString(MAX_PATH);
var bi = new BROWSEINFO(parentWindowHandle, rootPidl.DangerousGetHandle(), Description, browseInfoFlag, OnBrowseEvent, dn);
// Show the dialog
SelectedItemPIDL = SHBrowseForFolder(bi);
if (SelectedItemPIDL.IsInvalid) return false;
if (browseInfoFlag[BrowseInfoFlag.BIF_BROWSEFORPRINTER] || browseInfoFlag[BrowseInfoFlag.BIF_BROWSEFORCOMPUTER])
SelectedItem = bi.DisplayName;
else
SelectedItem = GetNameForPidl(SelectedItemPIDL);
return true;
}
/// Enables or disables the OK button in the dialog box.
/// The hwnd of the dialog box.
/// Whether or not the OK button should be enabled.
private static void EnableOk(HWND hwnd, bool isEnabled) => SendMessage(hwnd, (uint)BrowseForFolderMessages.BFFM_ENABLEOK, (IntPtr)0, (IntPtr)(isEnabled ? 1 : 0));
private static string GetNameForPidl(PIDL pidl)
{
try { SHGetNameFromIDList(pidl, SIGDN.SIGDN_FILESYSPATH, out var mStr); return mStr; } catch { }
try { SHGetNameFromIDList(pidl, SIGDN.SIGDN_DESKTOPABSOLUTEEDITING, out var mStr); return mStr; } catch { }
try { SHGetNameFromIDList(pidl, SIGDN.SIGDN_NORMALDISPLAY, out var mStr); return mStr; } catch { }
return string.Empty;
}
private static Icon GetSystemImageListIcon(int idx)
{
// Test first for overridden icon images
var regVal = Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Icons", idx.ToString(), null);
if (regVal != null)
return ResourceFile.GetResourceIcon(regVal.ToString());
// Get the image from the system image list
try
{
return IconExtension.GetSystemIcon(System.IO.Path.GetPathRoot(Environment.SystemDirectory), IconSize.Small);
}
catch
{
return null;
}
}
/// Callback for Windows.
/// Window handle of the browse dialog box.
/// Dialog box event that generated the statusMessage.
/// Value whose meaning depends on the event specified in uMsg.
/// Application-defined value that was specified in the lParam member of the BROWSEINFO structure used in the call to SHBrowseForFolder.
///
/// Returns 0 except in the case of BFFM_VALIDATEFAILED. For that flag, returns 0 to dismiss the dialog or nonzero to keep the dialog displayed.
///
//[CLSCompliant(false)]
private int OnBrowseEvent(HWND hwnd, BrowseForFolderMessages uMsg, IntPtr lParam, IntPtr lpData)
{
var messsage = uMsg;
switch (messsage)
{
case BrowseForFolderMessages.BFFM_INITIALIZED:
// Dialog is being initialized, so set the initial parameters
if (!string.IsNullOrEmpty(Caption))
SetWindowText(hwnd, Caption);
if (!string.IsNullOrEmpty(SelectedItem))
SendMessage(hwnd, (uint)BrowseForFolderMessages.BFFM_SETSELECTIONW, (IntPtr)1, SelectedItem);
if (Expanded)
SendMessage(hwnd, (uint)BrowseForFolderMessages.BFFM_SETEXPANDED, (IntPtr)1, rootPidl.DangerousGetHandle());
if (!string.IsNullOrEmpty(OkText))
SendMessage(hwnd, (uint)BrowseForFolderMessages.BFFM_SETOKTEXT, (IntPtr)0, OkText);
Initialized?.Invoke(this, new FolderBrowserDialogInitializedEventArgs(hwnd));
initialized = true;
return 0;
case BrowseForFolderMessages.BFFM_SELCHANGED:
try
{
if (!initialized || SelectedItemPIDL?.DangerousGetHandle() == lParam) return 0;
var tmpPidl = new PIDL(lParam, false, false);
var str = GetNameForPidl(tmpPidl);
if (string.IsNullOrEmpty(str))
return 0;
SelectedItem = str;
SelectedItemPIDL = tmpPidl;
}
catch
{
return 0;
}
SelectedItemChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem)));
return 0;
case BrowseForFolderMessages.BFFM_VALIDATEFAILEDA:
case BrowseForFolderMessages.BFFM_VALIDATEFAILEDW:
if (InvalidFolderSelected != null)
{
var folderName = messsage == BrowseForFolderMessages.BFFM_VALIDATEFAILEDA ? Marshal.PtrToStringAnsi(lParam) : Marshal.PtrToStringUni(lParam);
var e = new InvalidFolderEventArgs(folderName, true);
InvalidFolderSelected?.Invoke(this, e);
return e.DismissDialog ? 0 : 1;
}
return 0;
default:
return 0;
}
}
private void ResetRootFolder()
{
switch (BrowseOption)
{
case FolderBrowserDialogOptions.Folders:
case FolderBrowserDialogOptions.FoldersAndFiles:
RootFolder = defaultFolderFolder;
break;
case FolderBrowserDialogOptions.Computers:
RootFolder = defaultComputersFolder;
break;
case FolderBrowserDialogOptions.Printers:
RootFolder = defaultPrintersFolder;
break;
default:
throw new ArgumentOutOfRangeException();
}
}
private bool ShouldSerializeRootFolder()
{
switch (BrowseOption)
{
case FolderBrowserDialogOptions.Folders:
case FolderBrowserDialogOptions.FoldersAndFiles:
return RootFolder != KnownFolder.ComputerFolder;
case FolderBrowserDialogOptions.Computers:
return RootFolder != KnownFolder.NetworkFolder;
case FolderBrowserDialogOptions.Printers:
return RootFolder != KnownFolder.PrintersFolder;
default:
throw new ArgumentOutOfRangeException();
}
}
}
/// Event arguments for when the has been initialized.
public class FolderBrowserDialogInitializedEventArgs : EventArgs
{
/// The HWND of the dialog box.
public readonly HWND hwnd;
/// Initializes a new instance of the class.
/// The HWND of the dialog box.
public FolderBrowserDialogInitializedEventArgs(HWND hwnd) { this.hwnd = hwnd; }
}
/// Event arguments for when an invalid folder is selected.
public class InvalidFolderEventArgs : EventArgs
{
/// Constructs an instance.
/// The name of the invalid folder.
/// Whether or not to dismiss the dialog.
public InvalidFolderEventArgs(string folderName, bool dismissDialog)
{
FolderName = folderName;
DismissDialog = dismissDialog;
}
/// Gets or sets whether or not to dismiss the dialog box.
public bool DismissDialog { get; set; }
/// Gets the name of the invalid folder.
public string FolderName { get; }
}
}