Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / WinForms / Managed / System / WinForms / FolderBrowserDialog.cs / 1305376 / 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; ////// /// [ 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; ////// Represents a common dialog box that allows the user to specify options for /// selecting a folder. This class cannot be inherited. /// ////// /// public FolderBrowserDialog() { Reset(); } ////// Initializes a new instance of the ///class. /// /// [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; } } ////// /// [ Browsable(true), DefaultValue(""), Localizable(true), SRCategory(SR.CatFolderBrowsing), SRDescription(SR.FolderBrowserDialogDescription) ] public string Description { get { return descriptionText; } set { descriptionText = (value == null) ? String.Empty : value; } } ////// Gets or sets a description to show above the folders. Here you can provide instructions for /// selecting a folder. /// ////// 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]; } ////// /// public override void Reset() { rootFolder = System.Environment.SpecialFolder.Desktop; descriptionText = String.Empty; selectedPath = String.Empty; selectedPathNeedsCheck = false; showNewFolderButton = true; } ////// Resets all properties to their default values. /// ////// /// 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 = unchecked( (int) (long)UnsafeNativeMethods.BrowseInfos.NewDialogStyle); if (!showNewFolderButton) { mergedOptions += unchecked( (int) (long)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.CoTaskMemFree(pidlRoot); if (pidlRet != IntPtr.Zero) { UnsafeNativeMethods.CoTaskMemFree(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. // //----------------------------------------------------------------------------- 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; ////// /// [ 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; ////// Represents a common dialog box that allows the user to specify options for /// selecting a folder. This class cannot be inherited. /// ////// /// public FolderBrowserDialog() { Reset(); } ////// Initializes a new instance of the ///class. /// /// [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; } } ////// /// [ Browsable(true), DefaultValue(""), Localizable(true), SRCategory(SR.CatFolderBrowsing), SRDescription(SR.FolderBrowserDialogDescription) ] public string Description { get { return descriptionText; } set { descriptionText = (value == null) ? String.Empty : value; } } ////// Gets or sets a description to show above the folders. Here you can provide instructions for /// selecting a folder. /// ////// 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]; } ////// /// public override void Reset() { rootFolder = System.Environment.SpecialFolder.Desktop; descriptionText = String.Empty; selectedPath = String.Empty; selectedPathNeedsCheck = false; showNewFolderButton = true; } ////// Resets all properties to their default values. /// ////// /// 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 = unchecked( (int) (long)UnsafeNativeMethods.BrowseInfos.NewDialogStyle); if (!showNewFolderButton) { mergedOptions += unchecked( (int) (long)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.CoTaskMemFree(pidlRoot); if (pidlRet != IntPtr.Zero) { UnsafeNativeMethods.CoTaskMemFree(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.
Link Menu
![Network programming in C#, Network Programming in VB.NET, Network Programming in .NET](/images/book.jpg)
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- pingexception.cs
- TransportListener.cs
- CreateUserWizard.cs
- Error.cs
- AnimationException.cs
- SpanIndex.cs
- AliasExpr.cs
- ListViewTableCell.cs
- SessionStateItemCollection.cs
- HashLookup.cs
- MonitorWrapper.cs
- SoapIncludeAttribute.cs
- DataRelationCollection.cs
- MenuCommand.cs
- XamlBrushSerializer.cs
- DummyDataSource.cs
- ContainerSelectorGlyph.cs
- ScrollBarAutomationPeer.cs
- sortedlist.cs
- DataGridCell.cs
- externdll.cs
- Highlights.cs
- MergePropertyDescriptor.cs
- SystemWebExtensionsSectionGroup.cs
- SoapObjectReader.cs
- Documentation.cs
- ETagAttribute.cs
- MsmqQueue.cs
- TreeView.cs
- SqlClientWrapperSmiStreamChars.cs
- HelpKeywordAttribute.cs
- CookieHandler.cs
- TextHidden.cs
- ScriptReferenceBase.cs
- SQLInt64.cs
- RenderData.cs
- Int32Rect.cs
- ObjectQueryProvider.cs
- AnnotationResourceChangedEventArgs.cs
- TracingConnectionInitiator.cs
- IndexedGlyphRun.cs
- SafeThemeHandle.cs
- RectValueSerializer.cs
- AuthenticationException.cs
- SplitterPanel.cs
- SymbolType.cs
- SettingsPropertyCollection.cs
- DataView.cs
- BitmapEffectInputConnector.cs
- SimpleTypeResolver.cs
- BamlRecordHelper.cs
- ElementNotEnabledException.cs
- AccessedThroughPropertyAttribute.cs
- Exception.cs
- LocalFileSettingsProvider.cs
- MailAddress.cs
- VectorAnimationBase.cs
- MessageHeader.cs
- ObjectDataSourceStatusEventArgs.cs
- _LocalDataStore.cs
- BinaryFormatterWriter.cs
- NullRuntimeConfig.cs
- SqlCommandSet.cs
- ChildDocumentBlock.cs
- Debugger.cs
- CipherData.cs
- ToolTipService.cs
- RepeatButton.cs
- SrgsSubset.cs
- HtmlFormWrapper.cs
- FragmentQuery.cs
- WsdlInspector.cs
- TextEndOfParagraph.cs
- LinqDataSourceDeleteEventArgs.cs
- SourceChangedEventArgs.cs
- XmlBinaryWriterSession.cs
- AxisAngleRotation3D.cs
- SafeMILHandle.cs
- RepeaterCommandEventArgs.cs
- EntityDataSourceViewSchema.cs
- GeneralTransform3D.cs
- BitmapSource.cs
- ObjectListCommandsPage.cs
- UniqueEventHelper.cs
- HandlerBase.cs
- MexHttpsBindingElement.cs
- HtmlPhoneCallAdapter.cs
- DataGridViewCellCancelEventArgs.cs
- FrameworkContentElement.cs
- StaticResourceExtension.cs
- ObjectDisposedException.cs
- complextypematerializer.cs
- StringToken.cs
- DataGridViewBand.cs
- TableRow.cs
- FreezableOperations.cs
- BindingExpression.cs
- GridErrorDlg.cs
- KeyFrames.cs
- PropertyMetadata.cs