Esempio n. 1
0
        /// <summary>Shows the dialog box to let the user browse for and select a folder.</summary>
        /// <param name="parentWindowHandle">The HWND of the parent window.</param>
        /// <returns>The selected folder or <c>null</c> if no folder was selected by the user.</returns>
        protected override bool RunDialog(IntPtr parentWindowHandle)
        {
            // Setup BROWSEINFO.dwFlag value
            EnumFlagIndexer <BrowseInfoFlag> browseInfoFlag = BrowseInfoFlag.BIF_SHAREABLE;

            browseInfoFlag[BrowseInfoFlag.BIF_NEWDIALOGSTYLE]      = Application.OleRequired() == ApartmentState.STA;
            browseInfoFlag[BrowseInfoFlag.BIF_DONTGOBELOWDOMAIN]   = HideDomainFolders;
            browseInfoFlag[BrowseInfoFlag.BIF_BROWSEFILEJUNCTIONS] = ShowFileJunctions;
            browseInfoFlag[BrowseInfoFlag.BIF_RETURNONLYFSDIRS]    = LocalFileSystemOnly;
            browseInfoFlag[BrowseInfoFlag.BIF_NONEWFOLDERBUTTON]   = !ShowNewFolderButton;
            browseInfoFlag[BrowseInfoFlag.BIF_EDITBOX | BrowseInfoFlag.BIF_VALIDATE] = ShowFolderPathEditBox;
            switch (BrowseOption)
            {
            case FolderBrowserDialogOptions.Folders:
                break;

            case FolderBrowserDialogOptions.FoldersAndFiles:
                browseInfoFlag |= BrowseInfoFlag.BIF_BROWSEINCLUDEFILES;
                break;

            case FolderBrowserDialogOptions.Computers:
                browseInfoFlag |= BrowseInfoFlag.BIF_BROWSEFORCOMPUTER;
                RootFolder      = defaultComputersFolder;
                break;

            case FolderBrowserDialogOptions.Printers:
                browseInfoFlag |= BrowseInfoFlag.BIF_BROWSEFORPRINTER;
                RootFolder      = defaultPrintersFolder;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // Setup the BROWSEINFO structure
            var dn = new SafeCoTaskMemString(Kernel32.MAX_PATH);
            var bi = new BROWSEINFO(parentWindowHandle, rootPidl.DangerousGetHandle(), Description, browseInfoFlag, OnBrowseEvent, dn.DangerousGetHandle());

            // Show the dialog
            pidl = SHBrowseForFolder(ref bi);
            href = default(HandleRef);
            if (pidl.IsInvalid)
            {
                return(false);
            }
            if (browseInfoFlag[BrowseInfoFlag.BIF_BROWSEFORPRINTER] || browseInfoFlag[BrowseInfoFlag.BIF_BROWSEFORCOMPUTER])
            {
                SelectedItem = bi.DisplayName;
            }
            else
            {
                SelectedItem = GetNameForPidl(pidl);
            }
            return(true);
        }
Esempio n. 2
0
        /// <summary>Callback for Windows.</summary>
        /// <param name="hwnd">Window handle of the browse dialog box.</param>
        /// <param name="uMsg">Dialog box event that generated the statusMessage.</param>
        /// <param name="lParam">Value whose meaning depends on the event specified in uMsg.</param>
        /// <param name="lpData">Application-defined value that was specified in the lParam member of the BROWSEINFO structure used in the call to SHBrowseForFolder.</param>
        /// <returns>
        /// Returns 0 except in the case of BFFM_VALIDATEFAILED. For that flag, returns 0 to dismiss the dialog or nonzero to keep the dialog displayed.
        /// </returns>
        //[CLSCompliant(false)]
        private int OnBrowseEvent(IntPtr hwnd, BrowseForFolderMessages uMsg, IntPtr lParam, IntPtr lpData)
        {
            var messsage = uMsg;

            href = new HandleRef(this, hwnd);
            switch (messsage)
            {
            case BrowseForFolderMessages.BFFM_INITIALIZED:
                // Dialog is being initialized, so set the initial parameters
                if (!string.IsNullOrEmpty(Caption))
                {
                    SetWindowText(href, Caption);
                }

                if (!string.IsNullOrEmpty(SelectedItem))
                {
                    SendMessage(href, (uint)BrowseForFolderMessages.BFFM_SETSELECTIONW, (IntPtr)1, SelectedItem);
                }

                if (Expanded)
                {
                    SendMessage(href, (uint)BrowseForFolderMessages.BFFM_SETEXPANDED, (IntPtr)1, rootPidl.DangerousGetHandle());
                }

                if (!string.IsNullOrEmpty(OkText))
                {
                    SendMessage(href, (uint)BrowseForFolderMessages.BFFM_SETOKTEXT, (IntPtr)0, OkText);
                }

                Initialized?.Invoke(this, new FolderBrowserDialogInitializedEventArgs(hwnd));
                initialized = true;
                return(0);

            case BrowseForFolderMessages.BFFM_SELCHANGED:
                try
                {
                    if (!initialized || pidl?.DangerousGetHandle() == lParam)
                    {
                        return(0);
                    }
                    var tmpPidl = new PIDL(lParam, false, false);
                    var str     = GetNameForPidl(tmpPidl);
                    if (string.IsNullOrEmpty(str))
                    {
                        return(0);
                    }
                    SelectedItem = str;
                    pidl         = tmpPidl;
                }
                catch
                {
                    return(0);
                }

                SelectedItemChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SelectedItem)));
                return(0);

            case BrowseForFolderMessages.BFFM_VALIDATEFAILEDA:
            case BrowseForFolderMessages.BFFM_VALIDATEFAILEDW:
                if (InvalidFolderSelected != null)
                {
                    var folderName = messsage == BrowseForFolderMessages.BFFM_VALIDATEFAILEDA ? Marshal.PtrToStringAnsi(lParam) : Marshal.PtrToStringUni(lParam);
                    var e          = new InvalidFolderEventArgs(folderName, true);
                    InvalidFolderSelected?.Invoke(this, e);
                    return(e.DismissDialog ? 0 : 1);
                }
                return(0);

            default:
                return(0);
            }
        }