Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / FolderBrowserDialog.cs / 4 / FolderBrowserDialog.cs
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//-----------------------------------------------------------------------------
namespace System.Windows.Forms
{
using System;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using System.Diagnostics.CodeAnalysis;
///
///
///
/// Represents a common dialog box that allows the user to specify options for
/// selecting a folder. This class cannot be inherited.
///
///
[
DefaultEvent("HelpRequest"),
DefaultProperty("SelectedPath"),
Designer("System.Windows.Forms.Design.FolderBrowserDialogDesigner, " + AssemblyRef.SystemDesign),
SRDescription(SR.DescriptionFolderBrowserDialog)
]
public sealed class FolderBrowserDialog : CommonDialog
{
// Root node of the tree view.
private Environment.SpecialFolder rootFolder;
// Description text to show.
private string descriptionText;
// Folder picked by the user.
private string selectedPath;
// Show the 'New Folder' button?
private bool showNewFolderButton;
// set to True when selectedPath is set after the dialog box returns
// set to False when selectedPath is set via the SelectedPath property.
// Warning! Be careful about race conditions when touching this variable.
// This variable is determining if the PathDiscovery security check should
// be bypassed or not.
private bool selectedPathNeedsCheck;
// Callback function for the folder browser dialog (see VSWhidbey 551866)
private UnsafeNativeMethods.BrowseCallbackProc callback;
///
///
///
/// Initializes a new instance of the class.
///
///
public FolderBrowserDialog()
{
Reset();
}
///
///
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new event EventHandler HelpRequest
{
add
{
base.HelpRequest += value;
}
remove
{
base.HelpRequest -= value;
}
}
///
///
/// Determines if the 'New Folder' button should be exposed.
///
[
Browsable(true),
DefaultValue(true),
Localizable(false),
SRCategory(SR.CatFolderBrowsing),
SRDescription(SR.FolderBrowserDialogShowNewFolderButton)
]
public bool ShowNewFolderButton
{
get
{
return showNewFolderButton;
}
set
{
showNewFolderButton = value;
}
}
///
///
/// Gets the directory path of the folder the user picked.
/// Sets the directory path of the initial folder shown in the dialog box.
///
[
Browsable(true),
DefaultValue(""),
Editor("System.Windows.Forms.Design.SelectedPathEditor, " + AssemblyRef.SystemDesign, typeof(UITypeEditor)),
Localizable(true),
SRCategory(SR.CatFolderBrowsing),
SRDescription(SR.FolderBrowserDialogSelectedPath)
]
/// SECREVIEW: ReviewImperativeSecurity
/// vulnerability to watch out for: A method uses imperative security and might be constructing the permission using state information or return values that can change while the demand is active.
/// reason for exclude: we want to protect when the dialog has been set by the user - this is directly set when in RunDialog
[SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")]
public string SelectedPath
{
get
{
if (selectedPath == null || selectedPath.Length == 0)
{
return selectedPath;
}
if (selectedPathNeedsCheck)
{
Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileIO(" + selectedPath + ") Demanded");
new FileIOPermission(FileIOPermissionAccess.PathDiscovery, selectedPath).Demand();
}
return selectedPath;
}
set
{
selectedPath = (value == null) ? String.Empty : value;
selectedPathNeedsCheck = false;
}
}
///
///
/// Gets/sets the root node of the directory tree.
///
[
Browsable(true),
DefaultValue(System.Environment.SpecialFolder.Desktop),
Localizable(false),
SRCategory(SR.CatFolderBrowsing),
SRDescription(SR.FolderBrowserDialogRootFolder),
TypeConverter(typeof(SpecialFolderEnumConverter))
]
public System.Environment.SpecialFolder RootFolder
{
get
{
return rootFolder;
}
[SuppressMessage("Microsoft.Performance", "CA1803:AvoidCostlyCallsWherePossible")]
set
{
// FXCop:
// leaving in Enum.IsDefined because this Enum is likely to grow and we dont own it.
if (!Enum.IsDefined(typeof(System.Environment.SpecialFolder), value))
{
throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Environment.SpecialFolder));
}
rootFolder = value;
}
}
///
///
///
/// Gets or sets a description to show above the folders. Here you can provide instructions for
/// selecting a folder.
///
///
[
Browsable(true),
DefaultValue(""),
Localizable(true),
SRCategory(SR.CatFolderBrowsing),
SRDescription(SR.FolderBrowserDialogDescription)
]
public string Description
{
get
{
return descriptionText;
}
set
{
descriptionText = (value == null) ? String.Empty : value;
}
}
///
/// Helper function that returns the IMalloc interface used by the shell.
///
private static UnsafeNativeMethods.IMalloc GetSHMalloc()
{
UnsafeNativeMethods.IMalloc[] malloc = new UnsafeNativeMethods.IMalloc[1];
UnsafeNativeMethods.Shell32.SHGetMalloc(malloc);
return malloc[0];
}
///
///
///
/// Resets all properties to their default values.
///
///
public override void Reset()
{
rootFolder = System.Environment.SpecialFolder.Desktop;
descriptionText = String.Empty;
selectedPath = String.Empty;
selectedPathNeedsCheck = false;
showNewFolderButton = true;
}
///
///
/// Implements running of a folder browser dialog.
///
protected override bool RunDialog(IntPtr hWndOwner)
{
IntPtr pidlRoot = IntPtr.Zero;
bool returnValue = false;
UnsafeNativeMethods.Shell32.SHGetSpecialFolderLocation(hWndOwner, (int) rootFolder, ref pidlRoot);
if (pidlRoot == IntPtr.Zero)
{
UnsafeNativeMethods.Shell32.SHGetSpecialFolderLocation(hWndOwner, NativeMethods.CSIDL_DESKTOP, ref pidlRoot);
if (pidlRoot == IntPtr.Zero)
{
throw new InvalidOperationException(SR.GetString(SR.FolderBrowserDialogNoRootFolder));
}
}
int mergedOptions = (int) UnsafeNativeMethods.BrowseInfos.NewDialogStyle;
if (!showNewFolderButton)
{
mergedOptions += (int) UnsafeNativeMethods.BrowseInfos.HideNewFolderButton;
}
// The SHBrowserForFolder dialog is OLE/COM based, and documented as only being safe to use under the STA
// threading model if the BIF_NEWDIALOGSTYLE flag has been requested (which we always do in mergedOptions
// above). So make sure OLE is initialized, and throw an exception if caller attempts to invoke dialog
// under the MTA threading model (...dialog does appear under MTA, but is totally non-functional).
if (Control.CheckForIllegalCrossThreadCalls && Application.OleRequired() != System.Threading.ApartmentState.STA)
{
throw new System.Threading.ThreadStateException(SR.GetString(SR.DebuggingExceptionOnly, SR.GetString(SR.ThreadMustBeSTA)));
}
IntPtr pidlRet = IntPtr.Zero;
IntPtr pszDisplayName = IntPtr.Zero;
IntPtr pszSelectedPath = IntPtr.Zero;
try
{
// Construct a BROWSEINFO
UnsafeNativeMethods.BROWSEINFO bi = new UnsafeNativeMethods.BROWSEINFO();
pszDisplayName = Marshal.AllocHGlobal(NativeMethods.MAX_PATH * Marshal.SystemDefaultCharSize);
pszSelectedPath = Marshal.AllocHGlobal(NativeMethods.MAX_PATH * Marshal.SystemDefaultCharSize);
this.callback = new UnsafeNativeMethods.BrowseCallbackProc(this.FolderBrowserDialog_BrowseCallbackProc);
bi.pidlRoot = pidlRoot;
bi.hwndOwner = hWndOwner;
bi.pszDisplayName = pszDisplayName;
bi.lpszTitle = descriptionText;
bi.ulFlags = mergedOptions;
bi.lpfn = callback;
bi.lParam = IntPtr.Zero;
bi.iImage = 0;
// And show the dialog
pidlRet = UnsafeNativeMethods.Shell32.SHBrowseForFolder(bi);
if (pidlRet != IntPtr.Zero)
{
// Then retrieve the path from the IDList
UnsafeNativeMethods.Shell32.SHGetPathFromIDList(pidlRet, pszSelectedPath);
// set the flag to True before selectedPath is set to
// assure security check and avoid bogus race condition
selectedPathNeedsCheck = true;
// Convert to a string
selectedPath = Marshal.PtrToStringAuto(pszSelectedPath);
returnValue = true;
}
}
finally
{
UnsafeNativeMethods.IMalloc malloc = GetSHMalloc();
malloc.Free(pidlRoot);
if (pidlRet != IntPtr.Zero)
{
malloc.Free(pidlRet);
}
// Then free all the stuff we've allocated or the SH API gave us
if (pszSelectedPath != IntPtr.Zero)
{
Marshal.FreeHGlobal(pszSelectedPath);
}
if (pszDisplayName != IntPtr.Zero)
{
Marshal.FreeHGlobal(pszDisplayName);
}
this.callback = null;
}
return returnValue;
}
///
/// Callback function used to enable/disable the OK button,
/// and select the initial folder.
///
private int FolderBrowserDialog_BrowseCallbackProc(IntPtr hwnd,
int msg,
IntPtr lParam,
IntPtr lpData)
{
switch (msg)
{
case NativeMethods.BFFM_INITIALIZED:
// Indicates the browse dialog box has finished initializing. The lpData value is zero.
if (selectedPath.Length != 0)
{
// Try to select the folder specified by selectedPath
UnsafeNativeMethods.SendMessage(new HandleRef(null, hwnd), (int) NativeMethods.BFFM_SETSELECTION, 1, selectedPath);
}
break;
case NativeMethods.BFFM_SELCHANGED:
// Indicates the selection has changed. The lpData parameter points to the item identifier list for the newly selected item.
IntPtr selectedPidl = lParam;
if (selectedPidl != IntPtr.Zero)
{
IntPtr pszSelectedPath = Marshal.AllocHGlobal(NativeMethods.MAX_PATH * Marshal.SystemDefaultCharSize);
// Try to retrieve the path from the IDList
bool isFileSystemFolder = UnsafeNativeMethods.Shell32.SHGetPathFromIDList(selectedPidl, pszSelectedPath);
Marshal.FreeHGlobal(pszSelectedPath);
UnsafeNativeMethods.SendMessage(new HandleRef(null, hwnd), (int) NativeMethods.BFFM_ENABLEOK, 0, isFileSystemFolder ? 1 : 0);
}
break;
}
return 0;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ExpressionVisitor.cs
- WindowsListViewItemStartMenu.cs
- DataSvcMapFile.cs
- __Error.cs
- SchemaCollectionPreprocessor.cs
- StateInitializationDesigner.cs
- FixedSOMImage.cs
- SchemaElementDecl.cs
- RemotingConfiguration.cs
- DocumentScope.cs
- UpnEndpointIdentityExtension.cs
- ViewManager.cs
- DataGridViewSelectedCellCollection.cs
- GlyphInfoList.cs
- XmlSchemaAll.cs
- BreakRecordTable.cs
- RSAPKCS1SignatureFormatter.cs
- CustomErrorCollection.cs
- SafeUserTokenHandle.cs
- MediaTimeline.cs
- HttpCachePolicy.cs
- ActivityDefaults.cs
- CubicEase.cs
- InstanceKey.cs
- HttpCachePolicyElement.cs
- DeleteBookmarkScope.cs
- TraceHandler.cs
- TextFormatterHost.cs
- FixedSOMPage.cs
- ObjectQuery.cs
- DefaultMemberAttribute.cs
- GeometryModel3D.cs
- ClaimTypes.cs
- VectorValueSerializer.cs
- CalendarTable.cs
- XmlUtil.cs
- CompilationSection.cs
- PathSegment.cs
- Queue.cs
- MsmqIntegrationProcessProtocolHandler.cs
- UpdateException.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- Sql8ConformanceChecker.cs
- ExpandCollapsePattern.cs
- MatrixValueSerializer.cs
- SharedRuntimeState.cs
- SecurityToken.cs
- PenCursorManager.cs
- XmlSchemaElement.cs
- ListViewTableRow.cs
- ResourceWriter.cs
- TextureBrush.cs
- RankException.cs
- CustomLineCap.cs
- PrimarySelectionAdorner.cs
- TimeSpanFormat.cs
- SendMessageRecord.cs
- DiffuseMaterial.cs
- SerialPort.cs
- ListControl.cs
- GridViewColumnCollectionChangedEventArgs.cs
- WebPartVerbCollection.cs
- XmlSchemaValidator.cs
- SystemIPv4InterfaceProperties.cs
- CompiledAction.cs
- Enlistment.cs
- ResolveMatchesMessage11.cs
- XmlSchemaChoice.cs
- DeploymentSectionCache.cs
- SchemaManager.cs
- ObsoleteAttribute.cs
- AuthenticateEventArgs.cs
- TCPListener.cs
- XmlSerializerFaultFormatter.cs
- ToolStripRenderer.cs
- HtmlGenericControl.cs
- DesignerLinkAdapter.cs
- DataGridViewTextBoxCell.cs
- VirtualPath.cs
- AssemblySettingAttributes.cs
- FontStretches.cs
- ZoneButton.cs
- DataGridAutoFormat.cs
- AdditionalEntityFunctions.cs
- DrawingContextDrawingContextWalker.cs
- TagPrefixCollection.cs
- PartialCachingControl.cs
- ConditionalAttribute.cs
- NativeMethods.cs
- DocumentDesigner.cs
- PatternMatcher.cs
- XmlSchemaObjectTable.cs
- AsyncContentLoadedEventArgs.cs
- ToolStripAdornerWindowService.cs
- SecurityPolicySection.cs
- SqlTypeConverter.cs
- UserInitiatedNavigationPermission.cs
- followingsibling.cs
- URLIdentityPermission.cs
- XmlWriter.cs