■90057 |
Re[3]: FolderBrowserDialogでネットワークのみ選択 |
□投稿者/ 魔界の仮面弁士 -(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 |
|