FolderBrowserDialog to PickFolderDialog

    • C#
    • .NET (FX) 4.5–4.8

    Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von MasterQ.

      FolderBrowserDialog to PickFolderDialog

      @-Franky- hat hier: Eigener FolderBrowserDialog - Root Folder ermitteln
      einen eigenen FolderBrowserDialog in VB.NET vorgestellt.
      Dieser Dialog sieht aus wie ein "normaler" OpenFileDialog und verhält sich auch so, bis auf den Umstand, dass keine Dateien angezeigt werden.
      Ich habe den mal her genommen und nach C# konvertiert und ihn im Aufruf etwas dem FolderBrowserDialog angepasst, so dass ein FolderBrowserDialog ganz easy durch den PickFolderDialog ersetzt werden kann:
      Version 1
      PickFolderDialog

      C#-Quellcode

      1. using System;
      2. using System.Runtime.InteropServices;
      3. using System.Windows.Forms;
      4. namespace TestPickFolderDialog
      5. {
      6. /// <summary>
      7. /// FolderB
      8. /// </summary>
      9. public sealed class PickFolderDialog
      10. : IDisposable
      11. {
      12. #region Const
      13. // siehe Headerfile Winerror.h
      14. private const int S_OK = 0;
      15. // siehe Headerfile shobjidl_core.h
      16. private const string IID_IModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802";
      17. private const string IID_IFileDialog = "42f85136-db7e-439c-85f1-e4075d135fc8";
      18. private const string IID_IShellItem = "43826d1e-e718-42ee-bc55-a1e261c37bfe";
      19. private const string CLSID_FileOpenDialog = "dc1c5a9c-e88a-4dde-a5a1-60f82a20aef7";
      20. #endregion Const
      21. #region Enums
      22. // siehe Headerfile shobjidl_core.h
      23. private enum FileOpenDialogOptions : int
      24. {
      25. OverwritePrompt = 0x2,
      26. FOS_STRICTFILETYPES = 0x4,
      27. FOS_NOCHANGEDIR = 0x8,
      28. FOS_PICKFOLDERS = 0x20,
      29. FOS_FORCEFILESYSTEM = 0x40,
      30. FOS_ALLNONSTORAGEITEMS = 0x80,
      31. FOS_NOVALIDATE = 0x100,
      32. FOS_ALLOWMULTISELECT = 0x200,
      33. FOS_PATHMUSTEXIST = 0x800,
      34. FOS_FILEMUSTEXIST = 0x1000,
      35. FOS_CREATEPROMPT = 0x2000,
      36. FOS_SHAREAWARE = 0x4000,
      37. FOS_NOREADONLYRETURN = 0x8000,
      38. FOS_NOTESTFILECREATE = 0x10000,
      39. FOS_HIDEMRUPLACES = 0x20000,
      40. FOS_HIDEPINNEDPLACES = 0x40000,
      41. FOS_NODEREFERENCELINKS = 0x100000,
      42. FOS_OKBUTTONNEEDSINTERACTION = 0x200000,
      43. FOS_DONTADDTORECENT = 0x2000000,
      44. FOS_FORCESHOWHIDDEN = 0x10000000,
      45. FOS_DEFAULTNOMINIMODE = 0x20000000,
      46. FOS_FORCEPREVIEWPANEON = 0x40000000,
      47. FOS_SUPPORTSTREAMABLEITEMS = int.MinValue + 0x00000000
      48. }
      49. // siehe Headerfile shobjidl_core.h
      50. public enum SIGDN : int
      51. {
      52. SIGDN_NORMALDISPLAYField = 0x0,
      53. SIGDN_PARENTRELATIVEPARSINGField = int.MinValue + 0x00018001,
      54. SIGDN_DESKTOPABSOLUTEPARSINGField = int.MinValue + 0x00028000,
      55. SIGDN_PARENTRELATIVEEDITINGField = int.MinValue + 0x00031001,
      56. SIGDN_DESKTOPABSOLUTEEDITINGField = int.MinValue + 0x0004C000,
      57. SIGDN_FILESYSPATHField = int.MinValue + 0x00058000,
      58. SIGDN_URLField = int.MinValue + 0x00068000,
      59. SIGDN_PARENTRELATIVEFORADDRESSBARField = int.MinValue + 0x0007C001,
      60. SIGDN_PARENTRELATIVEField = int.MinValue + 0x00080001,
      61. SIGDN_PARENTRELATIVEFORUIField = int.MinValue + 0x00094001
      62. }
      63. #endregion Enums
      64. #region Member
      65. private bool m_DisposedValue;
      66. private IFileDialog m_FileOpenDialog;
      67. #endregion Member
      68. #region API
      69. // siehe https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-shcreateitemfromparsingname
      70. // oder Headerfile shobjidl_core.h
      71. [DllImport("Shell32.dll", EntryPoint = "SHCreateItemFromParsingName")]
      72. [PreserveSig]
      73. private static extern int SHCreateItemFromParsingName([In][MarshalAs(UnmanagedType.LPWStr)] string pszPath, [In] IntPtr pbc, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr pUnk);
      74. #endregion
      75. #region Properties
      76. /// <summary>
      77. /// Gets or sets the path selected by the user.
      78. /// Wird nichts angegeben: "Dieser PC"
      79. /// </summary>
      80. public string SelectedPath
      81. {
      82. get { return this.GetResult(PickFolderDialog.SIGDN.SIGDN_FILESYSPATHField); }
      83. set { this.SetFolder(value); }
      84. }
      85. #endregion Properties
      86. #region Konstruktor
      87. public PickFolderDialog()
      88. {
      89. FileOpenDialogOptions options;
      90. this.m_FileOpenDialog = (IFileDialog)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(CLSID_FileOpenDialog)));
      91. if (this.m_FileOpenDialog != null)
      92. {
      93. if (this.m_FileOpenDialog.GetOptions(out options) == S_OK)
      94. {
      95. options |= FileOpenDialogOptions.FOS_PICKFOLDERS;
      96. this.m_FileOpenDialog.SetOptions(options);
      97. }
      98. }
      99. }
      100. #endregion Konstruktor
      101. #region Public Functions
      102. public bool SetFolder(string folder = null)
      103. {
      104. // Wird bei Dialog.SetFolder nichts angegeben = Dieser PC
      105. // Ansonsten z.B. "C:" oder "C:\" = Laufwerk C:
      106. // "C:\Users" oder "C:\Users\" = Ordner Users auf Laufwerk C:
      107. // "::{645FF040-5081-101B-9F08-00AA002F954E}" = Papierkorb
      108. // "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}" = Netzwerk
      109. // "::{031E4825-7B94-4DC3-B131-E946B44C8DD5}" = Bibliotheken
      110. // usw.
      111. bool retval = false;
      112. if (this.m_FileOpenDialog != null)
      113. {
      114. IntPtr item;
      115. if (folder is null)
      116. {
      117. // C-String-Ende-Kennung
      118. folder = "\0";
      119. }
      120. if (SHCreateItemFromParsingName(folder, IntPtr.Zero, new Guid(IID_IShellItem), out item) == S_OK)
      121. {
      122. if (this.m_FileOpenDialog.SetFolder(item) == S_OK)
      123. {
      124. retval = true;
      125. }
      126. Marshal.Release(item);
      127. }
      128. }
      129. return retval;
      130. }
      131. public DialogResult ShowDialog(IntPtr hwndOwner = default)
      132. {
      133. if (this.m_FileOpenDialog != null)
      134. {
      135. if (this.m_FileOpenDialog.Show(hwndOwner) == S_OK)
      136. {
      137. return DialogResult.OK;
      138. }
      139. }
      140. return DialogResult.Cancel;
      141. }
      142. public string GetResult(SIGDN eSIGDN = SIGDN.SIGDN_FILESYSPATHField)
      143. {
      144. string strRet = string.Empty;
      145. if (this.m_FileOpenDialog != null)
      146. {
      147. if (this.m_FileOpenDialog.GetResult(out IShellItem ShellItem) == S_OK)
      148. {
      149. if (ShellItem.GetDisplayName(eSIGDN, out IntPtr pszName) == S_OK)
      150. {
      151. strRet = Marshal.PtrToStringUni(pszName);
      152. Marshal.FreeCoTaskMem(pszName);
      153. }
      154. Marshal.ReleaseComObject(ShellItem);
      155. }
      156. }
      157. return strRet;
      158. }
      159. #endregion Public Functions
      160. #region Interface IModalWindow
      161. // siehe Headerfile shobjidl_core.h
      162. [ComImport]
      163. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      164. [Guid(IID_IModalWindow)]
      165. private interface IModalWindow
      166. {
      167. // virtual /* [local] */ HRESULT STDMETHODCALLTYPE Show(
      168. // /* [annotation][unique][in] */
      169. // _In_opt_ HWND hwndOwner) = 0;
      170. [PreserveSig]
      171. int Show([In] IntPtr hwndOwner);
      172. }
      173. #endregion
      174. #region Interface IFileDialog
      175. // siehe Headerfile shobjidl_core.h
      176. [ComImport]
      177. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      178. [Guid(IID_IFileDialog)]
      179. private interface IFileDialog : IModalWindow
      180. {
      181. [PreserveSig]
      182. new int Show([In] IntPtr hwndOwner);
      183. // virtual HRESULT STDMETHODCALLTYPE SetFileTypes(
      184. // /* [in] */ UINT cFileTypes,
      185. // /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec) = 0;
      186. [PreserveSig]
      187. int SetFileTypes();
      188. // virtual HRESULT STDMETHODCALLTYPE SetFileTypeIndex(
      189. // /* [in] */ UINT iFileType) = 0;
      190. [PreserveSig]
      191. int SetFileTypeIndex();
      192. // virtual HRESULT STDMETHODCALLTYPE GetFileTypeIndex(
      193. // /* [out] */ __RPC__out UINT *piFileType) = 0;
      194. [PreserveSig]
      195. int GetFileTypeIndex();
      196. // virtual HRESULT STDMETHODCALLTYPE Advise(
      197. // /* [in] */ __RPC__in_opt IFileDialogEvents *pfde,
      198. // /* [out] */ __RPC__out DWORD *pdwCookie) = 0;
      199. [PreserveSig]
      200. int Advise();
      201. // virtual HRESULT STDMETHODCALLTYPE Unadvise(
      202. // /* [in] */ DWORD dwCookie) = 0;
      203. [PreserveSig]
      204. int Unadvise();
      205. // virtual HRESULT STDMETHODCALLTYPE SetOptions(
      206. // /* [in] */ FILEOPENDIALOGOPTIONS fos) = 0;
      207. [PreserveSig]
      208. int SetOptions([In] FileOpenDialogOptions fos);
      209. // virtual HRESULT STDMETHODCALLTYPE GetOptions(
      210. // /* [out] */ __RPC__out FILEOPENDIALOGOPTIONS *pfos) = 0;
      211. [PreserveSig]
      212. int GetOptions(out FileOpenDialogOptions pfos);
      213. // virtual HRESULT STDMETHODCALLTYPE SetDefaultFolder(
      214. // /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      215. [PreserveSig]
      216. int SetDefaultFolder();
      217. // virtual HRESULT STDMETHODCALLTYPE SetFolder(
      218. // /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      219. [PreserveSig]
      220. int SetFolder([In] IntPtr psi);
      221. // virtual HRESULT STDMETHODCALLTYPE GetFolder(
      222. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      223. [PreserveSig]
      224. int GetFolder();
      225. // virtual HRESULT STDMETHODCALLTYPE GetCurrentSelection(
      226. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      227. [PreserveSig]
      228. int GetCurrentSelection();
      229. // virtual HRESULT STDMETHODCALLTYPE SetFileName(
      230. // /* [string][in] */ __RPC__in_string LPCWSTR pszName) = 0;
      231. [PreserveSig]
      232. int SetFileName();
      233. // virtual HRESULT STDMETHODCALLTYPE GetFileName(
      234. // /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName) = 0;
      235. [PreserveSig]
      236. int GetFileName();
      237. // virtual HRESULT STDMETHODCALLTYPE SetTitle(
      238. // /* [string][in] */ __RPC__in_string LPCWSTR pszTitle) = 0;
      239. [PreserveSig]
      240. int SetTitle();
      241. // virtual HRESULT STDMETHODCALLTYPE SetOkButtonLabel(
      242. // /* [string][in] */ __RPC__in_string LPCWSTR pszText) = 0;
      243. [PreserveSig]
      244. int SetOkButtonLabel();
      245. // virtual HRESULT STDMETHODCALLTYPE SetFileNameLabel(
      246. // /* [string][in] */ __RPC__in_string LPCWSTR pszLabel) = 0;
      247. [PreserveSig]
      248. int SetFileNameLabel();
      249. // virtual HRESULT STDMETHODCALLTYPE GetResult(
      250. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      251. [PreserveSig]
      252. int GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
      253. // virtual HRESULT STDMETHODCALLTYPE AddPlace(
      254. // /* [in] */ __RPC__in_opt IShellItem *psi,
      255. // /* [in] */ FDAP fdap) = 0;
      256. [PreserveSig]
      257. int AddPlace();
      258. // virtual HRESULT STDMETHODCALLTYPE SetDefaultExtension(
      259. // /* [string][in] */ __RPC__in_string LPCWSTR pszDefaultExtension) = 0;
      260. [PreserveSig]
      261. int SetDefaultExtension();
      262. // virtual HRESULT STDMETHODCALLTYPE Close(
      263. // /* [in] */ HRESULT hr) = 0;
      264. [PreserveSig]
      265. int Close();
      266. // virtual HRESULT STDMETHODCALLTYPE SetClientGuid(
      267. // /* [in] */ __RPC__in REFGUID guid) = 0;
      268. [PreserveSig]
      269. int SetClientGuid();
      270. // virtual HRESULT STDMETHODCALLTYPE ClearClientData( void) = 0;
      271. [PreserveSig]
      272. int ClearClientData();
      273. // virtual HRESULT STDMETHODCALLTYPE SetFilter(
      274. // /* [in] */ __RPC__in_opt IShellItemFilter *pFilter) = 0;
      275. [PreserveSig]
      276. int SetFilter();
      277. }
      278. #endregion
      279. #region Interface IShellItem
      280. // siehe Headerfile shobjidl_core.h
      281. [ComImport]
      282. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      283. [Guid(IID_IShellItem)]
      284. private interface IShellItem
      285. {
      286. // virtual HRESULT STDMETHODCALLTYPE BindToHandler(
      287. // /* [unique][in] */ __RPC__in_opt IBindCtx *pbc,
      288. // /* [in] */ __RPC__in REFGUID bhid,
      289. // /* [in] */ __RPC__in REFIID riid,
      290. // /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
      291. [PreserveSig]
      292. int BindToHandler();
      293. // virtual HRESULT STDMETHODCALLTYPE GetParent(
      294. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      295. [PreserveSig]
      296. int GetParent();
      297. // virtual HRESULT STDMETHODCALLTYPE GetDisplayName(
      298. // /* [in] */ SIGDN sigdnName,
      299. // /* [annotation][string][out] */
      300. // _Outptr_result_nullonfailure_ LPWSTR *ppszName) = 0;
      301. [PreserveSig]
      302. int GetDisplayName([In] SIGDN sigdnName, out IntPtr ppszName);
      303. // virtual HRESULT STDMETHODCALLTYPE GetAttributes(
      304. // /* [in] */ SFGAOF sfgaoMask,
      305. // /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0;
      306. [PreserveSig]
      307. int GetAttributes();
      308. // virtual HRESULT STDMETHODCALLTYPE Compare(
      309. // /* [in] */ __RPC__in_opt IShellItem *psi,
      310. // /* [in] */ SICHINTF hint,
      311. // /* [out] */ __RPC__out int *piOrder) = 0;
      312. [PreserveSig]
      313. int Compare();
      314. }
      315. #endregion
      316. #region Dispose
      317. public void Dispose()
      318. {
      319. if (!this.m_DisposedValue)
      320. {
      321. if (this.m_FileOpenDialog != null)
      322. {
      323. if (Marshal.ReleaseComObject(this.m_FileOpenDialog) == 0)
      324. {
      325. this.m_FileOpenDialog = null;
      326. }
      327. }
      328. this.m_DisposedValue = true;
      329. }
      330. GC.SuppressFinalize(this);
      331. }
      332. #endregion Dispose
      333. }
      334. }
      Aufruf

      C#-Quellcode

      1. using System;
      2. using System.Windows.Forms;
      3. namespace TestPickFolderDialog
      4. {
      5. public partial class Form1 : Form
      6. {
      7. public Form1()
      8. {
      9. this.InitializeComponent();
      10. }
      11. private void Button1_Click(object sender, EventArgs e)
      12. {
      13. using (PickFolderDialog dlg = new PickFolderDialog())
      14. {
      15. dlg.SelectedPath = @"C:\Users\";
      16. if (dlg.ShowDialog() == DialogResult.OK)
      17. {
      18. this.label1.Text = dlg.SelectedPath;
      19. }
      20. }
      21. }
      22. }
      23. }
      Viel Vergnügen.
      =====
      Version 1.1:
      - Öffnet als modaler Dialog
      - von Component abgeleitet, lässt sich vom Designer aus auf die GUI ziehen
      - merkt sich den zuletzt ausgewählten Pfad (sofern er nicht mit Using aufgerufen wird)
      Version 1.1
      PickFolderDialog

      C#-Quellcode

      1. using System;
      2. using System.ComponentModel;
      3. using System.Runtime.InteropServices;
      4. using System.Windows.Forms;
      5. // Version 1.1 2022-01-16
      6. namespace TestPickFolderDialog
      7. {
      8. /// <summary>
      9. /// FolderBrowserDialog im Gewandt eines OpenFileDialogs
      10. /// </summary>
      11. [DesignerCategory("code")]
      12. public class PickFolderDialog
      13. : Component
      14. {
      15. #region Const
      16. // siehe Headerfile Winerror.h
      17. private const int S_OK = 0;
      18. // siehe Headerfile shobjidl_core.h
      19. private const string IID_IModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802";
      20. private const string IID_IFileDialog = "42f85136-db7e-439c-85f1-e4075d135fc8";
      21. private const string IID_IShellItem = "43826d1e-e718-42ee-bc55-a1e261c37bfe";
      22. private const string CLSID_FileOpenDialog = "dc1c5a9c-e88a-4dde-a5a1-60f82a20aef7";
      23. #endregion Const
      24. #region Enums
      25. // siehe Headerfile shobjidl_core.h
      26. private enum FileOpenDialogOptions : int
      27. {
      28. OverwritePrompt = 0x2,
      29. FOS_STRICTFILETYPES = 0x4,
      30. FOS_NOCHANGEDIR = 0x8,
      31. FOS_PICKFOLDERS = 0x20,
      32. FOS_FORCEFILESYSTEM = 0x40,
      33. FOS_ALLNONSTORAGEITEMS = 0x80,
      34. FOS_NOVALIDATE = 0x100,
      35. FOS_ALLOWMULTISELECT = 0x200,
      36. FOS_PATHMUSTEXIST = 0x800,
      37. FOS_FILEMUSTEXIST = 0x1000,
      38. FOS_CREATEPROMPT = 0x2000,
      39. FOS_SHAREAWARE = 0x4000,
      40. FOS_NOREADONLYRETURN = 0x8000,
      41. FOS_NOTESTFILECREATE = 0x10000,
      42. FOS_HIDEMRUPLACES = 0x20000,
      43. FOS_HIDEPINNEDPLACES = 0x40000,
      44. FOS_NODEREFERENCELINKS = 0x100000,
      45. FOS_OKBUTTONNEEDSINTERACTION = 0x200000,
      46. FOS_DONTADDTORECENT = 0x2000000,
      47. FOS_FORCESHOWHIDDEN = 0x10000000,
      48. FOS_DEFAULTNOMINIMODE = 0x20000000,
      49. FOS_FORCEPREVIEWPANEON = 0x40000000,
      50. FOS_SUPPORTSTREAMABLEITEMS = int.MinValue + 0x00000000
      51. }
      52. // siehe Headerfile shobjidl_core.h
      53. public enum SIGDN : int
      54. {
      55. SIGDN_NORMALDISPLAYField = 0x0,
      56. SIGDN_PARENTRELATIVEPARSINGField = int.MinValue + 0x00018001,
      57. SIGDN_DESKTOPABSOLUTEPARSINGField = int.MinValue + 0x00028000,
      58. SIGDN_PARENTRELATIVEEDITINGField = int.MinValue + 0x00031001,
      59. SIGDN_DESKTOPABSOLUTEEDITINGField = int.MinValue + 0x0004C000,
      60. SIGDN_FILESYSPATHField = int.MinValue + 0x00058000,
      61. SIGDN_URLField = int.MinValue + 0x00068000,
      62. SIGDN_PARENTRELATIVEFORADDRESSBARField = int.MinValue + 0x0007C001,
      63. SIGDN_PARENTRELATIVEField = int.MinValue + 0x00080001,
      64. SIGDN_PARENTRELATIVEFORUIField = int.MinValue + 0x00094001
      65. }
      66. #endregion Enums
      67. #region Member
      68. /// <summary>
      69. /// COM-Instanz des Dialogs
      70. /// </summary>
      71. private IFileDialog FileDialog;
      72. #endregion Member
      73. #region API
      74. // siehe https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-shcreateitemfromparsingname
      75. // oder Headerfile shobjidl_core.h
      76. [DllImport("Shell32.dll", EntryPoint = "SHCreateItemFromParsingName")]
      77. [PreserveSig]
      78. private static extern int SHCreateItemFromParsingName([In][MarshalAs(UnmanagedType.LPWStr)] string pszPath, [In] IntPtr pbc, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr pUnk);
      79. #endregion
      80. #region Properties
      81. /// <summary>
      82. /// Gets or sets the path selected by the user.
      83. /// Wird nichts angegeben: "Dieser PC"
      84. /// </summary>
      85. public string SelectedPath { get; set; }
      86. #endregion Properties
      87. #region Konstruktor
      88. public PickFolderDialog()
      89. {
      90. FileOpenDialogOptions options;
      91. this.FileDialog = (IFileDialog)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(CLSID_FileOpenDialog)));
      92. if (this.FileDialog == null)
      93. {
      94. throw new COMException("PickFolderDialog constructor failed.");
      95. }
      96. if (this.FileDialog.GetOptions(out options) == S_OK)
      97. {
      98. options |= FileOpenDialogOptions.FOS_PICKFOLDERS;
      99. this.FileDialog.SetOptions(options);
      100. }
      101. }
      102. #endregion Konstruktor
      103. #region Public Functions
      104. public DialogResult ShowDialog(IntPtr hwndOwner)
      105. {
      106. this.SetFolder(this.SelectedPath);
      107. if (this.FileDialog.Show(hwndOwner) == S_OK)
      108. {
      109. this.SelectedPath = this.GetResult(PickFolderDialog.SIGDN.SIGDN_FILESYSPATHField);
      110. return DialogResult.OK;
      111. }
      112. return DialogResult.Cancel;
      113. }
      114. public string GetResult(SIGDN eSIGDN = SIGDN.SIGDN_FILESYSPATHField)
      115. {
      116. string strRet = string.Empty;
      117. if (this.FileDialog.GetResult(out IShellItem ShellItem) == S_OK)
      118. {
      119. if (ShellItem.GetDisplayName(eSIGDN, out IntPtr pszName) == S_OK)
      120. {
      121. strRet = Marshal.PtrToStringUni(pszName);
      122. Marshal.FreeCoTaskMem(pszName);
      123. }
      124. Marshal.ReleaseComObject(ShellItem);
      125. }
      126. return strRet;
      127. }
      128. #endregion Public Functions
      129. #region Private Functions
      130. private bool SetFolder(string folder)
      131. {
      132. // Wird bei Dialog.SetFolder nichts angegeben = Dieser PC
      133. // Ansonsten z.B. "C:" oder "C:\" = Laufwerk C:
      134. // "C:\Users" oder "C:\Users\" = Ordner Users auf Laufwerk C:
      135. // "::{645FF040-5081-101B-9F08-00AA002F954E}" = Papierkorb
      136. // "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}" = Netzwerk
      137. // "::{031E4825-7B94-4DC3-B131-E946B44C8DD5}" = Bibliotheken
      138. // usw.
      139. bool retval = false;
      140. IntPtr item;
      141. if (folder is null)
      142. {
      143. // C-String-Ende-Kennung
      144. folder = "\0";
      145. }
      146. if (SHCreateItemFromParsingName(folder, IntPtr.Zero, new Guid(IID_IShellItem), out item) == S_OK)
      147. {
      148. if (this.FileDialog.SetFolder(item) == S_OK)
      149. {
      150. retval = true;
      151. }
      152. Marshal.Release(item);
      153. }
      154. return retval;
      155. }
      156. #endregion Private Functions
      157. #region Interface IModalWindow
      158. // siehe Headerfile shobjidl_core.h
      159. [ComImport]
      160. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      161. [Guid(IID_IModalWindow)]
      162. private interface IModalWindow
      163. {
      164. // virtual /* [local] */ HRESULT STDMETHODCALLTYPE Show(
      165. // /* [annotation][unique][in] */
      166. // _In_opt_ HWND hwndOwner) = 0;
      167. [PreserveSig]
      168. int Show([In] IntPtr hwndOwner);
      169. }
      170. #endregion
      171. #region Interface IFileDialog
      172. // siehe Headerfile shobjidl_core.h
      173. [ComImport]
      174. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      175. [Guid(IID_IFileDialog)]
      176. private interface IFileDialog : IModalWindow
      177. {
      178. [PreserveSig]
      179. new int Show([In] IntPtr hwndOwner);
      180. // virtual HRESULT STDMETHODCALLTYPE SetFileTypes(
      181. // /* [in] */ UINT cFileTypes,
      182. // /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec) = 0;
      183. [PreserveSig]
      184. int SetFileTypes();
      185. // virtual HRESULT STDMETHODCALLTYPE SetFileTypeIndex(
      186. // /* [in] */ UINT iFileType) = 0;
      187. [PreserveSig]
      188. int SetFileTypeIndex();
      189. // virtual HRESULT STDMETHODCALLTYPE GetFileTypeIndex(
      190. // /* [out] */ __RPC__out UINT *piFileType) = 0;
      191. [PreserveSig]
      192. int GetFileTypeIndex();
      193. // virtual HRESULT STDMETHODCALLTYPE Advise(
      194. // /* [in] */ __RPC__in_opt IFileDialogEvents *pfde,
      195. // /* [out] */ __RPC__out DWORD *pdwCookie) = 0;
      196. [PreserveSig]
      197. int Advise();
      198. // virtual HRESULT STDMETHODCALLTYPE Unadvise(
      199. // /* [in] */ DWORD dwCookie) = 0;
      200. [PreserveSig]
      201. int Unadvise();
      202. // virtual HRESULT STDMETHODCALLTYPE SetOptions(
      203. // /* [in] */ FILEOPENDIALOGOPTIONS fos) = 0;
      204. [PreserveSig]
      205. int SetOptions([In] FileOpenDialogOptions fos);
      206. // virtual HRESULT STDMETHODCALLTYPE GetOptions(
      207. // /* [out] */ __RPC__out FILEOPENDIALOGOPTIONS *pfos) = 0;
      208. [PreserveSig]
      209. int GetOptions(out FileOpenDialogOptions pfos);
      210. // virtual HRESULT STDMETHODCALLTYPE SetDefaultFolder(
      211. // /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      212. [PreserveSig]
      213. int SetDefaultFolder();
      214. // virtual HRESULT STDMETHODCALLTYPE SetFolder(
      215. // /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      216. [PreserveSig]
      217. int SetFolder([In] IntPtr psi);
      218. // virtual HRESULT STDMETHODCALLTYPE GetFolder(
      219. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      220. [PreserveSig]
      221. int GetFolder();
      222. // virtual HRESULT STDMETHODCALLTYPE GetCurrentSelection(
      223. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      224. [PreserveSig]
      225. int GetCurrentSelection();
      226. // virtual HRESULT STDMETHODCALLTYPE SetFileName(
      227. // /* [string][in] */ __RPC__in_string LPCWSTR pszName) = 0;
      228. [PreserveSig]
      229. int SetFileName();
      230. // virtual HRESULT STDMETHODCALLTYPE GetFileName(
      231. // /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName) = 0;
      232. [PreserveSig]
      233. int GetFileName();
      234. // virtual HRESULT STDMETHODCALLTYPE SetTitle(
      235. // /* [string][in] */ __RPC__in_string LPCWSTR pszTitle) = 0;
      236. [PreserveSig]
      237. int SetTitle();
      238. // virtual HRESULT STDMETHODCALLTYPE SetOkButtonLabel(
      239. // /* [string][in] */ __RPC__in_string LPCWSTR pszText) = 0;
      240. [PreserveSig]
      241. int SetOkButtonLabel();
      242. // virtual HRESULT STDMETHODCALLTYPE SetFileNameLabel(
      243. // /* [string][in] */ __RPC__in_string LPCWSTR pszLabel) = 0;
      244. [PreserveSig]
      245. int SetFileNameLabel();
      246. // virtual HRESULT STDMETHODCALLTYPE GetResult(
      247. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      248. [PreserveSig]
      249. int GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
      250. // virtual HRESULT STDMETHODCALLTYPE AddPlace(
      251. // /* [in] */ __RPC__in_opt IShellItem *psi,
      252. // /* [in] */ FDAP fdap) = 0;
      253. [PreserveSig]
      254. int AddPlace();
      255. // virtual HRESULT STDMETHODCALLTYPE SetDefaultExtension(
      256. // /* [string][in] */ __RPC__in_string LPCWSTR pszDefaultExtension) = 0;
      257. [PreserveSig]
      258. int SetDefaultExtension();
      259. // virtual HRESULT STDMETHODCALLTYPE Close(
      260. // /* [in] */ HRESULT hr) = 0;
      261. [PreserveSig]
      262. int Close();
      263. // virtual HRESULT STDMETHODCALLTYPE SetClientGuid(
      264. // /* [in] */ __RPC__in REFGUID guid) = 0;
      265. [PreserveSig]
      266. int SetClientGuid();
      267. // virtual HRESULT STDMETHODCALLTYPE ClearClientData( void) = 0;
      268. [PreserveSig]
      269. int ClearClientData();
      270. // virtual HRESULT STDMETHODCALLTYPE SetFilter(
      271. // /* [in] */ __RPC__in_opt IShellItemFilter *pFilter) = 0;
      272. [PreserveSig]
      273. int SetFilter();
      274. }
      275. #endregion
      276. #region Interface IShellItem
      277. // siehe Headerfile shobjidl_core.h
      278. [ComImport]
      279. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      280. [Guid(IID_IShellItem)]
      281. private interface IShellItem
      282. {
      283. // virtual HRESULT STDMETHODCALLTYPE BindToHandler(
      284. // /* [unique][in] */ __RPC__in_opt IBindCtx *pbc,
      285. // /* [in] */ __RPC__in REFGUID bhid,
      286. // /* [in] */ __RPC__in REFIID riid,
      287. // /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
      288. [PreserveSig]
      289. int BindToHandler();
      290. // virtual HRESULT STDMETHODCALLTYPE GetParent(
      291. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      292. [PreserveSig]
      293. int GetParent();
      294. // virtual HRESULT STDMETHODCALLTYPE GetDisplayName(
      295. // /* [in] */ SIGDN sigdnName,
      296. // /* [annotation][string][out] */
      297. // _Outptr_result_nullonfailure_ LPWSTR *ppszName) = 0;
      298. [PreserveSig]
      299. int GetDisplayName([In] SIGDN sigdnName, out IntPtr ppszName);
      300. // virtual HRESULT STDMETHODCALLTYPE GetAttributes(
      301. // /* [in] */ SFGAOF sfgaoMask,
      302. // /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0;
      303. [PreserveSig]
      304. int GetAttributes();
      305. // virtual HRESULT STDMETHODCALLTYPE Compare(
      306. // /* [in] */ __RPC__in_opt IShellItem *psi,
      307. // /* [in] */ SICHINTF hint,
      308. // /* [out] */ __RPC__out int *piOrder) = 0;
      309. [PreserveSig]
      310. int Compare();
      311. }
      312. #endregion
      313. #region Dispose
      314. protected override void Dispose(bool disposing)
      315. {
      316. if (this.FileDialog != null)
      317. {
      318. Marshal.ReleaseComObject(this.FileDialog);
      319. this.FileDialog = null;
      320. }
      321. base.Dispose(disposing);
      322. }
      323. #endregion Dispose
      324. }
      325. }
      Aufruf

      C#-Quellcode

      1. private void Button1_Click(object sender, EventArgs e)
      2. {
      3. if (this.pickFolderDialog1.ShowDialog(this.Handle) == DialogResult.OK)
      4. {
      5. // this.pickFolderDialog1 ist die Instanz, die im Designer auf die GUI gezogen wurde
      6. this.label1.Text = this.pickFolderDialog1.SelectedPath;
      7. }
      8. }
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodFromGermany“ ()

      zwei Dinge:
      • ich finde den gegebenen FolderBrowserDialog deutlich besser - was hat man davon, wenn der FolderBrowserDialog aussieht wie ein FileOpenDialog?
      • Man kann den PicFolderDialog nicht aus der Toolbox aufs Form ziehen.
        Somit speichert er auch nicht den zuletzt bestätigten Pfad - was imo ein nützliches Feature ist - siehe Dialoge benutzen ist einfach
      • Er öffnet nicht modal ?(
      Dateien

      ErfinderDesRades schrieb:

      Er öffnet nicht modal
      Ja, das ist mir noch gar nicht aufgefallen.
      Und noch ein Nebeneffekt:
      Man kann n Stück PickFolderDialog-Instanzen öffnen und dann das Hauptprogramm schließen.
      Die ersten (n-1) PickFolderDialog-Instanzen bleiben stehen.
      Ja, da ist doch einiges im Argen.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Moin moin

      Vllt bringe ich mal ein wenig Licht ins Dunkle. Es gibt, für mich, 3 Gründe den veralteten FolderBrowserDialog ab WinVista nicht mehr zu verwenden.

      1. Der FolderBrowserDialog wird intern per API SHBrowseForFolder erstellt. Das führt uns hierher: docs.microsoft.com/en-us/windo…j_core-shbrowseforfoldera und da steht unter Remarks:
      For Windows Vista or later, it is [b]recommended[/b] that you use IFileDialog with the FOS_PICKFOLDERS option rather than the SHBrowseForFolder function. This uses the Open Files dialog in pick folders mode and is the [b]preferred implementation[/b].
      2. Der FolderBrowserDialog hat einen kleinen Bug im Zusammenhang mit dem Flag BIF_USENEWUI. Wenn man dem FolderBrowserDialog einen Ordner mitgibt, der nach dem Öffnen des Dialoges gleich im sichtbaren Bereich des TreeView zu sehen sein soll, klappt dieses nur beim ersten Aufruf. Bei nachfolgenden Aufrufen ist der vorgegebene Ordner nicht in dem sichtbaren Bereich des TreeViews bzw der vorgegebene Ordner wird nicht in den sichtbaren Bereich gescrollt.
      3. das mein persönlicher Grund: Der Open- und Save-Dialog sahen schon immer gleich aus. Nur der FolderBrowser-Dialog wich davon ab. Ab WinVista gibt es nun die Möglichkeit das alle 3 Dialoge gleich aussehen. Ich wüsste keinen Grund warum ein OpenFile-Dialog oder OpenFolder-Dialog unterschiedlich aussehen sollten (usability.)

      ErfinderDesRades schrieb:

      Man kann den PicFolderDialog nicht aus der Toolbox aufs Form ziehen. Somit speichert er auch nicht den zuletzt bestätigten Pfad

      Das mit der Toolbox ist doch machbar? Einfach ein UserControl draus machen? Der zuletzt bestätigten Pfad wird gespeichert. Durch IFileDialog.SetFolder wird dieser aber überschrieben bzw. erzwingt einen anderen Ordner. Ansonsten mal in die Doku schauen: IFileDialog.SetClientGuid oder auch IFileDialog.ClearClientData bzw. IFileDialog.SetFolder nicht aufrufen oder den zuletzt zurückgegebenen Ordner wieder bei IFileDialog.SetFolder setzen.

      RodFromGermany schrieb:

      Die ersten (n-1) PickFolderDialog-Instanzen bleiben stehen.
      Ja, da ist doch einiges im Argen.

      IFileDialog::Close?

      Ich kann Euch nur die Doku zu den Interfaces empfehlen:
      IFileDialog interface: docs.microsoft.com/en-us/windo…shobjidl_core-ifiledialog
      IFileDialog2 interface: docs.microsoft.com/en-us/windo…/nn-shobjidl-ifiledialog2
      IFileDialogEvents interface: https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nn-shobjidl_core-ifiledialogevents

      Edit: Darüber hinaus bieten die neuen Dialoge mehr Möglichkeiten als die Standard-Dialoge (OpenFile/SaveFile/BrowserForFolder).
      Mfg -Franky-

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „-Franky-“ ()

      -Franky- schrieb:

      IFileDialog::Close?
      Offensichtlich läuft dieser Dialog in einem separaten Thread.
      Weil dieser nicht modale Dialog nicht in Application.OpenForms gelistet ist (wie auch, es ist ja keine WinForm), kann er nicht als zu schließendes Fenster erkannt werden.
      Vielleicht können wir gemeinsam hier ja einen schnuckeligen PickFolderDialog kreieren.
      ====
      Was mich ebenfalls und besonders am FolderBrowserDialog stört, ist, dass er das Start-Verzeichnis nicht aufklappt bzw. zentral anzeigt.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!

      Verhalten von ShowDialog() nachgezogen

      @ErfinderDesRades @-Franky-
      Wenn der Dialog mit

      VB.NET-Quellcode

      1. if (dlg.ShowDialog(this.Handle) == DialogResult.OK)
      aufgerufen wird, verhält er sich wie ein modaler Dialog.
      Wenn die Signatur von ShowDialog() entsprechend angepasst wird:

      C#-Quellcode

      1. public DialogResult ShowDialog(IntPtr hwndOwner = default)
      =>

      C#-Quellcode

      1. public DialogResult ShowDialog(IntPtr hwndOwner)
      ist das Problem mit dem Aufruf gelöst.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @RodFromGermany

      RodFromGermany schrieb:

      Was mich ebenfalls und besonders am FolderBrowserDialog stört, ist, dass er das Start-Verzeichnis nicht aufklappt bzw. zentral anzeigt.

      Noch so ein blöder Bug mit dem alten BrowserForFolder-Dialog.

      RodFromGermany schrieb:

      Vielleicht können wir gemeinsam hier ja einen schnuckeligen PickFolderDialog kreieren.

      Ich gebe Dir gern weitere Infos. Zuerst, falls Du kein Bock hast das komplette SDK herunterzuladen um nach den Headerdateien zu suchen, die findet man auch so im Internet:
      ShObjIdl_core.h -> github.com/tpn/winsdk-10/blob/…6299.0/um/ShObjIdl_core.h
      ShObjIdl.h -> github.com/tpn/winsdk-10/blob/…0.0.16299.0/um/ShObjIdl.h
      und das hier nutze ich auch ganz gern wenn ich weis wonach ich suche (IIDs, GUIDs, Enums, Const, Errorcodes usw)-> magnumdb.com/

      Zunächst würde ich zwei weitere Interfaces einbauen.

      VB.NET-Quellcode

      1. Private Const IID_IFileDialog2 As String = "61744fc7-85b5-4791-a9b0-272276309b13"
      2. Private Const IID_IFileDialogEvents As String = "973510db-7d7f-452b-8975-74a85828d354"


      Ich habe hier gleich auch noch ein paar Funktionen der Interfaces vervollständigt die für den PickFolder-Dialog von Interesse sein könnten.
      Spoiler anzeigen

      VB.NET-Quellcode

      1. #Region "Interface IFileDialog"
      2. ' siehe Headerfile shobjidl_core.h
      3. <ComImport>
      4. <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
      5. <Guid(IID_IFileDialog)>
      6. Private Interface IFileDialog
      7. Inherits IModalWindow
      8. <PreserveSig> Shadows Function Show(<[In]> hwndOwner As IntPtr) As Integer
      9. 'virtual HRESULT STDMETHODCALLTYPE SetFileTypes(
      10. ' /* [in] */ UINT cFileTypes,
      11. ' /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec) = 0;
      12. <PreserveSig> Function SetFileTypes() As Integer
      13. 'virtual HRESULT STDMETHODCALLTYPE SetFileTypeIndex(
      14. ' /* [in] */ UINT iFileType) = 0;
      15. <PreserveSig> Function SetFileTypeIndex() As Integer
      16. 'virtual HRESULT STDMETHODCALLTYPE GetFileTypeIndex(
      17. ' /* [out] */ __RPC__out UINT *piFileType) = 0;
      18. <PreserveSig> Function GetFileTypeIndex() As Integer
      19. 'virtual HRESULT STDMETHODCALLTYPE Advise(
      20. ' /* [in] */ __RPC__in_opt IFileDialogEvents *pfde,
      21. ' /* [out] */ __RPC__out DWORD *pdwCookie) = 0;
      22. <PreserveSig> Function Advise(<[In], MarshalAs(UnmanagedType.Interface)> pfde As IFileDialogEvents,
      23. <Out> ByRef pdwCookie As Integer) As Integer
      24. 'virtual HRESULT STDMETHODCALLTYPE Unadvise(
      25. ' /* [in] */ DWORD dwCookie) = 0;
      26. <PreserveSig> Function Unadvise(<[In]> dwCookie As Integer) As Integer
      27. 'virtual HRESULT STDMETHODCALLTYPE SetOptions(
      28. ' /* [in] */ FILEOPENDIALOGOPTIONS fos) = 0;
      29. <PreserveSig> Function SetOptions(<[In]> fos As FILEOPENDIALOGOPTIONS) As Integer
      30. 'virtual HRESULT STDMETHODCALLTYPE GetOptions(
      31. ' /* [out] */ __RPC__out FILEOPENDIALOGOPTIONS *pfos) = 0;
      32. <PreserveSig> Function GetOptions(<Out> ByRef pfos As FILEOPENDIALOGOPTIONS) As Integer
      33. 'virtual HRESULT STDMETHODCALLTYPE SetDefaultFolder(
      34. ' /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      35. <PreserveSig> Function SetDefaultFolder(<[In]> psi As IntPtr) As Integer
      36. 'virtual HRESULT STDMETHODCALLTYPE SetFolder(
      37. ' /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      38. <PreserveSig> Function SetFolder(<[In]> psi As IntPtr) As Integer
      39. 'virtual HRESULT STDMETHODCALLTYPE GetFolder(
      40. ' /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      41. <PreserveSig> Function GetFolder(<Out, MarshalAs(UnmanagedType.Interface)> ByRef ppsi As IShellItem) As Integer
      42. 'virtual HRESULT STDMETHODCALLTYPE GetCurrentSelection(
      43. ' /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      44. <PreserveSig> Function GetCurrentSelection() As Integer
      45. 'virtual HRESULT STDMETHODCALLTYPE SetFileName(
      46. ' /* [string][in] */ __RPC__in_string LPCWSTR pszName) = 0;
      47. <PreserveSig> Function SetFileName() As Integer
      48. 'virtual HRESULT STDMETHODCALLTYPE GetFileName(
      49. ' /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName) = 0;
      50. <PreserveSig> Function GetFileName() As Integer
      51. 'virtual HRESULT STDMETHODCALLTYPE SetTitle(
      52. ' /* [string][in] */ __RPC__in_string LPCWSTR pszTitle) = 0;
      53. <PreserveSig> Function SetTitle(<[In], MarshalAs(UnmanagedType.LPWStr)> pszTitle As String) As Integer
      54. 'virtual HRESULT STDMETHODCALLTYPE SetOkButtonLabel(
      55. ' /* [string][in] */ __RPC__in_string LPCWSTR pszText) = 0;
      56. <PreserveSig> Function SetOkButtonLabel(<[In], MarshalAs(UnmanagedType.LPWStr)> pszText As String) As Integer
      57. 'virtual HRESULT STDMETHODCALLTYPE SetFileNameLabel(
      58. ' /* [string][in] */ __RPC__in_string LPCWSTR pszLabel) = 0;
      59. <PreserveSig> Function SetFileNameLabel(<[In], MarshalAs(UnmanagedType.LPWStr)> pszLabel As String) As Integer
      60. 'virtual HRESULT STDMETHODCALLTYPE GetResult(
      61. ' /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      62. <PreserveSig> Function GetResult(<Out, MarshalAs(UnmanagedType.Interface)> ByRef ppsi As IShellItem) As Integer
      63. 'virtual HRESULT STDMETHODCALLTYPE AddPlace(
      64. ' /* [in] */ __RPC__in_opt IShellItem *psi,
      65. ' /* [in] */ FDAP fdap) = 0;
      66. <PreserveSig> Function AddPlace() As Integer
      67. 'virtual HRESULT STDMETHODCALLTYPE SetDefaultExtension(
      68. ' /* [string][in] */ __RPC__in_string LPCWSTR pszDefaultExtension) = 0;
      69. <PreserveSig> Function SetDefaultExtension() As Integer
      70. 'virtual HRESULT STDMETHODCALLTYPE Close(
      71. ' /* [in] */ HRESULT hr) = 0;
      72. <PreserveSig> Function Close() As Integer
      73. 'virtual HRESULT STDMETHODCALLTYPE SetClientGuid(
      74. ' /* [in] */ __RPC__in REFGUID guid) = 0;
      75. <PreserveSig> Function SetClientGuid() As Integer
      76. 'virtual HRESULT STDMETHODCALLTYPE ClearClientData( void) = 0;
      77. <PreserveSig> Function ClearClientData() As Integer
      78. 'virtual HRESULT STDMETHODCALLTYPE SetFilter(
      79. ' /* [in] */ __RPC__in_opt IShellItemFilter *pFilter) = 0;
      80. <PreserveSig> Function SetFilter() As Integer
      81. End Interface
      82. #End Region
      83. #Region "Interface IFileDialog2"
      84. ' siehe Headerfile ShObjIdl.h
      85. <ComImport>
      86. <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
      87. <Guid(IID_IFileDialog2)>
      88. Private Interface IFileDialog2
      89. Inherits IFileDialog
      90. <PreserveSig> Shadows Function Show(<[In]> hwndOwner As IntPtr) As Integer
      91. <PreserveSig> Shadows Function SetFileTypes() As Integer
      92. <PreserveSig> Shadows Function SetFileTypeIndex() As Integer
      93. <PreserveSig> Shadows Function GetFileTypeIndex() As Integer
      94. <PreserveSig> Shadows Function Advise(<[In], MarshalAs(UnmanagedType.Interface)> pfde As IFileDialogEvents,
      95. <Out> ByRef pdwCookie As Integer) As Integer
      96. <PreserveSig> Shadows Function Unadvise(<[In]> dwCookie As Integer) As Integer
      97. <PreserveSig> Shadows Function SetOptions(<[In]> fos As FILEOPENDIALOGOPTIONS) As Integer
      98. <PreserveSig> Shadows Function GetOptions(<Out> ByRef pfos As FILEOPENDIALOGOPTIONS) As Integer
      99. <PreserveSig> Shadows Function SetDefaultFolder(<[In]> psi As IntPtr) As Integer
      100. <PreserveSig> Shadows Function SetFolder(<[In]> psi As IntPtr) As Integer
      101. <PreserveSig> Shadows Function GetFolder(<Out, MarshalAs(UnmanagedType.Interface)> ByRef ppsi As IShellItem) As Integer
      102. <PreserveSig> Shadows Function GetCurrentSelection() As Integer
      103. <PreserveSig> Shadows Function SetFileName() As Integer
      104. <PreserveSig> Shadows Function GetFileName() As Integer
      105. <PreserveSig> Shadows Function SetTitle(<[In], MarshalAs(UnmanagedType.LPWStr)> pszTitle As String) As Integer
      106. <PreserveSig> Shadows Function SetOkButtonLabel(<[In], MarshalAs(UnmanagedType.LPWStr)> pszText As String) As Integer
      107. <PreserveSig> Shadows Function SetFileNameLabel(<[In], MarshalAs(UnmanagedType.LPWStr)> pszLabel As String) As Integer
      108. <PreserveSig> Shadows Function GetResult(<Out, MarshalAs(UnmanagedType.Interface)> ByRef ppsi As IShellItem) As Integer
      109. <PreserveSig> Shadows Function AddPlace() As Integer
      110. <PreserveSig> Shadows Function SetDefaultExtension() As Integer
      111. <PreserveSig> Shadows Function Close() As Integer
      112. <PreserveSig> Shadows Function SetClientGuid() As Integer
      113. <PreserveSig> Shadows Function ClearClientData() As Integer
      114. <PreserveSig> Shadows Function SetFilter() As Integer
      115. 'virtual HRESULT STDMETHODCALLTYPE SetCancelButtonLabel(
      116. ' /* [in] */ __RPC__in LPCWSTR pszLabel) = 0;
      117. <PreserveSig> Function SetCancelButtonLabel(<[In], MarshalAs(UnmanagedType.LPWStr)> pszLabel As String) As Integer
      118. 'virtual HRESULT STDMETHODCALLTYPE SetNavigationRoot(
      119. ' /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      120. <PreserveSig> Function SetNavigationRoot(<[In]> psi As IntPtr) As Integer
      121. End Interface
      122. #End Region
      123. #Region "Interface IFileDialogEvents"
      124. ' siehe Headerfile shobjidl_core.h
      125. <ComImport>
      126. <InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
      127. <Guid(IID_IFileDialogEvents)>
      128. Private Interface IFileDialogEvents
      129. 'virtual HRESULT STDMETHODCALLTYPE OnFileOk(
      130. ' /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0;
      131. <PreserveSig> Function OnFileOk(<[In], MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer
      132. 'virtual HRESULT STDMETHODCALLTYPE OnFolderChanging(
      133. ' /* [in] */ __RPC__in_opt IFileDialog *pfd,
      134. ' /* [in] */ __RPC__in_opt IShellItem *psiFolder) = 0;
      135. <PreserveSig> Function OnFolderChanging(<[In], MarshalAs(UnmanagedType.Interface)> pfd As Object,
      136. <[In], MarshalAs(UnmanagedType.Interface)> psiFolder As Object) As Integer
      137. 'virtual HRESULT STDMETHODCALLTYPE OnFolderChange(
      138. ' /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0;
      139. <PreserveSig> Function OnFolderChange(<[In], MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer
      140. 'virtual HRESULT STDMETHODCALLTYPE OnSelectionChange(
      141. ' /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0;
      142. <PreserveSig> Function OnSelectionChange(<[In], MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer
      143. 'virtual HRESULT STDMETHODCALLTYPE OnShareViolation(
      144. ' /* [in] */ __RPC__in_opt IFileDialog *pfd,
      145. ' /* [in] */ __RPC__in_opt IShellItem *psi,
      146. ' /* [out] */ __RPC__out FDE_SHAREVIOLATION_RESPONSE *pResponse) = 0;
      147. <PreserveSig> Function OnShareViolation(<[In], MarshalAs(UnmanagedType.Interface)> pfd As Object,
      148. <[In], MarshalAs(UnmanagedType.Interface)> psi As Object,
      149. <Out> ByRef pResponse As Integer) As Integer
      150. 'virtual HRESULT STDMETHODCALLTYPE OnTypeChange(
      151. ' /* [in] */ __RPC__in_opt IFileDialog *pfd) = 0;
      152. <PreserveSig> Function OnTypeChange(<[In], MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer
      153. 'virtual HRESULT STDMETHODCALLTYPE OnOverwrite(
      154. ' /* [in] */ __RPC__in_opt IFileDialog *pfd,
      155. ' /* [in] */ __RPC__in_opt IShellItem *psi,
      156. ' /* [out] */ __RPC__out FDE_OVERWRITE_RESPONSE *pResponse) = 0;
      157. <PreserveSig> Function OnOverwrite(<[In], MarshalAs(UnmanagedType.Interface)> pfd As Object,
      158. <[In], MarshalAs(UnmanagedType.Interface)> psi As Object,
      159. <Out> ByRef pResponse As Integer) As Integer
      160. End Interface
      161. #End Region



      Eine zusätzliche Variable: Private m_Cookie As Integer, und zwei Enums

      VB.NET-Quellcode

      1. Private Enum FDE_SHAREVIOLATION_RESPONSE As Integer
      2. FDESVR_DEFAULT = &H0
      3. FDESVR_ACCEPT = &H1
      4. FDESVR_REFUSE = &H2
      5. End Enum
      6. Private Enum FDE_OVERWRITE_RESPONSE As Integer
      7. FDEOR_DEFAULT = &H0
      8. FDEOR_ACCEPT = &H1
      9. FDEOR_REFUSE = &H2
      10. End Enum


      zusätzliches Implement IFileDialogEvents

      VB.NET-Quellcode

      1. Public Class PickFolderDialog
      2. Implements IDisposable
      3. Implements IFileDialogEvents ' <- zusätzlich

      das dann hierzu führt
      Spoiler anzeigen

      VB.NET-Quellcode

      1. #Region "Implements IFileDialogEvents"
      2. Public Function OnFileOk(<[In]> <MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer Implements IFileDialogEvents.OnFileOk
      3. Debug.Print("OnFileOk")
      4. Return S_OK
      5. End Function
      6. Public Function OnFolderChanging(<[In]> <MarshalAs(UnmanagedType.Interface)> pfd As Object,
      7. <[In]> <MarshalAs(UnmanagedType.Interface)> psiFolder As Object) As Integer Implements IFileDialogEvents.OnFolderChanging
      8. Debug.Print("OnFolderChanging")
      9. Return S_OK
      10. End Function
      11. Public Function OnFolderChange(<[In]> <MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer Implements IFileDialogEvents.OnFolderChange
      12. Debug.Print("OnFolderChange")
      13. Return S_OK
      14. End Function
      15. Public Function OnSelectionChange(<[In]> <MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer Implements IFileDialogEvents.OnSelectionChange
      16. Debug.Print("OnSelectionChange")
      17. Return S_OK
      18. End Function
      19. Public Function OnShareViolation(<[In]> <MarshalAs(UnmanagedType.Interface)> pfd As Object,
      20. <[In]> <MarshalAs(UnmanagedType.Interface)> psi As Object,
      21. <Out> ByRef pResponse As Integer) As Integer Implements IFileDialogEvents.OnShareViolation
      22. Debug.Print("OnShareViolation")
      23. Return S_OK
      24. End Function
      25. Public Function OnTypeChange(<[In]> <MarshalAs(UnmanagedType.Interface)> pfd As Object) As Integer Implements IFileDialogEvents.OnTypeChange
      26. Debug.Print("OnTypeChange")
      27. Return S_OK
      28. End Function
      29. Public Function OnOverwrite(<[In]> <MarshalAs(UnmanagedType.Interface)> pfd As Object,
      30. <[In]> <MarshalAs(UnmanagedType.Interface)> psi As Object,
      31. <Out> ByRef pResponse As Integer) As Integer Implements IFileDialogEvents.OnOverwrite
      32. Debug.Print("OnOverwrite")
      33. Return S_OK
      34. End Function
      35. #End Region



      Alle "If CType(m_FileOpenDialog, IFileDialog)" ändern wir auf "If CType(m_FileOpenDialog, IFileDialog2)".

      Dann kommen noch zwei kleine Änderungen
      Spoiler anzeigen

      VB.NET-Quellcode

      1. #Region "New"
      2. Public Sub New()
      3. Dim eFILEOPENDIALOGOPTIONS As FILEOPENDIALOGOPTIONS
      4. m_FileOpenDialog = Activator.CreateInstance(Type.GetTypeFromCLSID(New Guid(CLSID_FileOpenDialog)))
      5. If m_FileOpenDialog IsNot Nothing Then
      6. If CType(m_FileOpenDialog, IFileDialog2).GetOptions(eFILEOPENDIALOGOPTIONS) = S_OK Then
      7. eFILEOPENDIALOGOPTIONS = eFILEOPENDIALOGOPTIONS Or FILEOPENDIALOGOPTIONS.FOS_PICKFOLDERS
      8. If CType(m_FileOpenDialog, IFileDialog2).SetOptions(eFILEOPENDIALOGOPTIONS) = S_OK Then
      9. ' zusätzlich: IFileDialogEvents an den Dialog binden
      10. If CType(m_FileOpenDialog, IFileDialog2).Advise(Me, m_Cookie) = S_OK Then
      11. End If
      12. End If
      13. End If
      14. End If
      15. End Sub
      16. #End Region
      17. #Region "Implements IDisposable"
      18. Protected Overridable Sub Dispose(disposing As Boolean)
      19. If Not m_DisposedValue Then
      20. If disposing Then
      21. If m_FileOpenDialog IsNot Nothing Then
      22. ' IFileDialogEvents entbinden
      23. If m_Cookie <> 0 Then
      24. If CType(m_FileOpenDialog, IFileDialog).Unadvise(m_Cookie) = S_OK Then
      25. m_Cookie = 0
      26. End If
      27. End If
      28. If Marshal.ReleaseComObject(m_FileOpenDialog) = 0 Then
      29. m_FileOpenDialog = Nothing
      30. End If
      31. End If
      32. End If
      33. m_DisposedValue = True
      34. End If
      35. End Sub
      36. Public Sub Dispose() Implements IDisposable.Dispose
      37. Dispose(disposing:=True)
      38. GC.SuppressFinalize(Me)
      39. End Sub
      40. #End Region



      Damit kann man nun noch ein paar weitere Properties und Events für den Dialog zusätzlich einbauen.
      Mfg -Franky-
      @-Franky- Danke für Deine Bemühungen.
      Ich denke, hier besteht die Kunst im Weglassen.
      Das wichtigste für mich war ShowDialog(), das ist ja nun erledigt.
      Den zuletzt selektierten Pfad zu merken ist eine lokale String-Variable, allerdings rufe ich die File-Dialoge immer in einem Using-Block auf und halte selbst die Pfade unter Kontrolle,
      das ist deshalb so, weil bei mir mehrere OFD-SFD-Kombinationen in einem Mess-Dialog vorkommen.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @RodFromGermany

      RodFromGermany schrieb:

      Ich denke, hier besteht die Kunst im Weglassen.

      Ja klar. Wie ich immer sage, bau nur das ein was Du auch wirklich benötigst. Wenn man die erweiterten Möglichkeiten der Dialoge nicht verwendet, dann wech damit. ;)
      Mfg -Franky-
      @-Franky- Ich hab eben oben im Startpost die Version 1.1 angehängt.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!

      RodFromGermany schrieb:

      Was mich ebenfalls und besonders am FolderBrowserDialog stört, ist, dass er das Start-Verzeichnis nicht aufklappt bzw. zentral anzeigt.
      Was meinst du, was fehlt in dieser Ansicht?
      Bilder
      • 2022-01-16 19_20_10-ToMail.png

        20,15 kB, 321×550, 335 mal angesehen
      @ErfinderDesRades Das war wohl die alte Variante, die scrollte nicht zum selektierten Pfad.
      Ich sehe hier noch eine Lösung vor mir, in der wurde "von außen" mit nem Timer der selektierte Pfad "erscrollt".
      Hab das Snippet gefunden:
      Spoiler anzeigen

      VB.NET-Quellcode

      1. Imports System
      2. Imports System.Runtime.InteropServices
      3. Imports System.Windows.Forms
      4. ''' <summary>
      5. ''' Aufruf eines FolderBrowserDialogs, bei dem das Startverzeichnis im Anzeigebereich erscheint
      6. ''' Funktioniert nicht ganz so richtig.
      7. ''' </summary>
      8. ''' <remarks></remarks>
      9. Public Class Form2
      10. Private Const TV_FIRST As Integer = 4352
      11. Private Const TVGN_ROOT As Integer = 0
      12. Private Const TVGN_NEXT As Integer = 1
      13. Private Const TVGN_CHILD As Integer = 4
      14. Private Const TVGN_FIRSTVISIBLE As Integer = 5
      15. Private Const TVGN_NEXTVISIBLE As Integer = 6
      16. Private Const TVGN_CARET As Integer = 9
      17. Private Const TVM_SELECTITEM As Integer = 4363
      18. Private Const TVM_GETNEXTITEM As Integer = 4362
      19. Private Const TVM_GETITEM As Integer = 4364
      20. Private Const TVM_ENSUREVISIBLE As Long = 4372L
      21. Private Const TVM_EXPAND As Long = 4354L
      22. Private Const TVE_EXPAND As Integer = 2
      23. Public Sub New()
      24. Me.tm = New Timer()
      25. Me.InitializeComponent()
      26. End Sub
      27. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
      28. Public Shared Function FindWindowEx(ByVal hWndParent As IntPtr, ByVal hWndChildAfter As IntPtr, ByVal lpszClass As String, ByVal lpszWindow As String) As IntPtr
      29. End Function
      30. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
      31. Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
      32. End Function
      33. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
      34. Public Shared Function SendMessage(hWnd As IntPtr, Msg As UInt32, wParam As IntPtr, lParam As IntPtr) As IntPtr
      35. End Function
      36. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
      37. Public Shared Function GetWindowThreadProcessId(hwnd As IntPtr, lpdwProcessId As IntPtr) As IntPtr
      38. End Function
      39. Private Sub btnOpenFolderBrowser_Click(sender As Object, e As EventArgs) Handles btnOpenFolderBrowser.Click
      40. Dim folderBrowserDialog As FolderBrowserDialog = New FolderBrowserDialog()
      41. Me.tm.Interval = 200
      42. Using folderBrowserDialog2 As FolderBrowserDialog = folderBrowserDialog
      43. folderBrowserDialog2.SelectedPath = "D:\MyVideos\Fixed\"
      44. Me.tm.Start()
      45. folderBrowserDialog2.ShowDialog()
      46. Me.tm.Stop()
      47. End Using
      48. End Sub
      49. Private Sub tm_Tick(sender As Object, e As EventArgs) Handles tm.Tick
      50. Dim tVHandle As IntPtr = Me.getTVHandle(IntPtr.Zero)
      51. If tVHandle <> CType(0, IntPtr) Then
      52. Dim lParam As IntPtr = Form2.SendMessage(tVHandle, TVM_GETNEXTITEM, CType(TVGN_CARET, IntPtr), IntPtr.Zero)
      53. Form2.SendMessage(tVHandle, TVM_ENSUREVISIBLE, IntPtr.Zero, lParam)
      54. Form2.SendMessage(tVHandle, TVM_EXPAND, CType(TVE_EXPAND, IntPtr), lParam)
      55. Me.tm.Stop()
      56. End If
      57. End Sub
      58. Public Function getTVHandle(handle As IntPtr) As IntPtr
      59. Dim parent As IntPtr
      60. Dim returnTVHandle As Boolean
      61. If handle = IntPtr.Zero Then
      62. parent = Form2.FindWindow("#32770", Nothing)
      63. If Not Me.isFromSameThread(parent) Then
      64. Return Me.getTVHandle(parent)
      65. End If
      66. returnTVHandle = True
      67. Else
      68. parent = Form2.FindWindowEx(IntPtr.Zero, handle, "#32770", Nothing)
      69. If Not Me.isFromSameThread(parent) Then
      70. Return Me.getTVHandle(parent)
      71. End If
      72. returnTVHandle = True
      73. End If
      74. If returnTVHandle Then
      75. 'Get Control handle
      76. Dim hWndParent As IntPtr = Form2.FindWindowEx(parent, IntPtr.Zero, "SHBrowseForFolder ShellNameSpace Control", Nothing)
      77. Return Form2.FindWindowEx(hWndParent, IntPtr.Zero, "SysTreeView32", Nothing)
      78. End If
      79. Dim result As IntPtr
      80. Return result
      81. End Function
      82. Public Function isFromSameThread(handle As IntPtr) As Boolean
      83. Dim currentThreadId As Integer = AppDomain.GetCurrentThreadId() 'System.Threading.Thread.CurrentThread.ManagedThreadId
      84. Dim num As Integer = CInt(Form2.GetWindowThreadProcessId(handle, IntPtr.Zero))
      85. Return currentThreadId = num
      86. End Function
      87. End Class
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      @ErfinderDesRades
      Das Problem mit dem alten Dialog wird oft beschrieben. Wie hier zB: stackoverflow.com/questions/69…scroll-to-selected-folder Oder einfach mal nach "FolderBrowserDialog does not scroll selection" googeln. Irgendwann wurde mal was am alten Dialog geändert und ich glaub mich zu erinnern das ganze im Zusammenhang mit dem Flag BIF_NEWUI oder BIF_NEWDIALOGSTYLE steht. Ohne einen von diesen beiden Flags funktioniert der Dialog so wie er soll. Mit einem der beiden Flags kommt es zum genannten Problem das der Ordner nicht in den sichtbaren Bereich gescrollt wird bzw. beim ersten Start des Dialoges schon, danach nicht mehr. Soweit ich mich erinnere, da müsste man mal in das Framework schauen, wird in .NET der Dialog intern standardmäßig mit diesen Flags aufgerufen was zum besagten Problem führt.

      @RodFromGermany
      Uii, hab gerade mal mein Archiv durchsucht und autsch, was hat man nicht alles angestellt das dieser Dialog das macht was er soll. Ich stemple das unter Kuriositäten ab. Das ganze läuft hier ohne Timer. Aber so richtig wollte das auch nie.
      Spoiler anzeigen

      Quellcode

      1. Option Strict On
      2. Option Explicit On
      3. Imports System.Runtime.InteropServices
      4. Public Class FolderBrowseDialogEx
      5. Implements IDisposable
      6. Private Const S_OK As Integer = 0
      7. Private Const MAX_PATH As Integer = 512
      8. Private Const WM_USER As UInteger = 1024
      9. Private Const WM_VSCROLL As UInteger = 277
      10. Private Const TVM_ENSUREVISIBLE As Integer = 4372
      11. Private Const TVM_GETNEXTITEM As Integer = 4362
      12. Private Const TVM_EXPAND As Integer = 4354
      13. Private Const TVGN_CARET As Integer = 9
      14. Private Const TVE_COLLAPSE As Integer = 1
      15. Private Const TVE_EXPAND As Integer = 2
      16. Private Const SB_LINEUP As Integer = 0
      17. Private Const SB_LINEDOWN As Integer = 1
      18. Private Const BFFM_INITIALIZED As Integer = 1
      19. Private Const BFFM_SELCHANGED As Integer = 2
      20. Private Const BFFM_VALIDATEFAILEDA As Integer = 3
      21. Private Const BFFM_VALIDATEFAILEDW As Integer = 4
      22. Private Const BFFM_IUNKNOWN As Integer = 5
      23. Private Const BFFM_SETSTATUSTEXTA As Integer = (WM_USER + 100)
      24. Private Const BFFM_ENABLEOK As Integer = (WM_USER + 101)
      25. Private Const BFFM_SETSELECTIONA As Integer = (WM_USER + 102)
      26. Private Const BFFM_SETSELECTIONW As Integer = (WM_USER + 103)
      27. Private Const BFFM_SETSTATUSTEXTW As Integer = (WM_USER + 104)
      28. Private Const BFFM_SETOKTEXT As Integer = (WM_USER + 105)
      29. Private Const BFFM_SETEXPANDED As Integer = (WM_USER + 106)
      30. #Region "Public Enums"
      31. Public Enum eBrowseInfoFlags As UInteger
      32. BIF_RETURNONLYFSDIRS = 1
      33. BIF_DONTGOBELOWDOMAIN = 2
      34. BIF_STATUSTEXT = 4
      35. BIF_RETURNFSANCESTORS = 8
      36. BIF_EDITBOX = 16
      37. BIF_VALIDATE = 32
      38. BIF_NEWDIALOGSTYLE = 64
      39. BIF_BROWSEINCLUDEURLS = 128
      40. BIF_UAHINT = 256
      41. BIF_DONTSHOWNEWFOLDERBUTTON = 512
      42. BIF_USENEWUI = BIF_EDITBOX Or BIF_NEWDIALOGSTYLE
      43. 'BIF_BROWSEFORCOMPUTER = 4096
      44. 'BIF_BROWSEFORPRINTER = 8192
      45. 'BIF_BROWSEINCLUDEFILES = 16384
      46. 'BIF_SHAREABLE = 32768
      47. 'BIF_BROWSEFILEJUNCTIONS = ‭65536‬
      48. End Enum
      49. Public Enum eKnownFolderCSIDL As Integer
      50. '<desktop>
      51. CSIDL_DESKTOP = 0
      52. 'Internet Explorer (icon on desktop)
      53. CSIDL_INTERNET = 1
      54. 'Start Menu\Programs
      55. CSIDL_PROGRAMS = 2
      56. 'My Computer\Control Panel
      57. CSIDL_CONTROLS = 3
      58. 'My Computer\Printers
      59. CSIDL_PRINTERS = 4
      60. 'My Documents
      61. CSIDL_PERSONAL = 5
      62. '<user name>\Favourites
      63. CSIDL_FAVORITES = 6
      64. 'Start Menu\Programs\Startup
      65. CSIDL_STARTUP = 7
      66. '<user name>\Recent
      67. CSIDL_RECENT = 8
      68. '<user name>\SendTo
      69. CSIDL_SENDTO = 9
      70. '<desktop>\Recycle Bin
      71. CSIDL_BITBUCKET = &HA
      72. '<user name>\Start Menu
      73. CSIDL_STARTMENU = &HB
      74. 'logical "My Documents" desktop icon
      75. CSIDL_MYDOCUMENTS = &HC
      76. '"My Music" folder
      77. CSIDL_MYMUSIC = &HD
      78. '"My Videos" folder
      79. CSIDL_MYVIDEO = &HE
      80. '<user name>\Desktop
      81. CSIDL_DESKTOPDIRECTORY = &H10
      82. 'My Computer
      83. CSIDL_DRIVES = &H11
      84. 'Network Neighborhood (My Network Places)
      85. CSIDL_NETWORK = &H12
      86. '<user name>\nethood
      87. CSIDL_NETHOOD = &H13
      88. 'windows\fonts
      89. CSIDL_FONTS = &H14
      90. 'templates
      91. CSIDL_TEMPLATES = &H15
      92. 'All Users\Start Menu
      93. CSIDL_COMMON_STARTMENU = &H16
      94. 'All Users\Start Menu\Programs
      95. CSIDL_COMMON_PROGRAMS = &H17
      96. 'All Users\Startup
      97. CSIDL_COMMON_STARTUP = &H18
      98. 'All Users\Desktop
      99. CSIDL_COMMON_DESKTOPDIRECTORY = &H19
      100. '<user name>\Application Data
      101. CSIDL_APPDATA = &H1A
      102. '<user name>\PrintHood
      103. CSIDL_PRINTHOOD = &H1B
      104. '<user name>\Local Settings\Application Data (non roaming)
      105. CSIDL_LOCAL_APPDATA = &H1C
      106. 'non localized startup
      107. CSIDL_ALTSTARTUP = &H1D
      108. 'non localized common startup
      109. CSIDL_COMMON_ALTSTARTUP = &H1E
      110. CSIDL_COMMON_FAVORITES = &H1F
      111. CSIDL_INTERNET_CACHE = &H20
      112. CSIDL_COOKIES = &H21
      113. CSIDL_HISTORY = &H22
      114. 'All Users\Application Data
      115. CSIDL_COMMON_APPDATA = &H23
      116. 'GetWindowsDirectory()
      117. CSIDL_WINDOWS = &H24
      118. 'GetSystemDirectory()
      119. CSIDL_SYSTEM = &H25
      120. 'C:\Program Files
      121. CSIDL_PROGRAM_FILES = &H26
      122. 'C:\Program Files\My Pictures
      123. CSIDL_MYPICTURES = &H27
      124. 'USERPROFILE
      125. CSIDL_PROFILE = &H28
      126. 'x86 system directory on RISC
      127. CSIDL_SYSTEMX86 = &H29
      128. 'x86 C:\Program Files on RISC
      129. CSIDL_PROGRAM_FILESX86 = &H2A
      130. 'C:\Program Files\Common
      131. CSIDL_PROGRAM_FILES_COMMON = &H2B
      132. 'x86 Program Files\Common on RISC
      133. CSIDL_PROGRAM_FILES_COMMONX86 = &H2C
      134. 'All Users\Templates
      135. CSIDL_COMMON_TEMPLATES = &H2D
      136. 'All Users\Documents
      137. CSIDL_COMMON_DOCUMENTS = &H2E
      138. 'All Users\Start Menu\Programs\Administrative Tools
      139. CSIDL_COMMON_ADMINTOOLS = &H2F
      140. '<user name>\Start Menu\Programs\Administrative Tools
      141. CSIDL_ADMINTOOLS = &H30
      142. 'Network and Dial-up Connections
      143. CSIDL_CONNECTIONS = &H31
      144. 'All Users\My Music
      145. CSIDL_COMMON_MUSIC = &H35
      146. 'All Users\My Pictures
      147. CSIDL_COMMON_PICTURES = &H36
      148. 'All Users\My Video
      149. CSIDL_COMMON_VIDEO = &H37
      150. 'Resource Directory
      151. CSIDL_RESOURCES = &H38
      152. 'Localized Resource Directory
      153. CSIDL_RESOURCES_LOCALIZED = &H39
      154. 'Links to All Users OEM specific apps
      155. CSIDL_COMMON_OEM_LINKS = &H3A
      156. 'USERPROFILE\Local Settings\Application Data\Microsoft\CD Burning
      157. CSIDL_CDBURN_AREA = &H3B
      158. 'unused
      159. ' = &H3C
      160. 'Computers Near Me (computered from Workgroup membership)
      161. CSIDL_COMPUTERSNEARME = &H3D
      162. 'combine with CSIDL_ value to force folder creation in SHGetFolderPath()
      163. CSIDL_FLAG_CREATE = &H8000&
      164. 'combine with CSIDL_ value to return an unverified folder path
      165. CSIDL_FLAG_DONT_VERIFY = &H4000
      166. 'combine with CSIDL_ value to insure non-alias versions of the pidl
      167. CSIDL_FLAG_NO_ALIAS = &H1000
      168. 'combine with CSIDL_ value to indicate per-user init (eg. upgrade)
      169. CSIDL_FLAG_PER_USER_INIT = &H800
      170. End Enum
      171. #End Region
      172. #Region "Win32 Struct"
      173. Private Structure BROWSEINFO
      174. Dim hwndOwner As IntPtr
      175. Dim pidlRoot As IntPtr
      176. <MarshalAs(UnmanagedType.LPTStr)> Dim pszDisplayName As String
      177. <MarshalAs(UnmanagedType.LPTStr)> Dim lpszTitle As String
      178. <MarshalAs(UnmanagedType.U4)> Dim ulFlags As eBrowseInfoFlags
      179. <MarshalAs(UnmanagedType.FunctionPtr)> Dim lpfn As BrowseCallbackProc
      180. Dim lParam As IntPtr
      181. Dim iImage As Integer
      182. End Structure
      183. #End Region
      184. #Region "Win32 API"
      185. <DllImport("shell32.dll", EntryPoint:="ILFree", SetLastError:=True, CharSet:=CharSet.Auto)>
      186. Private Shared Sub ILFree(ByVal pidl As IntPtr)
      187. End Sub
      188. <DllImport("shell32.dll", EntryPoint:="SHGetDesktopFolder", SetLastError:=True, CharSet:=CharSet.Auto)>
      189. Private Shared Function SHGetDesktopFolder(<Out> ByRef ppshf As IShellFolder) As Integer
      190. End Function
      191. <DllImport("shell32.dll", EntryPoint:="SHBrowseForFolderW", SetLastError:=True, CharSet:=CharSet.Unicode)>
      192. Private Shared Function SHBrowseForFolderW(<MarshalAs(UnmanagedType.Struct)> ByRef lpFileOp As BROWSEINFO) As IntPtr
      193. End Function
      194. <DllImport("shell32.dll", EntryPoint:="SHGetPathFromIDListW", SetLastError:=True, CharSet:=CharSet.Unicode)>
      195. Private Shared Function SHGetPathFromIDListW(ByVal pidl As IntPtr,
      196. <MarshalAs(UnmanagedType.LPTStr)> ByVal pszPath As String) As Boolean
      197. End Function
      198. <DllImport("shell32.dll", EntryPoint:="SHGetFolderLocation", SetLastError:=True, CharSet:=CharSet.Auto)>
      199. Private Shared Function SHGetFolderLocation(ByVal hwndOwner As IntPtr,
      200. ByVal nFolder As eKnownFolderCSIDL,
      201. ByVal hToken As IntPtr,
      202. ByVal dwReserved As Integer,
      203. ByRef ppidl As IntPtr) As Integer
      204. End Function
      205. <DllImport("shell32.dll", EntryPoint:="SHGetSpecialFolderLocation", SetLastError:=True, CharSet:=CharSet.Auto)>
      206. Private Shared Function SHGetSpecialFolderLocation(ByVal hwndOwner As IntPtr,
      207. ByVal nFolder As Environment.SpecialFolder,
      208. ByRef ppidl As IntPtr) As Integer
      209. End Function
      210. <DllImport("ole32.dll", EntryPoint:="CreateBindCtx", SetLastError:=True, CharSet:=CharSet.Auto)>
      211. Private Shared Function CreateBindCtx(ByVal reserved As Integer,
      212. <Out> ByRef ppbc As IBindCtx) As Integer
      213. End Function
      214. <DllImport("user32.dll", EntryPoint:="PostMessageW", SetLastError:=True, CharSet:=CharSet.Auto)>
      215. Private Overloads Shared Function PostMessageW(ByVal hWnd As IntPtr,
      216. ByVal Msg As UInteger,
      217. ByVal wParam As UInteger,
      218. ByVal lParam As IntPtr) As Integer
      219. End Function
      220. <DllImport("user32.dll", EntryPoint:="SendMessageW", SetLastError:=True, CharSet:=CharSet.Auto)>
      221. Private Overloads Shared Function SendMessageW(ByVal hWnd As IntPtr,
      222. ByVal Msg As UInteger,
      223. ByVal wParam As UInteger,
      224. ByVal lParam As IntPtr) As IntPtr
      225. End Function
      226. <DllImport("user32.dll", EntryPoint:="SendMessageW", SetLastError:=True, CharSet:=CharSet.Auto)>
      227. Private Overloads Shared Function SendMessageW(ByVal hWnd As IntPtr,
      228. ByVal Msg As UInteger,
      229. ByVal wParam As UInteger,
      230. ByVal lParam As Integer) As IntPtr
      231. End Function
      232. <DllImport("user32.dll", EntryPoint:="SendMessageW", SetLastError:=True, CharSet:=CharSet.Unicode)>
      233. Private Overloads Shared Function SendMessageW(ByVal hWnd As IntPtr,
      234. ByVal Msg As UInteger,
      235. ByVal wParam As UInteger,
      236. <MarshalAs(UnmanagedType.LPWStr)> ByVal lParam As String) As IntPtr
      237. End Function
      238. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
      239. Public Shared Function FindWindowEx(ByVal hWndParent As IntPtr,
      240. ByVal hWndChildAfter As IntPtr,
      241. ByVal lpszClass As String,
      242. ByVal lpszWindow As String) As IntPtr
      243. End Function
      244. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
      245. Private Shared Function SetWindowText(ByVal hwnd As IntPtr,
      246. ByVal lpString As String) As Boolean
      247. End Function
      248. <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)>
      249. Private Shared Function SetFocus(ByVal hwnd As IntPtr) As IntPtr
      250. End Function
      251. #End Region
      252. #Region "Win32 Interfaces"
      253. <ComImport, Guid("000214E6-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
      254. Interface IShellFolder
      255. Function ParseDisplayName(<[In]> ByVal hwnd As IntPtr,
      256. <[In], MarshalAs(UnmanagedType.Interface)> ByVal pbc As IBindCtx,
      257. <[In], MarshalAs(UnmanagedType.LPWStr)> ByVal pszDisplayName As String,
      258. <Out, MarshalAs(UnmanagedType.U4)> ByRef pchEaten As UInteger,
      259. <Out> ByRef ppidl As IntPtr,
      260. <[In], Out, MarshalAs(UnmanagedType.U4)> ByVal pdwAttributes As UInteger) As Integer
      261. End Interface
      262. <ComImport, Guid("0000000E-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)>
      263. Interface IBindCtx
      264. End Interface
      265. #End Region
      266. #Region "CallBack Proc"
      267. Private Delegate Function BrowseCallbackProc(hwnd As IntPtr, uMsg As Integer, lParam As IntPtr, lpData As IntPtr) As Integer
      268. Private Function FolderBrowserDialog_BrowseCallbackProc(ByVal hwnd As IntPtr, ByVal msg As Integer,
      269. ByVal lParam As IntPtr, ByVal lpData As IntPtr) As Integer
      270. Select Case msg
      271. Case BFFM_INITIALIZED
      272. m_DialogInit = True
      273. If m_DialogText.Length <> 0 Then
      274. SetWindowText(hwnd, m_DialogText)
      275. End If
      276. If m_DialogOkButtonText.Length <> 0 Then
      277. SendMessageW(hwnd, BFFM_SETOKTEXT, 1, m_DialogOkButtonText)
      278. End If
      279. If m_DialogSelectedPath.Length <> 0 Then
      280. SendMessageW(hwnd, BFFM_SETSELECTIONW, 1, m_DialogSelectedPath)
      281. End If
      282. ' Optional, wenn BIF_NEWDIALOGSTYLE nicht verwendet wird
      283. If m_DialogUseNewStyle = False Then
      284. ' das TreeView
      285. Dim hwndTV As IntPtr = FindWindowEx(hwnd, IntPtr.Zero, "SysTreeView32", Nothing)
      286. If hwndTV <> IntPtr.Zero Then
      287. ' selektierten Node ermitteln
      288. Dim selectedNode As IntPtr = SendMessageW(hwndTV, TVM_GETNEXTITEM, TVGN_CARET, 0)
      289. If selectedNode <> IntPtr.Zero Then
      290. ' Node ausklappen oder nicht
      291. If m_ExpandSelectedPath = True Then
      292. SendMessageW(hwndTV, TVM_EXPAND, TVE_EXPAND, selectedNode)
      293. Else
      294. SendMessageW(hwndTV, TVM_EXPAND, TVE_COLLAPSE, selectedNode)
      295. End If
      296. End If
      297. ' Optional
      298. SetFocus(hwndTV)
      299. ' Optional, Node nach unten scrollen
      300. 'SendMessageW(hwndTV, WM_VSCROLL, SB_LINEUP, IntPtr.Zero)
      301. End If
      302. End If
      303. Case BFFM_SELCHANGED
      304. If lParam <> IntPtr.Zero Then
      305. Dim sRet As String = New String(Char.MinValue, MAX_PATH)
      306. Dim isFileSystemFolder As Boolean = SHGetPathFromIDListW(lParam, sRet)
      307. If isFileSystemFolder = True Then
      308. SendMessageW(hwnd, BFFM_ENABLEOK, 0, 1)
      309. Else
      310. SendMessageW(hwnd, BFFM_ENABLEOK, 0, 0)
      311. End If
      312. End If
      313. ' https://connect.microsoft.com/VisualStudio/feedback/details/518103/bffm-setselection-does-not-work-with-shbrowseforfolder-on-windows-7
      314. ' nach einen Hinweis von Karl E Peterson
      315. ' erst nach dem BFFM_INITIALIZED und sobalb ein Node selektiert wurde
      316. If m_DialogInit = True Then
      317. ' nur wenn BIF_NEWDIALOGSTYLE verwendet wird
      318. If m_DialogUseNewStyle = True Then
      319. If m_DialogSelectedPath.Length <> 0 Then
      320. SendMessageW(hwnd, BFFM_SETSELECTIONW, 1, m_DialogSelectedPath)
      321. End If
      322. ' bei BIF_NEWDIALOGSTYLE liegt das TreeView auf diesem Fenster
      323. Dim hwndDlg As IntPtr = FindWindowEx(hwnd, IntPtr.Zero, "SHBrowseForFolder ShellNameSpace Control", Nothing)
      324. If hwndDlg <> IntPtr.Zero Then
      325. ' das TreeView
      326. Dim hwndTV As IntPtr = FindWindowEx(hwndDlg, IntPtr.Zero, "SysTreeView32", Nothing)
      327. If hwndTV <> IntPtr.Zero Then
      328. ' selektierten Node ermitteln
      329. Dim selectedNode As IntPtr = SendMessageW(hwndTV, TVM_GETNEXTITEM, TVGN_CARET, 0)
      330. If selectedNode <> IntPtr.Zero Then
      331. ' TreeView-Item in den sichtbaren Bereich
      332. SendMessageW(hwndTV, TVM_ENSUREVISIBLE, 0, selectedNode)
      333. ' Node ausklappen oder nicht
      334. If m_ExpandSelectedPath = True Then
      335. SendMessageW(hwndTV, TVM_EXPAND, TVE_EXPAND, selectedNode)
      336. Else
      337. SendMessageW(hwndTV, TVM_EXPAND, TVE_COLLAPSE, selectedNode)
      338. End If
      339. End If
      340. ' Optional
      341. SetFocus(hwndTV)
      342. ' kleine Pause
      343. 'Threading.Thread.Sleep(25)
      344. ' Optional, Node nach oben scrollen
      345. 'PostMessageW(hwndTV, WM_VSCROLL, SB_LINEDOWN, IntPtr.Zero)
      346. End If
      347. End If
      348. End If
      349. m_DialogInit = False
      350. End If
      351. Case BFFM_VALIDATEFAILEDA 'SHBrowseForFolderA
      352. Dim failedSel As String = Marshal.PtrToStringAnsi(lParam)
      353. failedSel = "ungültiger Ordner '" & failedSel & "'"
      354. If m_DialogUseNewStyle = False Then
      355. SendMessageW(hwnd, BFFM_SETSTATUSTEXTA, 0, failedSel)
      356. Else
      357. ' bei BIF_NEWDIALOGSTYLE gibt es kein Static-Fenster wo
      358. ' die Ausgabe der Message erfolgenkann
      359. MsgBox(failedSel, MsgBoxStyle.Information Or MsgBoxStyle.OkOnly, "Ungültiger Ordner")
      360. End If
      361. Return 1
      362. Case BFFM_VALIDATEFAILEDW 'SHBrowseForFolderW
      363. Dim failedSel As String = Marshal.PtrToStringUni(lParam)
      364. failedSel = "ungültiger Ordner '" & failedSel & "'"
      365. If m_DialogUseNewStyle = False Then
      366. SendMessageW(hwnd, BFFM_SETSTATUSTEXTW, 0, failedSel)
      367. Else
      368. ' bei BIF_NEWDIALOGSTYLE gibt es kein Static-Fenster wo
      369. ' die Ausgabe der Message erfolgenkann
      370. MsgBox(failedSel, MsgBoxStyle.Information Or MsgBoxStyle.OkOnly, "Ungültiger Ordner")
      371. End If
      372. Return 1
      373. Case BFFM_IUNKNOWN
      374. 'On receipt of the BFFM_IUNKNOWN message, the callback function's lParam parameter contains
      375. 'a pointer to the dialog box's implementation of IUnknown. Call QueryInterface on that IUnknown
      376. 'to obtain a pointer to an instance of IFolderFilterSite. Create an object that implements IFolderFilter.
      377. 'Call IFolderFilterSite.SetFilter, passing to it a pointer to your IFolderFilter. IFolderFilter
      378. 'methods can then be used to include And exclude items from the tree. Once the filter Is created,
      379. 'the IFolderFilterSite interface Is no longer needed. Call IFolderFilterSite.Release If you have
      380. 'no further use for it.
      381. End Select
      382. Return 0
      383. End Function
      384. #End Region
      385. Private m_DialogText As String = String.Empty
      386. Private m_DialogOkButtonText As String = String.Empty
      387. Private m_DialogDisplayText As String = String.Empty
      388. Private m_DialogDescription As String = String.Empty
      389. Private m_DialogSelectedPath As String = String.Empty
      390. Private m_DialogRootFolderPidl As IntPtr = IntPtr.Zero
      391. Private m_DialogShowNewFolderButton As Boolean = True
      392. Private m_ExpandSelectedPath As Boolean = False
      393. Private m_DialogUseNewStyle As Boolean = False
      394. Private m_DialogInit As Boolean = False
      395. Private m_DialogFlags As eBrowseInfoFlags = eBrowseInfoFlags.BIF_RETURNONLYFSDIRS
      396. #Region "Properties"
      397. Public WriteOnly Property ExpandSelectedPath As Boolean
      398. Set(ByVal value As Boolean)
      399. m_ExpandSelectedPath = value
      400. End Set
      401. End Property
      402. Public WriteOnly Property DialogOkButtonText As String
      403. Set(ByVal value As String)
      404. m_DialogOkButtonText = value
      405. End Set
      406. End Property
      407. Public WriteOnly Property DialogText As String
      408. Set(ByVal value As String)
      409. m_DialogText = value
      410. End Set
      411. End Property
      412. Public WriteOnly Property BrowseInfoFlags As eBrowseInfoFlags
      413. Set(ByVal value As eBrowseInfoFlags)
      414. m_DialogFlags = value
      415. End Set
      416. End Property
      417. Public ReadOnly Property SelectedFolder As String
      418. Get
      419. Return m_DialogDisplayText
      420. End Get
      421. End Property
      422. Public WriteOnly Property Description As String
      423. Set(ByVal value As String)
      424. m_DialogDescription = value
      425. End Set
      426. End Property
      427. Public WriteOnly Property RootFolderByString As String
      428. Set(ByVal value As String)
      429. If m_DialogRootFolderPidl <> IntPtr.Zero Then
      430. ILFree(m_DialogRootFolderPidl)
      431. End If
      432. m_DialogRootFolderPidl = PathToAbsolutePIDL(IntPtr.Zero, value)
      433. End Set
      434. End Property
      435. Public WriteOnly Property RootFolderBySpecialFolder() As Environment.SpecialFolder
      436. Set(ByVal value As Environment.SpecialFolder)
      437. If m_DialogRootFolderPidl <> IntPtr.Zero Then
      438. ILFree(m_DialogRootFolderPidl)
      439. End If
      440. If SHGetSpecialFolderLocation(IntPtr.Zero, value, m_DialogRootFolderPidl) <> S_OK Then
      441. m_DialogRootFolderPidl = IntPtr.Zero
      442. End If
      443. End Set
      444. End Property
      445. Public WriteOnly Property RootFolderByKnownFolder() As eKnownFolderCSIDL
      446. Set(ByVal value As eKnownFolderCSIDL)
      447. If m_DialogRootFolderPidl <> IntPtr.Zero Then
      448. ILFree(m_DialogRootFolderPidl)
      449. End If
      450. If SHGetFolderLocation(IntPtr.Zero, value, IntPtr.Zero, 0, m_DialogRootFolderPidl) <> S_OK Then
      451. m_DialogRootFolderPidl = IntPtr.Zero
      452. End If
      453. End Set
      454. End Property
      455. Public Property SelectedPath As String
      456. Get
      457. Return m_DialogSelectedPath
      458. End Get
      459. Set(ByVal value As String)
      460. m_DialogSelectedPath = value
      461. End Set
      462. End Property
      463. Public WriteOnly Property ShowNewFolderButton As Boolean
      464. Set(ByVal value As Boolean)
      465. m_DialogShowNewFolderButton = value
      466. End Set
      467. End Property
      468. #End Region
      469. Public Overloads Function ShowDialog() As DialogResult
      470. Return Me.ShowDialog(Nothing)
      471. End Function
      472. Public Overloads Function ShowDialog(ByVal owner As IWin32Window) As DialogResult
      473. Dim bi As New BROWSEINFO
      474. Dim dlgResult As DialogResult
      475. Dim ownerHandle As IntPtr = IntPtr.Zero
      476. Dim callBack As New BrowseCallbackProc(AddressOf Me.FolderBrowserDialog_BrowseCallbackProc)
      477. If owner IsNot Nothing Then
      478. ownerHandle = owner.Handle
      479. End If
      480. If (m_DialogFlags And eBrowseInfoFlags.BIF_NEWDIALOGSTYLE) = eBrowseInfoFlags.BIF_NEWDIALOGSTYLE Then
      481. m_DialogUseNewStyle = True
      482. End If
      483. If m_DialogShowNewFolderButton = True Then
      484. If (m_DialogFlags And eBrowseInfoFlags.BIF_DONTSHOWNEWFOLDERBUTTON) = eBrowseInfoFlags.BIF_DONTSHOWNEWFOLDERBUTTON Then
      485. m_DialogFlags = m_DialogFlags Xor eBrowseInfoFlags.BIF_DONTSHOWNEWFOLDERBUTTON
      486. End If
      487. Else
      488. m_DialogFlags = m_DialogFlags Or eBrowseInfoFlags.BIF_DONTSHOWNEWFOLDERBUTTON
      489. End If
      490. With bi
      491. .hwndOwner = ownerHandle
      492. .pidlRoot = m_DialogRootFolderPidl
      493. .pszDisplayName = m_DialogDisplayText
      494. .lpszTitle = m_DialogDescription
      495. .ulFlags = m_DialogFlags
      496. .lpfn = callBack
      497. .lParam = IntPtr.Zero
      498. .iImage = 0
      499. End With
      500. Dim pidlSelectedPath As IntPtr = SHBrowseForFolderW(bi)
      501. If pidlSelectedPath <> IntPtr.Zero Then
      502. Dim sRet As String = New String(Char.MinValue, MAX_PATH)
      503. If SHGetPathFromIDListW(pidlSelectedPath, sRet) = True Then
      504. m_DialogSelectedPath = sRet.Trim(Char.MinValue)
      505. End If
      506. m_DialogDisplayText = bi.pszDisplayName
      507. dlgResult = DialogResult.OK
      508. Else
      509. dlgResult = DialogResult.Cancel
      510. End If
      511. If pidlSelectedPath <> IntPtr.Zero Then
      512. ILFree(pidlSelectedPath)
      513. End If
      514. If m_DialogRootFolderPidl <> IntPtr.Zero Then
      515. ILFree(m_DialogRootFolderPidl)
      516. End If
      517. callBack = Nothing
      518. Return dlgResult
      519. End Function
      520. Private Shared Function GetShellFolderChildrenRelativePIDL(ByVal hwnd As IntPtr,
      521. ByRef parentFolder As IShellFolder,
      522. ByVal displayName As String) As IntPtr
      523. Dim ppidl As IntPtr
      524. Dim bindCtx As IBindCtx
      525. If CreateBindCtx(0, bindCtx) = S_OK Then
      526. Dim pchEaten As UInteger
      527. Dim pdwAttributes As UInteger = 0
      528. If parentFolder.ParseDisplayName(hwnd, bindCtx, displayName, pchEaten, ppidl, pdwAttributes) = 0 Then
      529. Return ppidl
      530. End If
      531. End If
      532. End Function
      533. Private Shared Function PathToAbsolutePIDL(ByVal hwnd As IntPtr, ByVal path As String) As IntPtr
      534. Dim desktopFolder As IShellFolder
      535. If SHGetDesktopFolder(desktopFolder) = S_OK Then
      536. Return GetShellFolderChildrenRelativePIDL(hwnd, desktopFolder, path)
      537. End If
      538. End Function
      539. #Region "IDisposable Support"
      540. Private disposedValue As Boolean
      541. ' IDisposable
      542. Protected Overridable Sub Dispose(disposing As Boolean)
      543. If Not disposedValue Then
      544. If disposing Then
      545. ' TODO: verwalteten Zustand (verwaltete Objekte) entsorgen.
      546. End If
      547. ' TODO: nicht verwaltete Ressourcen (nicht verwaltete Objekte) freigeben und Finalize() weiter unten überschreiben.
      548. ' TODO: große Felder auf Null setzen.
      549. End If
      550. disposedValue = True
      551. End Sub
      552. ' TODO: Finalize() nur überschreiben, wenn Dispose(disposing As Boolean) weiter oben Code zur Bereinigung nicht verwalteter Ressourcen enthält.
      553. 'Protected Overrides Sub Finalize()
      554. ' ' Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in Dispose(disposing As Boolean) weiter oben ein.
      555. ' Dispose(False)
      556. ' MyBase.Finalize()
      557. 'End Sub
      558. ' Dieser Code wird von Visual Basic hinzugefügt, um das Dispose-Muster richtig zu implementieren.
      559. Public Sub Dispose() Implements IDisposable.Dispose
      560. ' Ändern Sie diesen Code nicht. Fügen Sie Bereinigungscode in Dispose(disposing As Boolean) weiter oben ein.
      561. Dispose(True)
      562. ' TODO: Auskommentierung der folgenden Zeile aufheben, wenn Finalize() oben überschrieben wird.
      563. ' GC.SuppressFinalize(Me)
      564. End Sub
      565. #End Region
      566. End Class
      567. Public Class Form1
      568. Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
      569. Using fbdEx As New FolderBrowseDialogEx
      570. fbdEx.BrowseInfoFlags = FolderBrowseDialogEx.eBrowseInfoFlags.BIF_RETURNONLYFSDIRS Or
      571. FolderBrowseDialogEx.eBrowseInfoFlags.BIF_UAHINT Or
      572. FolderBrowseDialogEx.eBrowseInfoFlags.BIF_STATUSTEXT Or
      573. FolderBrowseDialogEx.eBrowseInfoFlags.BIF_EDITBOX Or
      574. FolderBrowseDialogEx.eBrowseInfoFlags.BIF_VALIDATE Or
      575. FolderBrowseDialogEx.eBrowseInfoFlags.BIF_NEWDIALOGSTYLE
      576. 'fbdEx.RootFolderByString = "C:"
      577. 'fbdEx.RootFolderBySpecialFolder = Environment.SpecialFolder.MyComputer
      578. fbdEx.RootFolderByKnownFolder = FolderBrowseDialogEx.eKnownFolderCSIDL.CSIDL_DESKTOP
      579. fbdEx.SelectedPath = "C:\Windows"
      580. fbdEx.ExpandSelectedPath = True
      581. fbdEx.ShowNewFolderButton = True
      582. fbdEx.DialogText = "ein anderer Dialog-Fenstertext"
      583. fbdEx.Description = "eine zusätzliche Beschreibung"
      584. fbdEx.DialogOkButtonText = "1234567890" ' max. 10 Zeichen
      585. If fbdEx.ShowDialog(Me) = DialogResult.OK Then
      586. Debug.Print("SelectedPath: " & fbdEx.SelectedPath)
      587. Debug.Print("SelectedFolder: " & fbdEx.SelectedFolder)
      588. Else
      589. Debug.Print("NOK")
      590. End If
      591. End Using
      592. End Sub
      593. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
      594. FolderBrowserDialog1.Description = "Test"
      595. FolderBrowserDialog1.RootFolder = Environment.SpecialFolder.Desktop
      596. FolderBrowserDialog1.SelectedPath = "c:\windows"
      597. FolderBrowserDialog1.ShowNewFolderButton = True
      598. If FolderBrowserDialog1.ShowDialog(Me) = DialogResult.OK Then
      599. End If
      600. End Sub
      601. Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
      602. End Sub
      603. End Class

      Mfg -Franky-

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

      Guten Abend

      Früher gab es noch eine Textbox, wo man den Pfad reinkopieren oder herauskopieren konnte, was ich sehr praktisch fand.

      Mit der neuen Version muss man sich ständig zum Zielverzeichnis durchklicken. Find ich nicht so toll.

      Frag mich auch, warum man das rausnahm, war doch eine sehr sinnvolle Sache.

      Freundliche Grüsse

      exc-jdbi
      Moin moin @exc-jdbi

      exc-jdbi schrieb:

      Früher gab es noch eine Textbox, wo man den Pfad reinkopieren oder herauskopieren konnte, was ich sehr praktisch fand.

      Die gibt es immer noch. Siehe ScreenShot. Im Prinzip verhält sich der PickFolder-Dialog analog zum OpenFile-/SaveFile-Dialog oder wie der Explorer. Meiner Meinung nach ist das nur konsequent.

      Um es vllt etwas besser klarzustellen. MS empfiehlt den neuen PickFolder-Dialog zu verwenden, wahrscheinlich weil MS weis was sie da am alten Dialog verbrochen hat (bekannte Bugs), bedeutet aber nicht das man das nicht mehr darf. Die API SHBrowseForFolder ist ja noch nicht als deprecated gekennzeichnet.
      Bilder
      • PickFolder.png

        5,39 kB, 946×84, 128 mal angesehen
      Mfg -Franky-

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „-Franky-“ ()

      Hallo,

      ich habe den PickFolderDialog unter WPF am Laufen und wurde gebeten, meinen Code hier zu veröffentlichen.

      Es wurde nur DialogResult durch bool?, sowie DialogResult.OK und DialogResult.Cancel durch true und false ersetzt wie bei WPF eben notwendig. Andere Änderungen sind nicht erfolgt. Jetzt kann man auch DialogResult nachbauen, man kann es aber auch lassen.

      C#-Quellcode

      1. using System.Windows.Forms;
      wird natürlich auch überflüssig.

      Spoiler anzeigen

      C#-Quellcode

      1. using System;
      2. using System.ComponentModel;
      3. using System.Runtime.InteropServices;
      4. namespace PickFolderDialog
      5. {
      6. /// <summary>
      7. /// FolderBrowserDialog im Gewandt eines OpenFileDialogs
      8. /// </summary>
      9. [DesignerCategory("code")]
      10. public class PickFolderDialog
      11. : Component
      12. {
      13. #region Const
      14. // siehe Headerfile Winerror.h
      15. private const int S_OK = 0;
      16. // siehe Headerfile shobjidl_core.h
      17. private const string IID_IModalWindow = "b4db1657-70d7-485e-8e3e-6fcb5a5c1802";
      18. private const string IID_IFileDialog = "42f85136-db7e-439c-85f1-e4075d135fc8";
      19. private const string IID_IShellItem = "43826d1e-e718-42ee-bc55-a1e261c37bfe";
      20. private const string CLSID_FileOpenDialog = "dc1c5a9c-e88a-4dde-a5a1-60f82a20aef7";
      21. #endregion Const
      22. #region Enums
      23. // siehe Headerfile shobjidl_core.h
      24. private enum FileOpenDialogOptions : int
      25. {
      26. OverwritePrompt = 0x2,
      27. FOS_STRICTFILETYPES = 0x4,
      28. FOS_NOCHANGEDIR = 0x8,
      29. FOS_PICKFOLDERS = 0x20,
      30. FOS_FORCEFILESYSTEM = 0x40,
      31. FOS_ALLNONSTORAGEITEMS = 0x80,
      32. FOS_NOVALIDATE = 0x100,
      33. FOS_ALLOWMULTISELECT = 0x200,
      34. FOS_PATHMUSTEXIST = 0x800,
      35. FOS_FILEMUSTEXIST = 0x1000,
      36. FOS_CREATEPROMPT = 0x2000,
      37. FOS_SHAREAWARE = 0x4000,
      38. FOS_NOREADONLYRETURN = 0x8000,
      39. FOS_NOTESTFILECREATE = 0x10000,
      40. FOS_HIDEMRUPLACES = 0x20000,
      41. FOS_HIDEPINNEDPLACES = 0x40000,
      42. FOS_NODEREFERENCELINKS = 0x100000,
      43. FOS_OKBUTTONNEEDSINTERACTION = 0x200000,
      44. FOS_DONTADDTORECENT = 0x2000000,
      45. FOS_FORCESHOWHIDDEN = 0x10000000,
      46. FOS_DEFAULTNOMINIMODE = 0x20000000,
      47. FOS_FORCEPREVIEWPANEON = 0x40000000,
      48. FOS_SUPPORTSTREAMABLEITEMS = int.MinValue + 0x00000000
      49. }
      50. // siehe Headerfile shobjidl_core.h
      51. public enum SIGDN : int
      52. {
      53. SIGDN_NORMALDISPLAYField = 0x0,
      54. SIGDN_PARENTRELATIVEPARSINGField = int.MinValue + 0x00018001,
      55. SIGDN_DESKTOPABSOLUTEPARSINGField = int.MinValue + 0x00028000,
      56. SIGDN_PARENTRELATIVEEDITINGField = int.MinValue + 0x00031001,
      57. SIGDN_DESKTOPABSOLUTEEDITINGField = int.MinValue + 0x0004C000,
      58. SIGDN_FILESYSPATHField = int.MinValue + 0x00058000,
      59. SIGDN_URLField = int.MinValue + 0x00068000,
      60. SIGDN_PARENTRELATIVEFORADDRESSBARField = int.MinValue + 0x0007C001,
      61. SIGDN_PARENTRELATIVEField = int.MinValue + 0x00080001,
      62. SIGDN_PARENTRELATIVEFORUIField = int.MinValue + 0x00094001
      63. }
      64. #endregion Enums
      65. #region Member
      66. /// <summary>
      67. /// COM-Instanz des Dialogs
      68. /// </summary>
      69. private IFileDialog FileDialog;
      70. #endregion Member
      71. #region API
      72. // siehe https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-shcreateitemfromparsingname
      73. // oder Headerfile shobjidl_core.h
      74. [DllImport("Shell32.dll", EntryPoint = "SHCreateItemFromParsingName")]
      75. [PreserveSig]
      76. private static extern int SHCreateItemFromParsingName([In][MarshalAs(UnmanagedType.LPWStr)] string pszPath, [In] IntPtr pbc, [In][MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IntPtr pUnk);
      77. #endregion
      78. #region Properties
      79. /// <summary>
      80. /// Gets or sets the path selected by the user.
      81. /// Wird nichts angegeben: "Dieser PC"
      82. /// </summary>
      83. public string SelectedPath { get; set; }
      84. #endregion Properties
      85. #region Konstruktor
      86. public PickFolderDialog()
      87. {
      88. FileOpenDialogOptions options;
      89. this.FileDialog = (IFileDialog)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid(CLSID_FileOpenDialog)));
      90. if (this.FileDialog == null)
      91. {
      92. throw new COMException("PickFolderDialog constructor failed.");
      93. }
      94. if (this.FileDialog.GetOptions(out options) == S_OK)
      95. {
      96. options |= FileOpenDialogOptions.FOS_PICKFOLDERS;
      97. this.FileDialog.SetOptions(options);
      98. }
      99. }
      100. #endregion Konstruktor
      101. #region Public Functions
      102. public bool? ShowDialog(IntPtr hwndOwner)
      103. {
      104. this.SetFolder(this.SelectedPath);
      105. if (this.FileDialog.Show(hwndOwner) == S_OK)
      106. {
      107. this.SelectedPath = this.GetResult(PickFolderDialog.SIGDN.SIGDN_FILESYSPATHField);
      108. return true; // DialogResult.OK;
      109. }
      110. return false; // DialogResult.Cancel;
      111. }
      112. public string GetResult(SIGDN eSIGDN = SIGDN.SIGDN_FILESYSPATHField)
      113. {
      114. string strRet = string.Empty;
      115. if (this.FileDialog.GetResult(out IShellItem ShellItem) == S_OK)
      116. {
      117. if (ShellItem.GetDisplayName(eSIGDN, out IntPtr pszName) == S_OK)
      118. {
      119. strRet = Marshal.PtrToStringUni(pszName);
      120. Marshal.FreeCoTaskMem(pszName);
      121. }
      122. Marshal.ReleaseComObject(ShellItem);
      123. }
      124. return strRet;
      125. }
      126. #endregion Public Functions
      127. #region Private Functions
      128. private bool SetFolder(string folder)
      129. {
      130. // Wird bei Dialog.SetFolder nichts angegeben = Dieser PC
      131. // Ansonsten z.B. "C:" oder "C:\" = Laufwerk C:
      132. // "C:\Users" oder "C:\Users\" = Ordner Users auf Laufwerk C:
      133. // "::{645FF040-5081-101B-9F08-00AA002F954E}" = Papierkorb
      134. // "::{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}" = Netzwerk
      135. // "::{031E4825-7B94-4DC3-B131-E946B44C8DD5}" = Bibliotheken
      136. // usw.
      137. bool retval = false;
      138. IntPtr item;
      139. if (folder is null)
      140. {
      141. // C-String-Ende-Kennung
      142. folder = "\0";
      143. }
      144. if (SHCreateItemFromParsingName(folder, IntPtr.Zero, new Guid(IID_IShellItem), out item) == S_OK)
      145. {
      146. if (this.FileDialog.SetFolder(item) == S_OK)
      147. {
      148. retval = true;
      149. }
      150. Marshal.Release(item);
      151. }
      152. return retval;
      153. }
      154. #endregion Private Functions
      155. #region Interface IModalWindow
      156. // siehe Headerfile shobjidl_core.h
      157. [ComImport]
      158. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      159. [Guid(IID_IModalWindow)]
      160. private interface IModalWindow
      161. {
      162. // virtual /* [local] */ HRESULT STDMETHODCALLTYPE Show(
      163. // /* [annotation][unique][in] */
      164. // _In_opt_ HWND hwndOwner) = 0;
      165. [PreserveSig]
      166. int Show([In] IntPtr hwndOwner);
      167. }
      168. #endregion
      169. #region Interface IFileDialog
      170. // siehe Headerfile shobjidl_core.h
      171. [ComImport]
      172. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      173. [Guid(IID_IFileDialog)]
      174. private interface IFileDialog : IModalWindow
      175. {
      176. [PreserveSig]
      177. new int Show([In] IntPtr hwndOwner);
      178. // virtual HRESULT STDMETHODCALLTYPE SetFileTypes(
      179. // /* [in] */ UINT cFileTypes,
      180. // /* [size_is][in] */ __RPC__in_ecount_full(cFileTypes) const COMDLG_FILTERSPEC *rgFilterSpec) = 0;
      181. [PreserveSig]
      182. int SetFileTypes();
      183. // virtual HRESULT STDMETHODCALLTYPE SetFileTypeIndex(
      184. // /* [in] */ UINT iFileType) = 0;
      185. [PreserveSig]
      186. int SetFileTypeIndex();
      187. // virtual HRESULT STDMETHODCALLTYPE GetFileTypeIndex(
      188. // /* [out] */ __RPC__out UINT *piFileType) = 0;
      189. [PreserveSig]
      190. int GetFileTypeIndex();
      191. // virtual HRESULT STDMETHODCALLTYPE Advise(
      192. // /* [in] */ __RPC__in_opt IFileDialogEvents *pfde,
      193. // /* [out] */ __RPC__out DWORD *pdwCookie) = 0;
      194. [PreserveSig]
      195. int Advise();
      196. // virtual HRESULT STDMETHODCALLTYPE Unadvise(
      197. // /* [in] */ DWORD dwCookie) = 0;
      198. [PreserveSig]
      199. int Unadvise();
      200. // virtual HRESULT STDMETHODCALLTYPE SetOptions(
      201. // /* [in] */ FILEOPENDIALOGOPTIONS fos) = 0;
      202. [PreserveSig]
      203. int SetOptions([In] FileOpenDialogOptions fos);
      204. // virtual HRESULT STDMETHODCALLTYPE GetOptions(
      205. // /* [out] */ __RPC__out FILEOPENDIALOGOPTIONS *pfos) = 0;
      206. [PreserveSig]
      207. int GetOptions(out FileOpenDialogOptions pfos);
      208. // virtual HRESULT STDMETHODCALLTYPE SetDefaultFolder(
      209. // /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      210. [PreserveSig]
      211. int SetDefaultFolder();
      212. // virtual HRESULT STDMETHODCALLTYPE SetFolder(
      213. // /* [in] */ __RPC__in_opt IShellItem *psi) = 0;
      214. [PreserveSig]
      215. int SetFolder([In] IntPtr psi);
      216. // virtual HRESULT STDMETHODCALLTYPE GetFolder(
      217. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      218. [PreserveSig]
      219. int GetFolder();
      220. // virtual HRESULT STDMETHODCALLTYPE GetCurrentSelection(
      221. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      222. [PreserveSig]
      223. int GetCurrentSelection();
      224. // virtual HRESULT STDMETHODCALLTYPE SetFileName(
      225. // /* [string][in] */ __RPC__in_string LPCWSTR pszName) = 0;
      226. [PreserveSig]
      227. int SetFileName();
      228. // virtual HRESULT STDMETHODCALLTYPE GetFileName(
      229. // /* [string][out] */ __RPC__deref_out_opt_string LPWSTR *pszName) = 0;
      230. [PreserveSig]
      231. int GetFileName();
      232. // virtual HRESULT STDMETHODCALLTYPE SetTitle(
      233. // /* [string][in] */ __RPC__in_string LPCWSTR pszTitle) = 0;
      234. [PreserveSig]
      235. int SetTitle();
      236. // virtual HRESULT STDMETHODCALLTYPE SetOkButtonLabel(
      237. // /* [string][in] */ __RPC__in_string LPCWSTR pszText) = 0;
      238. [PreserveSig]
      239. int SetOkButtonLabel();
      240. // virtual HRESULT STDMETHODCALLTYPE SetFileNameLabel(
      241. // /* [string][in] */ __RPC__in_string LPCWSTR pszLabel) = 0;
      242. [PreserveSig]
      243. int SetFileNameLabel();
      244. // virtual HRESULT STDMETHODCALLTYPE GetResult(
      245. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      246. [PreserveSig]
      247. int GetResult([MarshalAs(UnmanagedType.Interface)] out IShellItem ppsi);
      248. // virtual HRESULT STDMETHODCALLTYPE AddPlace(
      249. // /* [in] */ __RPC__in_opt IShellItem *psi,
      250. // /* [in] */ FDAP fdap) = 0;
      251. [PreserveSig]
      252. int AddPlace();
      253. // virtual HRESULT STDMETHODCALLTYPE SetDefaultExtension(
      254. // /* [string][in] */ __RPC__in_string LPCWSTR pszDefaultExtension) = 0;
      255. [PreserveSig]
      256. int SetDefaultExtension();
      257. // virtual HRESULT STDMETHODCALLTYPE Close(
      258. // /* [in] */ HRESULT hr) = 0;
      259. [PreserveSig]
      260. int Close();
      261. // virtual HRESULT STDMETHODCALLTYPE SetClientGuid(
      262. // /* [in] */ __RPC__in REFGUID guid) = 0;
      263. [PreserveSig]
      264. int SetClientGuid();
      265. // virtual HRESULT STDMETHODCALLTYPE ClearClientData( void) = 0;
      266. [PreserveSig]
      267. int ClearClientData();
      268. // virtual HRESULT STDMETHODCALLTYPE SetFilter(
      269. // /* [in] */ __RPC__in_opt IShellItemFilter *pFilter) = 0;
      270. [PreserveSig]
      271. int SetFilter();
      272. }
      273. #endregion
      274. #region Interface IShellItem
      275. // siehe Headerfile shobjidl_core.h
      276. [ComImport]
      277. [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
      278. [Guid(IID_IShellItem)]
      279. private interface IShellItem
      280. {
      281. // virtual HRESULT STDMETHODCALLTYPE BindToHandler(
      282. // /* [unique][in] */ __RPC__in_opt IBindCtx *pbc,
      283. // /* [in] */ __RPC__in REFGUID bhid,
      284. // /* [in] */ __RPC__in REFIID riid,
      285. // /* [iid_is][out] */ __RPC__deref_out_opt void **ppv) = 0;
      286. [PreserveSig]
      287. int BindToHandler();
      288. // virtual HRESULT STDMETHODCALLTYPE GetParent(
      289. // /* [out] */ __RPC__deref_out_opt IShellItem **ppsi) = 0;
      290. [PreserveSig]
      291. int GetParent();
      292. // virtual HRESULT STDMETHODCALLTYPE GetDisplayName(
      293. // /* [in] */ SIGDN sigdnName,
      294. // /* [annotation][string][out] */
      295. // _Outptr_result_nullonfailure_ LPWSTR *ppszName) = 0;
      296. [PreserveSig]
      297. int GetDisplayName([In] SIGDN sigdnName, out IntPtr ppszName);
      298. // virtual HRESULT STDMETHODCALLTYPE GetAttributes(
      299. // /* [in] */ SFGAOF sfgaoMask,
      300. // /* [out] */ __RPC__out SFGAOF *psfgaoAttribs) = 0;
      301. [PreserveSig]
      302. int GetAttributes();
      303. // virtual HRESULT STDMETHODCALLTYPE Compare(
      304. // /* [in] */ __RPC__in_opt IShellItem *psi,
      305. // /* [in] */ SICHINTF hint,
      306. // /* [out] */ __RPC__out int *piOrder) = 0;
      307. [PreserveSig]
      308. int Compare();
      309. }
      310. #endregion
      311. #region Dispose
      312. protected override void Dispose(bool disposing)
      313. {
      314. if (this.FileDialog != null)
      315. {
      316. Marshal.ReleaseComObject(this.FileDialog);
      317. this.FileDialog = null;
      318. }
      319. base.Dispose(disposing);
      320. }
      321. #endregion Dispose
      322. }
      323. }


      Gruß

      MQ