internal static extern int SHBrowseForFolder([In] BROWSEINFO lpbi);
internal DialogResult ShowDialog() { IWin32Window owner = null; int[] pidlRoot = new int[1]; // Get/find an owner HWND for this dialog IntPtr hwndOwner; if (owner != null) { hwndOwner = owner.Handle; } else { hwndOwner = GetActiveWindow(); } // Get the IDL for the specific startLocation Shell32.SHGetSpecialFolderLocation(hwndOwner, (int)startLocation, pidlRoot); if (pidlRoot[0] == 0) { // UNDONE, fabioy: // Show we throw an exception here instead? return(DialogResult.Cancel); } int mergedOptions = (int)publicOptions | (int)privateOptions; // UNDONE, fabioy: // Expose the display name as another property. int pidlRet = 0; try { // Construct a BROWSEINFO BROWSEINFO bi = new BROWSEINFO(); IntPtr buffer = (IntPtr)Marshal.AllocHGlobal(MAX_PATH); bi.pidlRoot = pidlRoot[0]; bi.hwndOwner = hwndOwner; bi.pszDisplayName = buffer; bi.lpszTitle = descriptionText; bi.ulFlags = mergedOptions; bi.lpfn = (IntPtr)0; bi.lParam = 0; bi.iImage = (IntPtr)0; // And show the dialog pidlRet = Shell32.SHBrowseForFolder(bi); if (pidlRet == 0) { // User pressed Cancel return(DialogResult.Cancel); } // Then retrieve the path from the IDList //Shell32.SHGetPathFromIDList(pidlRet, buffer); // Convert to a string directoryPath = Marshal.PtrToStringUni(buffer); // Then free all the stuff we've allocated or the SH API gave us Marshal.FreeHGlobal(buffer); } finally { IMalloc malloc = GetSHMalloc(); malloc.Free(pidlRoot[0]); if (pidlRet != 0) { malloc.Free(pidlRet); } } return(DialogResult.OK); }