Code:
/ FX-1434 / FX-1434 / 1.0 / untmp / whidbey / REDBITS / ndp / fx / src / WinForms / Managed / System / WinForms / FileDialog.cs / 2 / FileDialog.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- namespace System.Windows.Forms { using System.Text; using System.Threading; using System.Runtime.Remoting; using System.Runtime.InteropServices; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System; using System.Security.Permissions; using System.Drawing; using System.ComponentModel; using System.Windows.Forms; using System.IO; using ArrayList = System.Collections.ArrayList; using Encoding = System.Text.Encoding; using Microsoft.Win32; using System.Security; using CharBuffer = System.Windows.Forms.UnsafeNativeMethods.CharBuffer; ////// /// [ DefaultEvent("FileOk"), DefaultProperty("FileName") ] public abstract partial class FileDialog : CommonDialog { private const int FILEBUFSIZE = 8192; ////// Displays a dialog window from which the user can select a file. /// ////// /// ///[To be supplied.] ///protected static readonly object EventFileOk = new object(); internal const int OPTION_ADDEXTENSION = unchecked(unchecked((int)0x80000000)); internal int options; private string title; private string initialDir; private string defaultExt; private string[] fileNames; private bool securityCheckFileNames; private string filter; private int filterIndex; private bool supportMultiDottedExtensions; private bool ignoreSecondFileOkNotification; // Used for VS Whidbey 95342 private int okNotificationCount; // Same private CharBuffer charBuffer; private IntPtr dialogHWnd; /// /// /// [ SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors") // If the constructor does not call Reset // it would be a breaking change. ] internal FileDialog() { Reset(); } ////// In an inherited class, /// initializes a new instance of the ////// class. /// /// /// [ SRCategory(SR.CatBehavior), DefaultValue(true), SRDescription(SR.FDaddExtensionDescr) ] public bool AddExtension { get { return GetOption(OPTION_ADDEXTENSION); } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); SetOption(OPTION_ADDEXTENSION, value); } } ////// Gets or sets a value indicating whether the /// dialog box automatically adds an extension to a /// file name if the user omits the extension. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(false), SRDescription(SR.FDcheckFileExistsDescr) ] public virtual bool CheckFileExists { get { return GetOption(NativeMethods.OFN_FILEMUSTEXIST); } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); SetOption(NativeMethods.OFN_FILEMUSTEXIST, value); } } ///Gets or sets a value indicating whether /// the dialog box displays a warning if the user specifies a file name that does not exist. ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(true), SRDescription(SR.FDcheckPathExistsDescr) ] public bool CheckPathExists { get { return GetOption(NativeMethods.OFN_PATHMUSTEXIST); } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); SetOption(NativeMethods.OFN_PATHMUSTEXIST, value); } } ////// Gets or sets a value indicating whether the /// dialog box displays a warning if the user specifies a path that does not exist. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(""), SRDescription(SR.FDdefaultExtDescr) ] public string DefaultExt { get { return defaultExt == null? "": defaultExt; } set { if (value != null) { if (value.StartsWith(".")) value = value.Substring(1); else if (value.Length == 0) value = null; } defaultExt = value; } } ////// Gets or sets the default file extension. /// /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(true), SRDescription(SR.FDdereferenceLinksDescr) ] public bool DereferenceLinks { get { return !GetOption(NativeMethods.OFN_NODEREFERENCELINKS); } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); SetOption(NativeMethods.OFN_NODEREFERENCELINKS, !value); } } internal string DialogCaption { get { int textLen = SafeNativeMethods.GetWindowTextLength(new HandleRef(this, dialogHWnd)); StringBuilder sb = new StringBuilder(textLen+1); UnsafeNativeMethods.GetWindowText(new HandleRef(this, dialogHWnd), sb, sb.Capacity); return sb.ToString(); } } ////// Gets or sets a value /// indicating whether the dialog box returns the location of the file referenced by the shortcut or /// whether it returns the location of the shortcut (.lnk). /// ////// /// [ SRCategory(SR.CatData), DefaultValue(""), SRDescription(SR.FDfileNameDescr) ] public string FileName { get { if (fileNames == null) { return ""; } else { if (fileNames[0].Length > 0) { // See if we need to perform a security check on file names. We need // to do this if the set of file names was provided by the file dialog. // A developer can set file names through the FileDialog API as well, // but we don't need to check those since the developer can provide any // name s/he wants. This is important because it is otherwise possible // to get the FileName property to accept garbage, but throw during get. if (securityCheckFileNames) { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileIO(" + fileNames[0] + ") Demanded"); IntSecurity.DemandFileIO(FileIOPermissionAccess.AllAccess, fileNames[0]); } return fileNames[0]; } else { return ""; } } } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); if (value == null) { fileNames = null; } else { fileNames = new string[] {value}; } // As the developer has called this API and set the file name with an arbitrary value, // we do not need to perform a security check on the name. securityCheckFileNames = false; } } ////// Gets /// or sets a string containing /// the file name selected in the file dialog box. /// ////// /// [ Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), SRDescription(SR.FDFileNamesDescr) ] public string[] FileNames { get{ string[] files = FileNamesInternal; // See if we need to perform a security check on file names. We need // to do this if the set of file names was provided by the file dialog. // A developer can set file names through the FileDialog API as well, // but we don't need to check those since the developer can provide any // name s/he wants. This is important because it is otherwise possible // to get the FileName property to accept garbage, but throw during get. if (securityCheckFileNames) { foreach (string file in files) { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileIO(" + file + ") Demanded"); IntSecurity.DemandFileIO(FileIOPermissionAccess.AllAccess, file); } } return files; } } internal string[] FileNamesInternal { get { if (fileNames == null) { return new string[0]; } else { return(string[])fileNames.Clone(); } } } ////// Gets the file /// names of all selected files in the dialog box. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(""), Localizable(true), SRDescription(SR.FDfilterDescr) ] public string Filter { get { return filter == null? "": filter; } set { if (value != filter) { if (value != null && value.Length > 0) { string[] formats = value.Split('|'); if (formats == null || formats.Length % 2 != 0) { throw new ArgumentException(SR.GetString(SR.FileDialogInvalidFilter)); } } else { value = null; } filter = value; } } } ////// Gets /// or sets the current file name filter string, /// which determines the choices that appear in the "Save as file type" or /// "Files of type" box in the dialog box. /// ////// /// Extracts the file extensions specified by the current file filter into /// an array of strings. None of the extensions contain .'s, and the /// default extension is first. /// private string[] FilterExtensions { get { string filter = this.filter; ArrayList extensions = new ArrayList(); // First extension is the default one. It's a little strange if DefaultExt // is not in the filters list, but I guess it's legal. if (defaultExt != null) extensions.Add(defaultExt); if (filter != null) { string[] tokens = filter.Split('|'); if ((filterIndex * 2) - 1 >= tokens.Length) { throw new InvalidOperationException(SR.GetString(SR.FileDialogInvalidFilterIndex)); } if (filterIndex > 0) { string[] exts = tokens[(filterIndex * 2) - 1].Split(';'); foreach (string ext in exts) { int i = this.supportMultiDottedExtensions ? ext.IndexOf('.') : ext.LastIndexOf('.'); if (i >= 0) { extensions.Add(ext.Substring(i + 1, ext.Length - (i + 1))); } } } } string[] temp = new string[extensions.Count]; extensions.CopyTo(temp, 0); return temp; } } ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(1), SRDescription(SR.FDfilterIndexDescr) ] public int FilterIndex { get { return filterIndex; } set { filterIndex = value; } } ////// Gets or sets the index of the filter currently selected in the file dialog box. /// ////// /// [ SRCategory(SR.CatData), DefaultValue(""), SRDescription(SR.FDinitialDirDescr) ] public string InitialDirectory { get { return initialDir == null? "": initialDir; } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); initialDir = value; } } ////// Gets or sets the initial directory displayed by the file dialog /// box. /// ////// /// /// /* SECURITYUNDONE : should require EventQueue permission */ protected virtual IntPtr Instance { [ SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode), SecurityPermission(SecurityAction.InheritanceDemand, Flags=SecurityPermissionFlag.UnmanagedCode) ] get { return UnsafeNativeMethods.GetModuleHandle(null); } } ////// Gets the Win32 instance handle for the application. /// ////// /// /// protected int Options { get { return options & (NativeMethods.OFN_READONLY | NativeMethods.OFN_HIDEREADONLY | NativeMethods.OFN_NOCHANGEDIR | NativeMethods.OFN_SHOWHELP | NativeMethods.OFN_NOVALIDATE | NativeMethods.OFN_ALLOWMULTISELECT | NativeMethods.OFN_PATHMUSTEXIST | NativeMethods.OFN_NODEREFERENCELINKS); } } ////// Gets the Win32 common Open File Dialog OFN_* option flags. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(false), SRDescription(SR.FDrestoreDirectoryDescr) ] public bool RestoreDirectory { get { return GetOption(NativeMethods.OFN_NOCHANGEDIR); } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); SetOption(NativeMethods.OFN_NOCHANGEDIR, value); } } ////// Gets or sets a value indicating whether the dialog box restores the current directory before /// closing. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(false), SRDescription(SR.FDshowHelpDescr) ] public bool ShowHelp { get { return GetOption(NativeMethods.OFN_SHOWHELP); } set { SetOption(NativeMethods.OFN_SHOWHELP, value); } } ////// Gets or sets a value indicating /// whether whether the Help button is displayed in the file dialog. /// /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(false), SRDescription(SR.FDsupportMultiDottedExtensionsDescr) ] public bool SupportMultiDottedExtensions { get { return this.supportMultiDottedExtensions; } set { this.supportMultiDottedExtensions = value; } } ////// Gets or sets whether def or abc.def is the extension of the file filename.abc.def /// ////// /// [ SRCategory(SR.CatAppearance), DefaultValue(""), Localizable(true), SRDescription(SR.FDtitleDescr) ] public string Title { get { return title == null? "": title; } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); title = value; } } ////// Gets or sets the file dialog box title. /// ////// /// [ SRCategory(SR.CatBehavior), DefaultValue(true), SRDescription(SR.FDvalidateNamesDescr) ] public bool ValidateNames { get { return !GetOption(NativeMethods.OFN_NOVALIDATE); } set { Debug.WriteLineIf(IntSecurity.SecurityDemand.TraceVerbose, "FileDialogCustomization Demanded"); IntSecurity.FileDialogCustomization.Demand(); SetOption(NativeMethods.OFN_NOVALIDATE, !value); } } ////// Gets or sets a value indicating whether the dialog box accepts only valid /// Win32 file names. /// ////// /// [SRDescription(SR.FDfileOkDescr)] public event CancelEventHandler FileOk { add { Events.AddHandler(EventFileOk, value); } remove { Events.RemoveHandler(EventFileOk, value); } } ////// Occurs when the user clicks on the Open or Save button on a file dialog /// box. /// ////// ////// For information about handling events, see ///. /// /// /// Processes the CDN_FILEOK notification. /// private bool DoFileOk(IntPtr lpOFN) { NativeMethods.OPENFILENAME_I ofn = (NativeMethods.OPENFILENAME_I)UnsafeNativeMethods.PtrToStructure(lpOFN, typeof(NativeMethods.OPENFILENAME_I)); int saveOptions = options; int saveFilterIndex = filterIndex; string[] saveFileNames = fileNames; bool saveSecurityCheckFileNames = securityCheckFileNames; bool ok = false; try { options = options & ~NativeMethods.OFN_READONLY | ofn.Flags & NativeMethods.OFN_READONLY; filterIndex = ofn.nFilterIndex; charBuffer.PutCoTaskMem(ofn.lpstrFile); // We are filling in the file names list with secure // data. Any access to this list now will require // a security demand. We set this bit before actually // setting the names; otherwise a thread race could // expose them. securityCheckFileNames = true; Thread.MemoryBarrier(); if ((options & NativeMethods.OFN_ALLOWMULTISELECT) == 0) { fileNames = new string[] {charBuffer.GetString()}; } else { fileNames = GetMultiselectFiles(charBuffer); } if (ProcessFileNames()) { CancelEventArgs ceevent = new CancelEventArgs(); if (NativeWindow.WndProcShouldBeDebuggable) { OnFileOk(ceevent); ok = !ceevent.Cancel; } else { try { OnFileOk(ceevent); ok = !ceevent.Cancel; } catch (Exception e) { Application.OnThreadException(e); } } } } finally { if (!ok) { securityCheckFileNames = saveSecurityCheckFileNames; Thread.MemoryBarrier(); fileNames = saveFileNames; options = saveOptions; filterIndex = saveFilterIndex; } } return ok; } /// 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: filename is a local variable and not subject to race conditions. [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")] internal static bool FileExists(string fileName) { bool fileExists = false; try { // SECREVIEW : We must Assert just to check if the file exists. Since // : we are doing this as part of the FileDialog, this is OK. new FileIOPermission(FileIOPermissionAccess.Read, IntSecurity.UnsafeGetFullPath(fileName)).Assert(); try { fileExists = File.Exists(fileName); } finally { CodeAccessPermission.RevertAssert(); } } catch (System.IO.PathTooLongException) { } return fileExists; } ////// /// Extracts the filename(s) returned by the file dialog. /// private string[] GetMultiselectFiles(CharBuffer charBuffer) { string directory = charBuffer.GetString(); string fileName = charBuffer.GetString(); if (fileName.Length == 0) return new string[] { directory }; if (directory[directory.Length - 1] != '\\') { directory = directory + "\\"; } ArrayList names = new ArrayList(); do { if (fileName[0] != '\\' && (fileName.Length <= 3 || fileName[1] != ':' || fileName[2] != '\\')) { fileName = directory + fileName; } names.Add(fileName); fileName = charBuffer.GetString(); } while (fileName.Length > 0); string[] temp = new string[names.Count]; names.CopyTo(temp, 0); return temp; } ////// /// Returns the state of the given option flag. /// ///internal bool GetOption(int option) { return(options & option) != 0; } /// /// /// [SecurityPermission(SecurityAction.LinkDemand, Flags=SecurityPermissionFlag.UnmanagedCode)] protected override IntPtr HookProc(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) { if (msg == NativeMethods.WM_NOTIFY) { dialogHWnd = UnsafeNativeMethods.GetParent(new HandleRef(null, hWnd)); try { UnsafeNativeMethods.OFNOTIFY notify = (UnsafeNativeMethods.OFNOTIFY)UnsafeNativeMethods.PtrToStructure(lparam, typeof(UnsafeNativeMethods.OFNOTIFY)); switch (notify.hdr_code) { case -601: /* CDN_INITDONE */ MoveToScreenCenter(dialogHWnd); break; case -602: /* CDN_SELCHANGE */ NativeMethods.OPENFILENAME_I ofn = (NativeMethods.OPENFILENAME_I)UnsafeNativeMethods.PtrToStructure(notify.lpOFN, typeof(NativeMethods.OPENFILENAME_I)); // Get the buffer size required to store the selected file names. int sizeNeeded = (int)UnsafeNativeMethods.SendMessage(new HandleRef(this, dialogHWnd), 1124 /*CDM_GETSPEC*/, System.IntPtr.Zero, System.IntPtr.Zero); if (sizeNeeded > ofn.nMaxFile) { // A bigger buffer is required. try { int newBufferSize = sizeNeeded + (FILEBUFSIZE / 4); // Allocate new buffer CharBuffer charBufferTmp = CharBuffer.CreateBuffer(newBufferSize); IntPtr newBuffer = charBufferTmp.AllocCoTaskMem(); // Free old buffer Marshal.FreeCoTaskMem(ofn.lpstrFile); // Substitute buffer ofn.lpstrFile = newBuffer; ofn.nMaxFile = newBufferSize; this.charBuffer = charBufferTmp; Marshal.StructureToPtr(ofn, notify.lpOFN, true); Marshal.StructureToPtr(notify, lparam, true); } catch { // intentionaly not throwing here. } } this.ignoreSecondFileOkNotification = false; break; case -604: /* CDN_SHAREVIOLATION */ // See VS Whidbey 95342. When the selected file is locked for writing, // we get this notification followed by *two* CDN_FILEOK notifications. this.ignoreSecondFileOkNotification = true; // We want to ignore the second CDN_FILEOK this.okNotificationCount = 0; // to avoid a second prompt by PromptFileOverwrite. break; case -606: /* CDN_FILEOK */ if (this.ignoreSecondFileOkNotification) { // We got a CDN_SHAREVIOLATION notification and want to ignore the second CDN_FILEOK notification if (this.okNotificationCount == 0) { this.okNotificationCount = 1; // This one is the first and is all right. } else { // This is the second CDN_FILEOK, so we want to ignore it. this.ignoreSecondFileOkNotification = false; UnsafeNativeMethods.SetWindowLong(new HandleRef(null, hWnd), 0, new HandleRef(null, NativeMethods.InvalidIntPtr)); return NativeMethods.InvalidIntPtr; } } if (!DoFileOk(notify.lpOFN)) { UnsafeNativeMethods.SetWindowLong(new HandleRef(null, hWnd), 0, new HandleRef(null, NativeMethods.InvalidIntPtr)); return NativeMethods.InvalidIntPtr; } break; } } catch { if (dialogHWnd != IntPtr.Zero) { UnsafeNativeMethods.EndDialog(new HandleRef(this, dialogHWnd), IntPtr.Zero); } throw; } } return IntPtr.Zero; } ////// Defines the common dialog box hook procedure that is overridden to add /// specific functionality to the file dialog box. /// ////// /// Converts the given filter string to the format required in an OPENFILENAME_I /// structure. /// private static string MakeFilterString(string s, bool dereferenceLinks) { if (s == null || s.Length == 0) { // Workaround for Whidbey bug #5165 // Apply the workaround only when DereferenceLinks is true and OS is at least WinXP. if (dereferenceLinks && System.Environment.OSVersion.Version.Major >= 5) { s = " |*.*"; } else if (s == null) { return null; } } int length = s.Length; char[] filter = new char[length + 2]; s.CopyTo(0, filter, 0, length); for (int i = 0; i < length; i++) { if (filter[i] == '|') filter[i] = (char)0; } filter[length + 1] = (char)0; return new string(filter); } ////// /// protected void OnFileOk(CancelEventArgs e) { CancelEventHandler handler = (CancelEventHandler)Events[EventFileOk]; if (handler != null) handler(this, e); } ////// Raises the ///event. /// /// /// Processes the filenames entered in the dialog according to the settings /// of the "addExtension", "checkFileExists", "createPrompt", and /// "overwritePrompt" properties. /// private bool ProcessFileNames() { if ((options & NativeMethods.OFN_NOVALIDATE) == 0) { string[] extensions = FilterExtensions; for (int i = 0; i < fileNames.Length; i++) { string fileName = fileNames[i]; if ((options & OPTION_ADDEXTENSION) != 0 && !Path.HasExtension(fileName)) { bool fileMustExist = (options & NativeMethods.OFN_FILEMUSTEXIST) != 0; for (int j = 0; j < extensions.Length; j++) { string currentExtension = Path.GetExtension(fileName); Debug.Assert(!extensions[j].StartsWith("."), "FileDialog.FilterExtensions should not return things starting with '.'"); Debug.Assert(currentExtension.Length == 0 || currentExtension.StartsWith("."), "File.GetExtension should return something that starts with '.'"); string s = fileName.Substring(0, fileName.Length - currentExtension.Length); // we don't want to append the extension if it contains wild cards if (extensions[j].IndexOfAny(new char[] { '*', '?' }) == -1) { s += "." + extensions[j]; } if (!fileMustExist || FileExists(s)) { fileName = s; break; } } fileNames[i] = fileName; } if (!PromptUserIfAppropriate(fileName)) return false; } } return true; } ////// /// internal bool MessageBoxWithFocusRestore(string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon) { bool ret; IntPtr focusHandle = UnsafeNativeMethods.GetFocus(); try { ret = RTLAwareMessageBox.Show(null, message, caption, buttons, icon, MessageBoxDefaultButton.Button1, 0) == DialogResult.Yes; } finally { UnsafeNativeMethods.SetFocus(new HandleRef(null, focusHandle)); } return ret; } ////// Prompts the user with a ////// with the given parameters. It also ensures that /// the focus is set back on the window that had /// the focus to begin with (before we displayed /// the MessageBox). /// /// /// private void PromptFileNotFound(string fileName) { MessageBoxWithFocusRestore(SR.GetString(SR.FileDialogFileNotFound, fileName), DialogCaption, MessageBoxButtons.OK, MessageBoxIcon.Warning); } // If it's necessary to throw up a "This file exists, are you sure?" kind of // MessageBox, here's where we do it // Return value is whether or not the user hit "okay". internal virtual bool PromptUserIfAppropriate(string fileName) { if ((options & NativeMethods.OFN_FILEMUSTEXIST) != 0) { if (!FileExists(fileName)) { PromptFileNotFound(fileName); return false; } } return true; } ////// Prompts the user with a ////// when a file /// does not exist. /// /// /// public override void Reset() { options = NativeMethods.OFN_HIDEREADONLY | NativeMethods.OFN_PATHMUSTEXIST | OPTION_ADDEXTENSION; title = null; initialDir = null; defaultExt = null; fileNames = null; filter = null; filterIndex = 1; supportMultiDottedExtensions = false; this._customPlaces.Clear(); } ////// Resets all properties to their default values. /// ////// /// Implements running of a file dialog. /// ///protected override bool RunDialog(IntPtr hWndOwner) { // See VSWhidbey bug 107000. Shell APIs do not support multisthreaded apartment model. if (Control.CheckForIllegalCrossThreadCalls && Application.OleRequired() != System.Threading.ApartmentState.STA) { throw new System.Threading.ThreadStateException(SR.GetString(SR.DebuggingExceptionOnly, SR.GetString(SR.ThreadMustBeSTA))); } EnsureFileDialogPermission(); if (this.UseVistaDialogInternal) { return RunDialogVista(hWndOwner); } else { return RunDialogOld(hWndOwner); } } internal abstract void EnsureFileDialogPermission(); private bool RunDialogOld(IntPtr hWndOwner) { NativeMethods.WndProc hookProcPtr = new NativeMethods.WndProc(this.HookProc); NativeMethods.OPENFILENAME_I ofn = new NativeMethods.OPENFILENAME_I(); try { charBuffer = CharBuffer.CreateBuffer(FILEBUFSIZE); if (fileNames != null) { charBuffer.PutString(fileNames[0]); } ofn.lStructSize = Marshal.SizeOf(typeof(NativeMethods.OPENFILENAME_I)); // Degrade to the older style dialog if we're not on Win2K. // We do this by setting the struct size to a different value // if (Environment.OSVersion.Platform != System.PlatformID.Win32NT || Environment.OSVersion.Version.Major < 5) { ofn.lStructSize = 0x4C; } ofn.hwndOwner = hWndOwner; ofn.hInstance = Instance; ofn.lpstrFilter = MakeFilterString(filter, this.DereferenceLinks); ofn.nFilterIndex = filterIndex; ofn.lpstrFile = charBuffer.AllocCoTaskMem(); ofn.nMaxFile = FILEBUFSIZE; ofn.lpstrInitialDir = initialDir; ofn.lpstrTitle = title; ofn.Flags = Options | (NativeMethods.OFN_EXPLORER | NativeMethods.OFN_ENABLEHOOK | NativeMethods.OFN_ENABLESIZING); ofn.lpfnHook = hookProcPtr; ofn.FlagsEx = NativeMethods.OFN_USESHELLITEM; if (defaultExt != null && AddExtension) { ofn.lpstrDefExt = defaultExt; } //Security checks happen here return RunFileDialog(ofn); } finally { charBuffer = null; if (ofn.lpstrFile != IntPtr.Zero) { Marshal.FreeCoTaskMem(ofn.lpstrFile); } } } /// /// /// Implements the actual call to GetOPENFILENAME_I or GetSaveFileName. /// ///internal abstract bool RunFileDialog(NativeMethods.OPENFILENAME_I ofn); /// /// /// Sets the given option to the given boolean value. /// ///internal void SetOption(int option, bool value) { if (value) { options |= option; } else { options &= ~option; } } /// /// /// /// public override string ToString() { StringBuilder sb = new StringBuilder(base.ToString() + ": Title: " + Title + ", FileName: "); try { sb.Append(FileName); } catch (Exception e) { sb.Append("<"); sb.Append(e.GetType().FullName); sb.Append(">"); } return sb.ToString(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved./// Provides a string version of this Object. /// ///
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- GridViewPageEventArgs.cs
- ObjectRef.cs
- FormViewUpdateEventArgs.cs
- StylusButton.cs
- HashCodeCombiner.cs
- ClickablePoint.cs
- RenderingEventArgs.cs
- TextTreeText.cs
- ToolStripControlHost.cs
- DataGridViewComboBoxEditingControl.cs
- SimpleMailWebEventProvider.cs
- DelimitedListTraceListener.cs
- NonSerializedAttribute.cs
- RoleService.cs
- Application.cs
- UxThemeWrapper.cs
- PasswordRecovery.cs
- FormViewRow.cs
- ScopelessEnumAttribute.cs
- EntityDataSourceSelectingEventArgs.cs
- InputReportEventArgs.cs
- BufferedGraphicsManager.cs
- ProviderUtil.cs
- JapaneseCalendar.cs
- UpdateManifestForBrowserApplication.cs
- PasswordDeriveBytes.cs
- DataGridViewRowsRemovedEventArgs.cs
- CFStream.cs
- AttributeProviderAttribute.cs
- ScrollChrome.cs
- RuntimeCompatibilityAttribute.cs
- TimeEnumHelper.cs
- AttributeQuery.cs
- Button.cs
- FixedSOMTableCell.cs
- Comparer.cs
- XmlElementAttributes.cs
- PopupEventArgs.cs
- DesignParameter.cs
- TemplateParser.cs
- ContentPosition.cs
- TemplatedWizardStep.cs
- SmiEventSink_DeferedProcessing.cs
- RadioButtonPopupAdapter.cs
- Rethrow.cs
- Camera.cs
- View.cs
- ReplyChannel.cs
- ImageField.cs
- HostedTransportConfigurationBase.cs
- TakeQueryOptionExpression.cs
- ToolStripPanelDesigner.cs
- SessionIDManager.cs
- TypeSource.cs
- UriTemplateHelpers.cs
- DataView.cs
- XmlQueryContext.cs
- StylusPointCollection.cs
- CodeCastExpression.cs
- SpellerInterop.cs
- ParameterCollectionEditor.cs
- SafeHandles.cs
- XmlChoiceIdentifierAttribute.cs
- XmlBinaryReaderSession.cs
- HtmlMeta.cs
- TransformedBitmap.cs
- dsa.cs
- HoistedLocals.cs
- SqlDataReader.cs
- InternalPolicyElement.cs
- ProtocolsConfigurationEntry.cs
- AstTree.cs
- FormsAuthentication.cs
- CatalogPartCollection.cs
- ProfileSettings.cs
- MsdtcWrapper.cs
- DataGridViewImageColumn.cs
- Predicate.cs
- PropertyManager.cs
- ClientRuntimeConfig.cs
- DataProtectionSecurityStateEncoder.cs
- Int64Storage.cs
- FontFamilyIdentifier.cs
- PrintDialog.cs
- StorageFunctionMapping.cs
- DataRowView.cs
- SizeValueSerializer.cs
- ConfigXmlComment.cs
- StringDictionaryCodeDomSerializer.cs
- TimeoutValidationAttribute.cs
- DataDocumentXPathNavigator.cs
- GeometryDrawing.cs
- MsmqIntegrationBinding.cs
- XmlNamespaceMapping.cs
- BCryptHashAlgorithm.cs
- DecoderExceptionFallback.cs
- BasicHttpMessageSecurityElement.cs
- XmlChildEnumerator.cs
- ReadOnlyTernaryTree.cs
- XmlConvert.cs