本文介绍了C#如何让我的FolderBrowserDialog与电脑的选择的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的申请,我要的FolderBrowserDialog允许我的电脑的选择。但OK按钮被选择后禁用我的电脑从对话框中。

In my application, I want the folderBrowserDialog to allow selection of My Computer. But the OK button gets disabled after selecting My Computer from the dialog box.

有没有什么办法让我的电脑中选择浏览对话框

Is there any way to allow the selection of My Computer in Browse Dialog?

推荐答案

我的电脑(或者这台电脑在最近的Windows版本)是一种特殊的文件夹(不是文件系统文件夹),以及标准的FolderBrowserDialog类不支持它。

My Computer (or This PC in more recent Windows versions) is a special folder (not a file system folder), and the standard FolderBrowserDialog class does not support it.

下面是替代样本 FolderBrowser 类,允许用户选择的任何文件夹。这是使用它的Windows窗体应用程序的例子:

Here is a replacement sample FolderBrowser class that allows the user to select any folder. This is an example that uses it in a Windows form app:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        // other special GUIDs are defined in Windows SDK's ShlGuid.h
        Guid CLSID_MyComputer = new Guid("20D04FE0-3AEA-1069-A2D8-08002B30309D");

        FolderBrowser dlg = new FolderBrowser();
        dlg.Title = "Choose any folder you want";

        // optionally uncomment the following line to start from a folder
        //dlg.SelectedPath = @"c:\temp";

        // optionally uncomment the following line to start from My Computer/This PC
        //dlg.SelectedDesktopAbsoluteParsing = "::" + CLSID_MyComputer.ToString("B");

        if (dlg.ShowDialog(null) == DialogResult.OK)
        {
            MessageBox.Show(dlg.SelectedDesktopAbsoluteParsing + Environment.NewLine +
                dlg.SelectedNormalDisplay + Environment.NewLine +
                dlg.SelectedPath + Environment.NewLine +
                dlg.SelectedUrl);

            if (dlg.SelectedDesktopAbsoluteParsing == "::" + CLSID_MyComputer.ToString("B").ToUpperInvariant())
            {
                MessageBox.Show("My Computer was selected!");
            }
        }
    }
}

和在这个答案的底部,你会发现 FolderBrowser 替换类。有趣的是这一行:

And at the bottom of this answer you'll find the FolderBrowser replacement class. The interesting part is this line:

dialog.SetOptions(FOS.FOS_PICKFOLDERS | FOS.FOS_ALLNONSTORAGEITEMS);



这将指示代码只挑选文件夹,并允许非文件系统的项目。

which will instruct the code to pick only folders and allow non file system items.

有关普通文件夹,返回 SelectedPath 属性将包含的文件夹路径。对于没有存储特殊文件夹,这将是空的。
,而外壳为我们提供了一个包含普通文件夹和将在 SelectedDesktopAbsoluteParsing 属性来定义其他文件夹中一个特殊值的文件夹路径规范绰号。
在我的电脑的情况下,该值将始终以 :: {20D04FE0-3AEA-1069-A2D8-08002B30309D}

For normal folders, the returned SelectedPath property will contain the folder path. For special folders without a storage, it will be empty.But the shell provides us a canonical moniker that contains the folder path for normal folders and a special values for other folders that will be defined in the SelectedDesktopAbsoluteParsing property.In the case of My Computer, the value will always be "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}".

这特殊的语法定义有所这里正式:的。

This special syntax is somewhat defined officially here: Specifying a Namespace Extension's Location.

public class FolderBrowser
{
    public string SelectedPath { get; set; }
    public string SelectedDesktopAbsoluteParsing { get; set; }
    public string Title { get; set; }
    public string SelectedNormalDisplay { get; private set; }
    public string SelectedUrl { get; private set; }

    public DialogResult ShowDialog(IWin32Window owner)
    {
        IShellItem result = null;
        IFileOpenDialog dialog = (IFileOpenDialog)new FileOpenDialog();

        if (!string.IsNullOrEmpty(SelectedPath))
        {
            SelectInitialPath(dialog, SelectedPath);
        }
        else if (!string.IsNullOrEmpty(SelectedDesktopAbsoluteParsing))
        {
            SelectInitialPath(dialog, SelectedDesktopAbsoluteParsing);
        }

        if (!string.IsNullOrWhiteSpace(Title))
        {
            dialog.SetTitle(Title);
        }

        dialog.SetOptions(FOS.FOS_PICKFOLDERS | FOS.FOS_ALLNONSTORAGEITEMS);
        uint hr = dialog.Show(owner != null ? owner.Handle : IntPtr.Zero);
        if (hr == ERROR_CANCELLED)
            return DialogResult.Cancel;

        if (hr != 0)
            return DialogResult.Abort;

        dialog.GetResult(out result);

        string path;
        result.GetDisplayName(SIGDN.SIGDN_FILESYSPATH, out path);
        SelectedPath = path;

        result.GetDisplayName(SIGDN.SIGDN_NORMALDISPLAY, out path);
        SelectedNormalDisplay = path;

        result.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEPARSING, out path);
        SelectedDesktopAbsoluteParsing = path;

        result.GetDisplayName(SIGDN.SIGDN_URL, out path);
        SelectedUrl = path;

        return DialogResult.OK;
    }

    private void SelectInitialPath(IFileOpenDialog dialog, string path)
    {
        uint atts = 0;
        IntPtr idl = IntPtr.Zero;
        if (SHILCreateFromPath(path, out idl, ref atts) == 0)
        {
            IShellItem initial = null;
            if (SHCreateShellItem(IntPtr.Zero, IntPtr.Zero, idl, out initial) == 0)
            {
                dialog.SetFolder(initial);
            }
            Marshal.FreeCoTaskMem(idl);
        }
    }

    [DllImport("shell32.dll", CharSet = CharSet.Unicode)]
    private static extern int SHILCreateFromPath(string pszPath, out IntPtr ppIdl, ref uint rgflnOut);

    [DllImport("shell32.dll")]
    private static extern int SHCreateShellItem(IntPtr pidlParent, IntPtr psfParent, IntPtr pidl, out IShellItem ppsi);

    private const uint ERROR_CANCELLED = 0x800704C7;

    [ComImport]
    [Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")]
    private class FileOpenDialog
    {
    }

    [Guid("42f85136-db7e-439c-85f1-e4075d135fc8")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IFileOpenDialog
    {
        [PreserveSig]
        uint Show(IntPtr parent); // IModalWindow
        void SetFileTypes();  // not fully defined
        void SetFileTypeIndex(uint iFileType);
        void GetFileTypeIndex(out uint piFileType);
        void Advise(); // not fully defined
        void Unadvise();
        void SetOptions(FOS fos);
        void GetOptions(out FOS pfos);
        void SetDefaultFolder(IShellItem psi);
        void SetFolder(IShellItem psi);
        void GetFolder(out IShellItem ppsi);
        void GetCurrentSelection(out IShellItem ppsi);
        void SetFileName([MarshalAs(UnmanagedType.LPWStr)] string pszName);
        void GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
        void SetTitle([MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
        void SetOkButtonLabel([MarshalAs(UnmanagedType.LPWStr)] string pszText);
        void SetFileNameLabel([MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
        void GetResult(out IShellItem ppsi);
        void AddPlace(IShellItem psi, int alignment);
        void SetDefaultExtension([MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
        void Close(int hr);
        void SetClientGuid();  // not fully defined
        void ClearClientData();
        void SetFilter([MarshalAs(UnmanagedType.Interface)] IntPtr pFilter);
        void GetResults([MarshalAs(UnmanagedType.Interface)] out IntPtr ppenum); // not fully defined
        void GetSelectedItems([MarshalAs(UnmanagedType.Interface)] out IntPtr ppsai); // not fully defined
    }

    [Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE")]
    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    private interface IShellItem
    {
        void BindToHandler(); // not fully defined
        void GetParent(); // not fully defined
        [PreserveSig]
        int GetDisplayName(SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
        void GetAttributes();  // not fully defined
        void Compare();  // not fully defined
    }

    // https://msdn.microsoft.com/en-us/library/windows/desktop/bb762544.aspx
    private enum SIGDN : uint
    {
        SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,
        SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,
        SIGDN_FILESYSPATH = 0x80058000,
        SIGDN_NORMALDISPLAY = 0,
        SIGDN_PARENTRELATIVE = 0x80080001,
        SIGDN_PARENTRELATIVEEDITING = 0x80031001,
        SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001,
        SIGDN_PARENTRELATIVEPARSING = 0x80018001,
        SIGDN_URL = 0x80068000
    }

    // https://msdn.microsoft.com/en-us/library/windows/desktop/dn457282.aspx
    [Flags]
    private enum FOS
    {
        FOS_ALLNONSTORAGEITEMS = 0x80,
        FOS_ALLOWMULTISELECT = 0x200,
        FOS_CREATEPROMPT = 0x2000,
        FOS_DEFAULTNOMINIMODE = 0x20000000,
        FOS_DONTADDTORECENT = 0x2000000,
        FOS_FILEMUSTEXIST = 0x1000,
        FOS_FORCEFILESYSTEM = 0x40,
        FOS_FORCESHOWHIDDEN = 0x10000000,
        FOS_HIDEMRUPLACES = 0x20000,
        FOS_HIDEPINNEDPLACES = 0x40000,
        FOS_NOCHANGEDIR = 8,
        FOS_NODEREFERENCELINKS = 0x100000,
        FOS_NOREADONLYRETURN = 0x8000,
        FOS_NOTESTFILECREATE = 0x10000,
        FOS_NOVALIDATE = 0x100,
        FOS_OVERWRITEPROMPT = 2,
        FOS_PATHMUSTEXIST = 0x800,
        FOS_PICKFOLDERS = 0x20,
        FOS_SHAREAWARE = 0x4000,
        FOS_STRICTFILETYPES = 4
    }
}

这篇关于C#如何让我的FolderBrowserDialog与电脑的选择的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-22 19:21