DOBON.NET DOBON.NETプログラミング掲示板過去ログ

folderBrowserDialog1.RootFolderで任意フォルダは指定できますか?

環境/言語:[win7 visual studio 2008 c#]
分類:[.NET]

特定のフォルダ内にあるフォルダの指定しようと思っています。

folderBrowserDialogのRootFolderを設定すると、そのフォルダ配下のみが指定対象となります。

しかし、このRootFolderはEnvironment.SpecialFolderに限定されているようです。
任意のフォルダをRootFolderとして指定する方法は無いでしょうか。

目的としては、データが保存されているフォルダ以外にアクセスして欲しくないためです。
戻り値でチェックすることは可能ですが、
選択時から固定されていた方が便利だと思っています。

よろしくお願いします。
■No27833に返信(duke0045さんの記事)
> 任意のフォルダをRootFolderとして指定する方法は無いでしょうか。

できません。FolderBrowserDialog は、ルートフォルダとして
SHGetSpecialFolderLocation で得られる PIDL しか扱わないためです。

代替策としては、このような手法があります。面倒ですけれどね。

(案1) FolderBrowserDialog が内部で呼び出している SHBrowseForFolder APIを
 直接呼び出して、BROWSEINFO.pidlRoot に任意フォルダの PIDL を渡す。
http://support.microsoft.com/kb/306285/ja

※上記サンプルでは、SHGetSpecialFolderLocation から PIDL を得ていますが、
ここを SHSimpleIDListFromPath から ITEMIDLIST を得るようにするか、または
IShellFolder.ParseDisplayName メソッドで ITEMIDLIST を得るようにします。
http://msdn.microsoft.com/en-us/library/bb762254.aspx
http://support.microsoft.com/kb/132750/ja

(案2) COM の Shell オブジェクトの BrowseForFolder メソッドで代用する。
http://msdn.microsoft.com/en-us/library/bb774065.aspx
■No27839に返信(魔界の仮面弁士さんの記事)
> (案2) COM の Shell オブジェクトの BrowseForFolder メソッドで代用する。
> http://msdn.microsoft.com/en-us/library/bb774065.aspx

サンプル。
[Microsoft Shell Controls And Automation] を参照設定しておいてください。

呼び出し方は、
 string root = @"C:\";
 string s = FolderDialog.Show("タイトル", root);
 textBox1.Text = (s == null) ? "(キャンセル)" : s;
という感じです。



//-------------
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public static class FolderDialog
{
    public static string Show(string title)
    {
        return BrowseForFolder(title, 0x240, Type.Missing);
    }

    public static string Show(string title, Environment.SpecialFolder root)
    {
        return BrowseForFolder(title, 0x240, root);
    }

    public static string Show(string title, string root)
    {
        return BrowseForFolder(title, 0x240, root);
    }

    public static string Show(string title, Flags options)
    {
        return BrowseForFolder(title, (int)options, Type.Missing);
    }

    public static string Show(string title, Environment.SpecialFolder root, Flags options)
    {
        return BrowseForFolder(title, (int)options, (int)root);
    }

    public static string Show(string title, string root, Flags options)
    {
        return BrowseForFolder(title, (int)options, root);
    }

    private static string BrowseForFolder(string title, int options, object root)
    {
        string returnPath = null;
        IntPtr hwnd = IntPtr.Zero;
        if (Form.ActiveForm != null)
        {
            hwnd = Form.ActiveForm.Handle;
        }
        Shell32.Shell shell = new Shell32.ShellClass();
        Shell32.Folder folder = shell.BrowseForFolder(hwnd.ToInt32(), title, options, root);
        if (folder != null)
        {
            Shell32.FolderItems items = folder.Items();
            if (items != null)
            {
                Shell32.FolderItem item = null;
                item = items.Item(Type.Missing);
                if (item != null)
                {
                    returnPath = item.Path;
                    Marshal.ReleaseComObject(item);
                }
                Marshal.ReleaseComObject(items);
            }
            Marshal.ReleaseComObject(folder);
        }
        Marshal.ReleaseComObject(shell);
        return returnPath;
    }

    [Flags]
    public enum Flags
    {
        ReturnOnlyFSDirs = 0x1,
        DontGoBelowDomain = 0x2,
        StatusText = 0x4,
        RetrunFSAncestors = 0x8,
        EditBox = 0x10,
        Validate = 0x20,
        NewDialgStyle = 0x40,
        UseNewUI = 0x50,
        BrowseIncludUrls = 0x80,
        UAHint = 0x100,
        NoNewFolderButton = 0x200,
        NoTranslateTargets = 0x400,
        BrowseForComputer = 0x1000,
        BrowseForPrinter = 0x2000,
        BrowseIncludeFiles = 0x4000,
        Shareable = 0x8000,
    }
}
■No27840に返信(魔界の仮面弁士さんの記事)
> ■No27839に返信(魔界の仮面弁士さんの記事)
>>(案2) COM の Shell オブジェクトの BrowseForFolder メソッドで代用する。
>>http://msdn.microsoft.com/en-us/library/bb774065.aspx
>
> サンプル。
> [Microsoft Shell Controls And Automation] を参照設定しておいてください。
>
> 呼び出し方は、
>  string root = @"C:\";
>  string s = FolderDialog.Show("タイトル", root);
>  textBox1.Text = (s == null) ? "(キャンセル)" : s;
> という感じです。
>
>
>
> //-------------
> using System;
> using System.Windows.Forms;
> using System.Runtime.InteropServices;
>
> public static class FolderDialog
> {
> public static string Show(string title)
> {
> return BrowseForFolder(title, 0x240, Type.Missing);
> }
>
> public static string Show(string title, Environment.SpecialFolder root)
> {
> return BrowseForFolder(title, 0x240, root);
> }
>
> public static string Show(string title, string root)
> {
> return BrowseForFolder(title, 0x240, root);
> }
>
> public static string Show(string title, Flags options)
> {
> return BrowseForFolder(title, (int)options, Type.Missing);
> }
>
> public static string Show(string title, Environment.SpecialFolder root, Flags options)
> {
> return BrowseForFolder(title, (int)options, (int)root);
> }
>
> public static string Show(string title, string root, Flags options)
> {
> return BrowseForFolder(title, (int)options, root);
> }
>
> private static string BrowseForFolder(string title, int options, object root)
> {
> string returnPath = null;
> IntPtr hwnd = IntPtr.Zero;
> if (Form.ActiveForm != null)
> {
> hwnd = Form.ActiveForm.Handle;
> }
> Shell32.Shell shell = new Shell32.ShellClass();
> Shell32.Folder folder = shell.BrowseForFolder(hwnd.ToInt32(), title, options, root);
> if (folder != null)
> {
> Shell32.FolderItems items = folder.Items();
> if (items != null)
> {
> Shell32.FolderItem item = null;
> item = items.Item(Type.Missing);
> if (item != null)
> {
> returnPath = item.Path;
> Marshal.ReleaseComObject(item);
> }
> Marshal.ReleaseComObject(items);
> }
> Marshal.ReleaseComObject(folder);
> }
> Marshal.ReleaseComObject(shell);
> return returnPath;
> }
>
> [Flags]
> public enum Flags
> {
> ReturnOnlyFSDirs = 0x1,
> DontGoBelowDomain = 0x2,
> StatusText = 0x4,
> RetrunFSAncestors = 0x8,
> EditBox = 0x10,
> Validate = 0x20,
> NewDialgStyle = 0x40,
> UseNewUI = 0x50,
> BrowseIncludUrls = 0x80,
> UAHint = 0x100,
> NoNewFolderButton = 0x200,
> NoTranslateTargets = 0x400,
> BrowseForComputer = 0x1000,
> BrowseForPrinter = 0x2000,
> BrowseIncludeFiles = 0x4000,
> Shareable = 0x8000,
> }
> }

DOBON.NET | プログラミング道 | プログラミング掲示板