C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト


■90057 / )  Re[3]: FolderBrowserDialogでネットワークのみ選択
□投稿者/ 魔界の仮面弁士 (2035回)-(2019/02/01(Fri) 16:05:04)
2019/02/02(Sat) 10:15:12 編集(投稿者)

# 解決済みマークはつけたままにしておきます。

No90047 (yu さん) に返信
> 無理矢理な方法、と仰いましたが、なるほど!と思わされる方法でした。

No90044 はリフレクションで、Backing-Field 変数に強制代入していますが、
これは要するに、下記に相当する処理であることを意味します。

 const int CSIDL_NETWORK = 0x0012
 folderBrowserDialog1.RootFolder = (System.Environment.SpecialFolder)CSIDL_NETWORK;


しかし、RootFolder プロパティの setter は下記の実装になっており、そのままだと例外で失敗するため、
それを回避するため、rootFolder メンバーへの直接代入で回避していたというわけで。

 if (!Enum.IsDefined(typeof(System.Environment.SpecialFolder), value))
 {
  throw new InvalidEnumArgumentException("value", (int)value, typeof(System.Environment.SpecialFolder));
 }
 rootFolder = value;


> よろしければ、"0x12"がネットワークの番号だとどのように調べたのか教えていただけませんか?

0x12 は、"ネットワーク" フォルダーを意味する識別子です。
Windows SDK 上では CSIDL_NETWORK 定数として定義されています。(see: ShFolder.h , KnownFolders.h)


=======================
同じ処理を COM 版で書くとこんな感じ。

Shell32.dll を参照設定した上で、
ShellSpecialFolderConstants 列挙型の ssfNETWORK を利用できます。


const int BIF_NEWDIALOGSTYLE = 0x40;
const int BIF_NONEWFOLDERBUTTON = 0x200;

int Hwnd = (int)(long)Handle;
string Title = "フォルダを選択して下さい";
int Options = BIF_NEWDIALOGSTYLE | BIF_NONEWFOLDERBUTTON;
object RootFolder = Shell32.ShellSpecialFolderConstants.ssfNETWORK;

Shell32.Shell sh = new Shell32.Shell();
Shell32.Folder fo = sh.BrowseForFolder(Hwnd, Title, Options, RootFolder);

string selectedFolder = null;
if ( fo != null)
{
  Shell32.FolderItems fis = fo.Items();
  Shell32.FolderItem fi = fis.Item(Type.Missing);
  selectedFolder = fi.Path;
  Marshal.ReleaseComObject(fi);
  Marshal.ReleaseComObject(fis);
  Marshal.ReleaseComObject(fis);
  Marshal.ReleaseComObject(fo);
}
Marshal.ReleaseComObject(sh);

return selectedFolder;

=======================
参照設定したくなければ、レイトバインドで。

dynamic sh = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic fo = sh.BrowseForFolder((int)(long) Handle, "フォルダを選択して下さい", 0x240, 0x12);
string selectedFolder = null;
if ( fo != null)
{
  dynamic fis = fo.Items();
  dynamic fi = fis.Item();
  selectedFolder = fi.Path;
  Marshal.ReleaseComObject(fi);
  Marshal.ReleaseComObject(fo);
}
Marshal.ReleaseComObject(sh);
return selectedFolder;


=======================
上記 COM の BrowseForFolder メソッドや
.NET の FolderBrowserDialog クラスというものは、
SHBrowseForFolder という API をカプセル化したものです。
https://docs.microsoft.com/en-us/windows/desktop/api/shlobj_core/nf-shlobj_core-shbrowseforfolderw
https://docs.microsoft.com/en-us/windows/desktop/api/shlobj_core/nf-shlobj_core-shbrowseforfoldera
https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/FolderBrowserDialog.cs,94edc2b722c18d1f
解決済み
返信 編集キー/


管理者用

- Child Tree -