Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#如何允许使用folderBrowserDialog选择我的计算机_C#_Visual Studio 2008_Folderbrowserdialog - Fatal编程技术网

C#如何允许使用folderBrowserDialog选择我的计算机

C#如何允许使用folderBrowserDialog选择我的计算机,c#,visual-studio-2008,folderbrowserdialog,C#,Visual Studio 2008,Folderbrowserdialog,在我的应用程序中,我希望FolderBrowser对话框允许选择我的计算机。但在从对话框中选择“我的电脑”后,“确定”按钮将被禁用 是否有任何方法允许在浏览对话框中选择我的电脑?显示: 如果用户选择的文件夹 没有物理路径(例如,我的计算机), 对话框上的“确定”按钮将被禁用 你问: 有没有办法为我的电脑启用“确定”按钮 没有。有一种可能性: 使用该功能: [StructLayout(LayoutKind.Sequential)] public struct BROWSEINFO

在我的应用程序中,我希望FolderBrowser对话框允许选择
我的计算机
。但在从对话框中选择“我的电脑”后,“确定”按钮将被禁用

是否有任何方法允许在
浏览对话框
中选择
我的电脑

显示:

如果用户选择的文件夹 没有物理路径(例如,我的计算机), 对话框上的“确定”按钮将被禁用

你问:

有没有办法为我的电脑启用“确定”按钮

没有。有一种可能性: 使用该功能:

   [StructLayout(LayoutKind.Sequential)]
    public struct BROWSEINFO
    {
        public IntPtr hwndOwner;
        public IntPtr pidlRoot;
        //public IntPtr pszDisplayName;
        public string pszDisplayName;
        public string lpszTitle;
        public uint ulFlags;
        public BrowseCallbackProc lpfn;
        public IntPtr lParam;
        public int iImage;
     }
[DllImport("shell32.dll")]
public static extern IntPtr SHBrowseForFolder(ref BROWSEINFO lpbi);

 [DllImport("shell32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SHGetPathFromIDListW(IntPtr pidl, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszPath);

   [DllImport("shell32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool SHGetPathFromIDListW(IntPtr pidl, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder pszPath);
回拨可设置为:

 private int _callback(IntPtr hDlg, int msg, IntPtr lParam, IntPtr lpData)
    {
        switch (msg)
        {

            case 2://BFFM_SELCHANGED:
                StringBuilder sb1 = new StringBuilder();
                Win32.SHGetPathFromIDListW((IntPtr)lParam, sb);

                Win32.EnableWindow(Win32.GetDlgItem(hDlg, CtlIds.IDOK), true);
                break;

        }

        return 0;
    }
致电:

 BROWSEINFO bi = new Win32.BROWSEINFO();
    bi.lpfn = new Win32.BrowseCallbackProc(callback);


    string selected = SHBrowseForFolder(ref bi);
“确定”按钮将可单击。 唯一的问题,我还没有发现,是如何确保我的电脑被选中

一些来源来自:

我的电脑(或较新Windows版本中的这台电脑)是一个特殊文件夹(不是文件系统文件夹),标准FolderBrowserDialog类不支持它

下面是一个替换示例
FolderBrowser
类,允许用户选择任何文件夹。这是一个在Windows窗体应用程序中使用它的示例:

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
替换类。有趣的是这一行:

dialog.SetOptions(FOS.FOS_PICKFOLDERS | FOS.FOS_ALLNONSTORAGEITEMS);
这将指示代码仅拾取文件夹并允许非文件系统项

对于普通文件夹,返回的
SelectedPath
属性将包含文件夹路径。对于没有存储的特殊文件夹,它将为空。 但是shell为我们提供了一个规范的名字对象,其中包含普通文件夹的文件夹路径,以及将在
selecteddesktopabsolutionarsing
属性中定义的其他文件夹的特殊值。 对于我的计算机,该值将始终为“
:{20D04FE0-3AEA-1069-A2D8-08002B30309D}

这里正式定义了这种特殊语法:


我的电脑
不是文件夹,我的电脑不是文件夹。我不明白你选择它的原因。您不能在那里保存任何内容。@Android在我的应用程序中,我想允许用户选择我的计算机,应用程序会相应地执行业务逻辑。@SLaks我没有说过我的计算机是一个文件夹。是吗?
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)
    {
        var 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 IShellItem result);
        SelectedPath = GetDisplayName(result, SIGDN.SIGDN_FILESYSPATH);
        SelectedNormalDisplay = GetDisplayName(result, SIGDN.SIGDN_NORMALDISPLAY);
        SelectedDesktopAbsoluteParsing = GetDisplayName(result, SIGDN.SIGDN_DESKTOPABSOLUTEPARSING);
        SelectedUrl = GetDisplayName(result, SIGDN.SIGDN_URL);
        return DialogResult.OK;
    }

    private static string GetDisplayName(IShellItem item, SIGDN sigdnName)
    {
        item.GetDisplayName(sigdnName, out var ptr);
        var name = Marshal.PtrToStringUni(ptr);
        Marshal.FreeCoTaskMem(ptr);
        return name;
    }

    private void SelectInitialPath(IFileOpenDialog dialog, string path)
    {
        uint atts = 0;
        IntPtr idl = IntPtr.Zero;
        if (SHILCreateFromPath(path, out idl, ref atts) == 0)
        {
            if (SHCreateShellItem(IntPtr.Zero, IntPtr.Zero, idl, out IShellItem 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(out IntPtr 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, out IntPtr 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
    }
}