■90066 / inTopicNo.7) |
Re[4]: FolderBrowserDialogでネットワークのみ選択 |
□投稿者/ yu (5回)-(2019/02/04(Mon) 02:54:26)
|
2019/02/04(Mon) 02:57:08 編集(投稿者) 魔界の仮面弁士 様
すごい…なるほど。 設定された識別子以外で設定するのは、特にC#ではやはり難しいですね。
実際にWindows SDK のコードで確認するには開発ツールのダウンロードが必要なようですね。 今の開発環境だとすぐには確認できず残念です。
初心者ながらに色々と調べてみましたが、知識不足でせっかく教えていただいた内容を 全ては理解しきれておらず大変申し訳ないですが、非常に勉強になりました。
ご回答いただきまして本当にありがとうございます。
■No90057 (魔界の仮面弁士 さん) に返信 > 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
|
解決済み
|