Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ProfilePropertyNameValidator.cs
- SoapReflector.cs
- DiagnosticTraceSource.cs
- RtfNavigator.cs
- MemberMaps.cs
- HtmlTable.cs
- Geometry3D.cs
- GridViewHeaderRowPresenter.cs
- _OverlappedAsyncResult.cs
- SqlConnection.cs
- SmtpSpecifiedPickupDirectoryElement.cs
- WindowsGraphics.cs
- TreeViewItem.cs
- ChangeConflicts.cs
- HttpFileCollection.cs
- SafeFileHandle.cs
- XMLUtil.cs
- RsaSecurityKey.cs
- DataServiceKeyAttribute.cs
- DataRelationPropertyDescriptor.cs
- Table.cs
- HwndSourceKeyboardInputSite.cs
- HelpKeywordAttribute.cs
- TextServicesLoader.cs
- EventLogEntryCollection.cs
- HtmlInputHidden.cs
- WindowsImpersonationContext.cs
- ImageSourceValueSerializer.cs
- EtwTrackingParticipant.cs
- RequestUriProcessor.cs
- CodeCastExpression.cs
- DataObjectPastingEventArgs.cs
- SparseMemoryStream.cs
- MembershipSection.cs
- GridViewItemAutomationPeer.cs
- DebugController.cs
- HttpDebugHandler.cs
- ToolStripTextBox.cs
- DataGridBoolColumn.cs
- X509CertificateCollection.cs
- StrokeNodeOperations2.cs
- MergePropertyDescriptor.cs
- MappingSource.cs
- DigitShape.cs
- TypedElement.cs
- ArrayEditor.cs
- LayoutTable.cs
- FuncCompletionCallbackWrapper.cs
- OleDbWrapper.cs
- ChtmlTextWriter.cs
- SortedSet.cs
- OdbcConnectionOpen.cs
- BufferBuilder.cs
- HttpRawResponse.cs
- xmlfixedPageInfo.cs
- DiscoveryClientProtocol.cs
- GeneralTransform3DTo2DTo3D.cs
- Camera.cs
- LowerCaseStringConverter.cs
- ApplicationSecurityManager.cs
- PeekCompletedEventArgs.cs
- WorkerRequest.cs
- ObjectContext.cs
- SelectionService.cs
- EncodingInfo.cs
- PeerNameRecordCollection.cs
- StrongBox.cs
- XmlSerializationWriter.cs
- UrlAuthFailedErrorFormatter.cs
- StringUtil.cs
- ParseChildrenAsPropertiesAttribute.cs
- ToolStripInSituService.cs
- NamespaceInfo.cs
- ExtensionSurface.cs
- OpCodes.cs
- Missing.cs
- AbstractDataSvcMapFileLoader.cs
- ConfigXmlWhitespace.cs
- DataGridViewRowPostPaintEventArgs.cs
- RestClientProxyHandler.cs
- ColorAnimationBase.cs
- PointLight.cs
- OleDbRowUpdatedEvent.cs
- ContextProperty.cs
- EventLogSession.cs
- TemplateControlParser.cs
- Pen.cs
- SelectionItemProviderWrapper.cs
- PasswordPropertyTextAttribute.cs
- Interlocked.cs
- DataServiceHostFactory.cs
- TimeSpanValidatorAttribute.cs
- Utilities.cs
- MouseGesture.cs
- EditorPartCollection.cs
- ListDictionary.cs
- MenuItemCollection.cs
- XhtmlStyleClass.cs
- BinaryNode.cs
- TailCallAnalyzer.cs