예제 #1
0
        //---------------------------------------------------
        //
        // Internal Methods
        //
        //---------------------------------------------------
        #region Internal Methods

        /// <summary>
        ///  Performs the actual call to display a file open dialog.
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// Thrown if there is an invalid filename, if
        /// a subclass failure occurs or if the buffer length
        /// allocated to store the filenames occurs.
        /// </exception>
        /// <remarks>
        ///  The call chain is ShowDialog > RunDialog >
        ///  RunFileDialog (this function).  In
        ///  FileDialog.RunDialog, we created the OPENFILENAME
        ///  structure - so all this function needs to do is
        ///  call GetOpenFileName and process the result code.
        /// </remarks>
        internal override bool RunFileDialog(NativeMethods.OPENFILENAME_I ofn)
        {
            bool result = false;

            // Make the actual call to GetOpenFileName.  This function
            // blocks on GetOpenFileName until the entire dialog display
            // is completed - any interaction we have with the dialog
            // while it's open takes place through our HookProc.  The
            // return value is a bool;  true = success.
            result = UnsafeNativeMethods.GetOpenFileName(ofn);

            if (!result)    // result was 0 (false), so an error occurred.
            {
                // Something may have gone wrong - check for error conditions
                // by calling CommDlgExtendedError to get the specific error.
                int errorCode = UnsafeNativeMethods.CommDlgExtendedError();

                // Throw an appropriate exception if we know what happened:
                switch (errorCode)
                {
                // FNERR_INVALIDFILENAME is usually triggered when an invalid initial filename is specified
                case NativeMethods.FNERR_INVALIDFILENAME:
                    throw new InvalidOperationException(SR.Get(SRID.FileDialogInvalidFileName, SafeFileName));

                case NativeMethods.FNERR_SUBCLASSFAILURE:
                    throw new InvalidOperationException(SR.Get(SRID.FileDialogSubClassFailure));

                // note for FNERR_BUFFERTOOSMALL:
                // This error likely indicates a problem with our buffer size growing code;
                // take a look at that part of HookProc if customers report this error message is occurring.
                case NativeMethods.FNERR_BUFFERTOOSMALL:
                    throw new InvalidOperationException(SR.Get(SRID.FileDialogBufferTooSmall));

                    /*
                     * According to MSDN, the following errors can also occur, but we do not handle them as
                     * they are very unlikely, and if they do occur, they indicate a catastrophic failure.
                     * Most are related to features we do not wrap in our implementation.
                     *
                     * CDERR_DIALOGFAILURE
                     * CDERR_FINDRESFAILURE
                     * CDERR_NOHINSTANCE
                     * CDERR_INITIALIZATION
                     * CDERR_NOHOOK
                     * CDERR_LOCKRESFAILURE
                     * CDERR_NOTEMPLATE
                     * CDERR_LOADRESFAILURE
                     * CDERR_STRUCTSIZE
                     * CDERR_LOADSTRFAILURE
                     * CDERR_MEMALLOCFAILURE
                     * CDERR_MEMLOCKFAILURE
                     */
                }
            }
            return(result);
        }
예제 #2
0
        private bool DoFileOk(IntPtr lpOFN)
        {
            NativeMethods.OPENFILENAME_I openfilename_I = (NativeMethods.OPENFILENAME_I)UnsafeNativeMethods.PtrToStructure(lpOFN, typeof(NativeMethods.OPENFILENAME_I));
            int value       = this._dialogOptions.Value;
            int filterIndex = this._filterIndex;

            string[] fileNames = this._fileNames;
            bool     flag      = false;

            try
            {
                this._dialogOptions.Value = ((this._dialogOptions.Value & -2) | (openfilename_I.Flags & 1));
                this._filterIndex         = openfilename_I.nFilterIndex;
                this._charBuffer.PutCoTaskMem(openfilename_I.lpstrFile);
                if (!this.GetOption(512))
                {
                    this._fileNames = new string[]
                    {
                        this._charBuffer.GetString()
                    };
                }
                else
                {
                    this._fileNames = FileDialog.GetMultiselectFiles(this._charBuffer);
                }
                if (this.ProcessFileNames())
                {
                    CancelEventArgs cancelEventArgs = new CancelEventArgs();
                    this.OnFileOk(cancelEventArgs);
                    flag = !cancelEventArgs.Cancel;
                }
            }
            finally
            {
                if (!flag)
                {
                    this._dialogOptions.Value = value;
                    this._filterIndex         = filterIndex;
                    this._fileNames           = fileNames;
                }
            }
            return(flag);
        }
예제 #3
0
        private bool RunLegacyDialog(IntPtr hwndOwner)
        {
            NativeMethods.WndProc        lpfnHook       = new NativeMethods.WndProc(this.HookProc);
            NativeMethods.OPENFILENAME_I openfilename_I = new NativeMethods.OPENFILENAME_I();
            bool result;

            try
            {
                this._charBuffer = NativeMethods.CharBuffer.CreateBuffer(8192);
                if (this._fileNames != null)
                {
                    this._charBuffer.PutString(this._fileNames[0]);
                }
                openfilename_I.lStructSize     = Marshal.SizeOf(typeof(NativeMethods.OPENFILENAME_I));
                openfilename_I.hwndOwner       = hwndOwner;
                openfilename_I.hInstance       = IntPtr.Zero;
                openfilename_I.lpstrFilter     = FileDialog.MakeFilterString(this._filter, this.DereferenceLinks);
                openfilename_I.nFilterIndex    = this._filterIndex;
                openfilename_I.lpstrFile       = this._charBuffer.AllocCoTaskMem();
                openfilename_I.nMaxFile        = this._charBuffer.Length;
                openfilename_I.lpstrInitialDir = this._initialDirectory.Value;
                openfilename_I.lpstrTitle      = this._title.Value;
                openfilename_I.Flags           = (this.Options | 8912928);
                openfilename_I.lpfnHook        = lpfnHook;
                openfilename_I.FlagsEx         = 16777216;
                if (this._defaultExtension != null && this.AddExtension)
                {
                    openfilename_I.lpstrDefExt = this._defaultExtension;
                }
                result = this.RunFileDialog(openfilename_I);
            }
            finally
            {
                this._charBuffer = null;
                if (openfilename_I.lpstrFile != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(openfilename_I.lpstrFile);
                }
            }
            return(result);
        }
예제 #4
0
        internal override bool RunFileDialog(NativeMethods.OPENFILENAME_I ofn)
        {
            bool openFileName = UnsafeNativeMethods.GetOpenFileName(ofn);

            if (!openFileName)
            {
                switch (UnsafeNativeMethods.CommDlgExtendedError())
                {
                case 12289:
                    throw new InvalidOperationException(SR.Get("FileDialogSubClassFailure"));

                case 12290:
                    throw new InvalidOperationException(SR.Get("FileDialogInvalidFileName", new object[]
                    {
                        base.SafeFileName
                    }));

                case 12291:
                    throw new InvalidOperationException(SR.Get("FileDialogBufferTooSmall"));
                }
            }
            return(openFileName);
        }
예제 #5
0
 private protected override bool RunFileDialog(NativeMethods.OPENFILENAME_I ofn)
 {
     return(RunFileDialogAction(ofn));
 }
예제 #6
0
        private bool RunLegacyDialog(IntPtr hwndOwner)
        {
            // Once we run the dialog, all of our communication with it is handled
            // by processing WM_NOTIFY messages in our hook procedure, this.HookProc.
            // NativeMethods.WndProc is a delegate with the appropriate signature
            // needed for a Win32 window hook procedure.
            NativeMethods.WndProc hookProcPtr = new NativeMethods.WndProc(this.HookProc);

            // Create a new OPENFILENAME structure.  OPENFILENAME is a structure defined
            // in Win32's commdlg.h that contains most of the information needed to
            // successfully display a file dialog box.
            // NOTE:  Despite the name, OPENFILENAME is the proper structure for both
            //        file open and file save dialogs.
            NativeMethods.OPENFILENAME_I ofn = new NativeMethods.OPENFILENAME_I();

            // do everything in a try block, so we always free memory in the finalizer
            try
            {
                // Create an appropriately sized buffer to hold the filenames.
                // The buffer's initial size is controlled by the FILEBUFSIZE constant,
                // an arbitrary value chosen so that we will rarely have to grow the buffer.
                _charBuffer = CharBuffer.CreateBuffer(FILEBUFSIZE);

                // If we have a filename stored in our internal array _fileNames,
                // place it in the buffer as a default filename.
                if (_fileNames != null)
                {
                    _charBuffer.PutString(_fileNames[0]);
                }

                // --- Set up the OPENFILENAME structure ---

                // lStructSize
                // Specifies the length, in bytes, of the structure. 
                ofn.lStructSize = Marshal.SizeOf(typeof(NativeMethods.OPENFILENAME_I));

                // hwndOwner
                // Handle to the window that owns the dialog box. This member can be any
                // valid window handle, or it can be NULL if the dialog box has no owner.
                ofn.hwndOwner = hwndOwner;

                // hInstance
                // This property is ignored unless OFN_ENABLETEMPLATEHANDLE or 
                // OFN_ENABLETEMPLATE are set.  Since we do not set either,
                // hInstance is ignored, so we can set it to zero.
                ofn.hInstance = IntPtr.Zero;

                // lpstrFilter
                // Pointer to a buffer containing pairs of null-terminated filter strings. 
                // The last string in the buffer must be terminated by two NULL characters. 
                // Since our filter strings are stored terminated by vertical bar '|' chars,
                // we call MakeFilterString to reformat and validate the filter string.
                ofn.lpstrFilter = MakeFilterString(_filter, this.DereferenceLinks);

                // nFilterIndex
                // Specifies the index of the currently selected filter in the File Types 
                // control.  Note that since 0 is reserved for a custom filter (which we
                // do not support), our valid filter indexes begin at 1.
                ofn.nFilterIndex = _filterIndex;

                // lpstrFile
                // Pointer to a buffer used to store filenames.  When initializing the
                // dialog, this name is used as an initial value in the File Name edit
                // control.  When files are selected and the function returns, the buffer
                // contains the full path to every file selected.
                ofn.lpstrFile = _charBuffer.AllocCoTaskMem();

                // nMaxFile
                // Size of the lpstrFile buffer in number of Unicode characters.
                ofn.nMaxFile = _charBuffer.Length;

                // lpstrInitialDir
                // Pointer to a null terminated string that can specify the initial directory.
                // A relatively complex algorithm is used to determine which directory is
                // actually used as the initial directory - for details, see MSDN for the
                // OPENFILENAME structure.
                ofn.lpstrInitialDir = _initialDirectory.Value;

                // lpstrTitle
                // Pointer to a string to be placed in the title bar of the dialog box.
                // NULL causes the title bar to display the operating system default string.
                ofn.lpstrTitle = _title.Value;

                // Flags
                // A set of bit flags you can use to initialize the dialog box.
                // Most of these will be set through public properties that then call
                // GetOption or SetOption.  We retrieve the flags using the Options property
                // and then add three additional flags here:
                //
                //     OFN_EXPLORER
                //         display an Explorer-style box (newer style)
                //     OFN_ENABLEHOOK
                //         enable the hook procedure (important for much of our functionality)
                //     OFN_ENABLESIZING
                //         allow the user to resize the dialog box
                //         
                ofn.Flags = Options | (NativeMethods.OFN_EXPLORER |
                                       NativeMethods.OFN_ENABLEHOOK |
                                       NativeMethods.OFN_ENABLESIZING);

                // lpfnHook
                // Pointer to the hook procedure.
                // Ignored unless OFN_ENABLEHOOK is set in Flags.
                ofn.lpfnHook = hookProcPtr;

                // FlagsEx
                // Can be either zero or OFN_EX_NOPLACESBAR, depending on whether
                // the Places Bar (My Computer/Favorites/etc) should be shown on the
                // left side of the file dialog.
                ofn.FlagsEx = NativeMethods.OFN_USESHELLITEM;

                // lpstrDefExt
                // Pointer to a buffer that contains the default extension;  it will
                // be appended to filenames if the user does not type an extension.
                // Only the first three characters are appended by Windows.  If this
                // is NULL, no extension is appended.
                if (_defaultExtension != null && AddExtension)
                {
                    ofn.lpstrDefExt = _defaultExtension;
                }

                // Call into either OpenFileDialog or SaveFileDialog to show the
                // actual dialog box.  This call blocks until the dialog is closed;
                // while dialog is open, all interaction is through HookProc.
                return RunFileDialog(ofn);
            }
            finally
            {
                // Explicitly set the character buffer to null.
                _charBuffer = null;

                // If there is still a pointer to a memory location in
                // ofn.lpstrFile, we explicitly free that memory here.
                if (ofn.lpstrFile != IntPtr.Zero)
                {
                    Marshal.FreeCoTaskMem(ofn.lpstrFile);
                }
            }
        }
예제 #7
0
 // Token: 0x0600020C RID: 524
 internal abstract bool RunFileDialog(NativeMethods.OPENFILENAME_I ofn);
예제 #8
0
        protected override IntPtr HookProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam)
        {
            IntPtr result = IntPtr.Zero;

            if (msg == 78)
            {
                this._hwndFileDialog = UnsafeNativeMethods.GetParent(new HandleRef(this, hwnd));
                NativeMethods.OFNOTIFY ofnotify = (NativeMethods.OFNOTIFY)UnsafeNativeMethods.PtrToStructure(lParam, typeof(NativeMethods.OFNOTIFY));
                switch (ofnotify.hdr_code)
                {
                case -606:
                    if (this._ignoreSecondFileOkNotification)
                    {
                        if (this._fileOkNotificationCount != 0)
                        {
                            this._ignoreSecondFileOkNotification = false;
                            UnsafeNativeMethods.CriticalSetWindowLong(new HandleRef(this, hwnd), 0, NativeMethods.InvalidIntPtr);
                            result = NativeMethods.InvalidIntPtr;
                            break;
                        }
                        this._fileOkNotificationCount = 1;
                    }
                    if (!this.DoFileOk(ofnotify.lpOFN))
                    {
                        UnsafeNativeMethods.CriticalSetWindowLong(new HandleRef(this, hwnd), 0, NativeMethods.InvalidIntPtr);
                        result = NativeMethods.InvalidIntPtr;
                    }
                    break;

                case -604:
                    this._ignoreSecondFileOkNotification = true;
                    this._fileOkNotificationCount        = 0;
                    break;

                case -602:
                {
                    NativeMethods.OPENFILENAME_I openfilename_I = (NativeMethods.OPENFILENAME_I)UnsafeNativeMethods.PtrToStructure(ofnotify.lpOFN, typeof(NativeMethods.OPENFILENAME_I));
                    int num = (int)UnsafeNativeMethods.UnsafeSendMessage(this._hwndFileDialog, (WindowMessage)1124, IntPtr.Zero, IntPtr.Zero);
                    if (num > openfilename_I.nMaxFile)
                    {
                        int num2 = num + 2048;
                        NativeMethods.CharBuffer charBuffer = NativeMethods.CharBuffer.CreateBuffer(num2);
                        IntPtr lpstrFile = charBuffer.AllocCoTaskMem();
                        Marshal.FreeCoTaskMem(openfilename_I.lpstrFile);
                        openfilename_I.lpstrFile = lpstrFile;
                        openfilename_I.nMaxFile  = num2;
                        this._charBuffer         = charBuffer;
                        Marshal.StructureToPtr(openfilename_I, ofnotify.lpOFN, true);
                        Marshal.StructureToPtr(ofnotify, lParam, true);
                    }
                    break;
                }

                case -601:
                    base.MoveToScreenCenter(new HandleRef(this, this._hwndFileDialog));
                    break;
                }
            }
            else
            {
                result = base.HookProc(hwnd, msg, wParam, lParam);
            }
            return(result);
        }