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; ////// /// [ 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 = (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
- SpeechUI.cs
- WebPartConnectionsConnectVerb.cs
- WebCategoryAttribute.cs
- XmlReader.cs
- WebUtil.cs
- JournalEntry.cs
- GridLength.cs
- PkcsMisc.cs
- GridViewDeleteEventArgs.cs
- ContentFileHelper.cs
- ImportContext.cs
- RefType.cs
- IndexedSelectQueryOperator.cs
- ObjectViewFactory.cs
- SystemInfo.cs
- PathSegmentCollection.cs
- HierarchicalDataBoundControl.cs
- Utils.cs
- safesecurityhelperavalon.cs
- InteropAutomationProvider.cs
- RSAOAEPKeyExchangeFormatter.cs
- DbFunctionCommandTree.cs
- BinaryUtilClasses.cs
- SmiRecordBuffer.cs
- HeaderUtility.cs
- DefaultHttpHandler.cs
- NavigationFailedEventArgs.cs
- TrackBar.cs
- DesignColumn.cs
- GuidTagList.cs
- XmlSchemaInferenceException.cs
- BaseCAMarshaler.cs
- CardSpaceException.cs
- XsdBuildProvider.cs
- HttpCacheParams.cs
- Geometry.cs
- AsymmetricSignatureFormatter.cs
- DesignTimeVisibleAttribute.cs
- ArrayConverter.cs
- EntryIndex.cs
- X509RecipientCertificateServiceElement.cs
- TransactionContextValidator.cs
- InternalEnumValidator.cs
- StringInfo.cs
- GenericsInstances.cs
- CustomErrorCollection.cs
- CodeTypeDeclaration.cs
- WebPartRestoreVerb.cs
- HttpBrowserCapabilitiesWrapper.cs
- OleDbError.cs
- CompilerGeneratedAttribute.cs
- TreeView.cs
- TemplateField.cs
- DataGridCellsPresenter.cs
- SystemColors.cs
- RotateTransform3D.cs
- MimeMapping.cs
- ComplusEndpointConfigContainer.cs
- cookiecollection.cs
- PerformanceCounterTraceRecord.cs
- TypeInitializationException.cs
- Gdiplus.cs
- ZipPackagePart.cs
- RadioButton.cs
- XmlObjectSerializerWriteContextComplexJson.cs
- XmlNodeWriter.cs
- EntityCommand.cs
- ToolStripItemCollection.cs
- Drawing.cs
- PropagatorResult.cs
- UriExt.cs
- RuntimeArgumentHandle.cs
- DesignerForm.cs
- WindowExtensionMethods.cs
- ModifiableIteratorCollection.cs
- InternalDuplexChannelListener.cs
- EntityDataSourceReferenceGroup.cs
- AnnotationService.cs
- HttpHandlerActionCollection.cs
- WindowsTokenRoleProvider.cs
- Internal.cs
- FileRegion.cs
- SpotLight.cs
- ResourceDictionaryCollection.cs
- ConsoleTraceListener.cs
- CategoryAttribute.cs
- LayoutSettings.cs
- ProcessHost.cs
- DurationConverter.cs
- ConfigXmlReader.cs
- AttachedPropertyBrowsableForChildrenAttribute.cs
- ContentElement.cs
- MultiAsyncResult.cs
- exports.cs
- ModelItem.cs
- DataBinder.cs
- UpdateTracker.cs
- BaseTemplateParser.cs
- KeysConverter.cs
- StateRuntime.cs