none
Setting Root Folder in FolderBrowserDialog RRS feed

  • Question

  • I want to set the RootFolder to a "Master" folder that the user has already selected, but the RootFolder expects an Environment,SpecialFolder, which is an enum (integer).
    Option Strict On wants to cast it but that fails ("FBD" is a FolderBrowserDialog)

                'Original
                If Directory.Exists(MasterFolder) Then
                    FBD.RootFolder = MasterFolder
                End If
                'Opt Strict changes
                If Directory.Exists(MasterFolder) Then
                    FBD.RootFolder = CType(MasterFolder, Environment.SpecialFolder)
                End If

    When I run the program, it halts there with this exception:
    System.InvalidCastException
      HResult=0x80004002
      Message=Conversion from string "C:\Users\devon\source\repos" to type 'Integer' is not valid.
      Inner Exception 1:
      FormatException: Input string was not in a correct format.

    Is there any way to fix this? I am setting the FBD.SelectedPath but it's not 100% what I want.

    There is no Environment.Special folder for the Visual Studio source repository, in my case that is
    C:\users\devon\source\repos


    Wednesday, October 9, 2019 4:52 PM

Answers

  • Ah yes, I forgot HRESULT

    It can be defined :

        Public Enum HRESULT As Integer
            S_OK = 0
            S_FALSE = 1
            E_NOINTERFACE = &H80004002
            E_NOTIMPL = &H80004001
            E_FAIL = &H80004005
            E_UNEXPECTED = &H8000FFFF
            E_OUTOFMEMORY = &H8007000E
        End Enum

    For BROWSEINFO.pidlRoot,the doc says :

    "Only the specified folder and its subfolders in the namespace hierarchy appear in the dialog box. "


    • Edited by Castorix31 Wednesday, October 9, 2019 6:51 PM
    • Marked as answer by Devon_Nullman Wednesday, October 9, 2019 11:03 PM
    Wednesday, October 9, 2019 6:51 PM

All replies

  • Hi

    Try this out - may help

    	Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    		Dim fbd As New FolderBrowserDialog
    
    		If IO.Directory.Exists(MasterFolder) Then
    			fbd.SelectedPath = MasterFolder
    		End If
    
    		If fbd.ShowDialog = DialogResult.OK Then
    			MasterFolder = fbd.SelectedPath
    			' do something with selected folder
    		End If
    	End Sub
    

    :


    Regards Les, Livingston, Scotland

    Wednesday, October 9, 2019 5:15 PM
  • You can use SHBrowseForFolder with BROWSEINFO.pidlRoot

    For example :

    Dim pidlFull As IntPtr = IntPtr.Zero, pidlRet = IntPtr.Zero
    Dim nlnOut As UInteger = 0
    Dim hr As HRESULT = HRESULT.E_FAIL
    Dim sPath As String = "e:\temp"
    hr = SHILCreateFromPath(sPath, pidlFull, nlnOut)
    If (hr = HRESULT.S_OK) Then
        Dim bi As BROWSEINFO = New BROWSEINFO()
        bi.pidlRoot = pidlFull
        bi.hwndOwner = Me.Handle
        bi.ulFlags = BIF_NEWDIALOGSTYLE
        pidlRet = SHBrowseForFolder(bi)
        If (pidlRet <> IntPtr.Zero) Then
            Dim pszSelectedPath As IntPtr = IntPtr.Zero
            pszSelectedPath = Marshal.AllocHGlobal(((260 + 1) * Marshal.SystemDefaultCharSize))
            SHGetPathFromIDList(pidlRet, pszSelectedPath)
            Dim sSelectedPath As String = Nothing
            sSelectedPath = Marshal.PtrToStringAuto(pszSelectedPath)
            Marshal.FreeHGlobal(pszSelectedPath)
        End If
    End If

    With declarations :

        Public Delegate Function BrowseCallbackProc(ByVal hwnd As IntPtr, ByVal msg As Integer, ByVal lParam As IntPtr, ByVal lpData As IntPtr) As Integer
    
        <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Auto)>
        Public Class BROWSEINFO
            Public hwndOwner As IntPtr
            Public pidlRoot As IntPtr
            Public pszDisplayName As IntPtr
            Public lpszTitle As String
            Public ulFlags As Integer
            Public lpfn As BrowseCallbackProc
            Public lParam As IntPtr
            Public iImage As Integer
        End Class
    
        <DllImport("Shell32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)>
        Public Shared Function SHBrowseForFolder(<[In]> ByVal lpbi As BROWSEINFO) As IntPtr
        End Function
    
        Public Const BIF_RETURNONLYFSDIRS = &H1 ' For finding a folder to start document searching
        Public Const BIF_DONTGOBELOWDOMAIN = &H2 ' For starting the Find Computer
        Public Const BIF_STATUSTEXT = &H4  ' Top of the dialog has 2 lines of text for BROWSEINFO.lpszTitle and one line if
        ' this flag is set.  Passing the message BFFM_SETSTATUSTEXTA to the hwnd can set the
        ' rest of the text.  This is not used with BIF_USENEWUI and BROWSEINFO.lpszTitle gets
        ' all three lines of text.
        Public Const BIF_RETURNFSANCESTORS = &H8
        Public Const BIF_EDITBOX = &H10  ' Add an editbox to the dialog
        Public Const BIF_VALIDATE = &H20  ' insist on valid result (or CANCEL)
    
        Public Const BIF_NEWDIALOGSTYLE = &H40  ' Use the new dialog layout with the ability to resize
        ' Caller needs to call OleInitialize() before using this API
    
        Public Const BIF_USENEWUI = (BIF_NEWDIALOGSTYLE Or BIF_EDITBOX)
    
        Public Const BIF_BROWSEINCLUDEURLS = &H80  ' Allow URLs to be displayed or entered. (Requires BIF_USENEWUI)
        Public Const BIF_UAHINT = &H100  ' Add a UA hint to the dialog, in place of the edit box. May not be combined with BIF_EDITBOX
        Public Const BIF_NONEWFOLDERBUTTON = &H200  ' Do not add the "New Folder" button to the dialog.  Only applicable with BIF_NEWDIALOGSTYLE.
        Public Const BIF_NOTRANSLATETARGETS = &H400  ' don't traverse target as shortcut
    
        Public Const BIF_BROWSEFORCOMPUTER = &H1000 ' Browsing for Computers.
        Public Const BIF_BROWSEFORPRINTER = &H2000 ' Browsing for Printers
        Public Const BIF_BROWSEINCLUDEFILES = &H4000 ' Browsing for Everything
        Public Const BIF_SHAREABLE = &H8000 ' sharable resources displayed (remote shares, requires BIF_USENEWUI)
        Public Const BIF_BROWSEFILEJUNCTIONS = &H10000 ' allow folder junctions like zip files and libraries to be browsed  
    
        <DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
        Public Shared Function SHILCreateFromPath(ByVal pszPath As String, ByRef ppIdl As IntPtr, ByRef rgflnOut As UInteger) As HRESULT
        End Function
    
        <DllImport("Shell32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)>
        Public Shared Function SHGetPathFromIDList(ByVal pidl As IntPtr, ByVal pszPath As IntPtr) As Boolean
        End Function


    Wednesday, October 9, 2019 5:35 PM
  • That's what I have for now, what I don't like is that the selected folder doesn't show in the dialog unless I scroll a long ways.
    Wednesday, October 9, 2019 5:37 PM
  • Nice - I wasn't able to use the HRESULT at all. Could not find any reference at all. Changed it to IntPrt and it does work.

    Also it seems like it restricts the user to the initial folder and its subfolders, nothing above the initial folder is shown.


    Wednesday, October 9, 2019 6:38 PM
  • Ah yes, I forgot HRESULT

    It can be defined :

        Public Enum HRESULT As Integer
            S_OK = 0
            S_FALSE = 1
            E_NOINTERFACE = &H80004002
            E_NOTIMPL = &H80004001
            E_FAIL = &H80004005
            E_UNEXPECTED = &H8000FFFF
            E_OUTOFMEMORY = &H8007000E
        End Enum

    For BROWSEINFO.pidlRoot,the doc says :

    "Only the specified folder and its subfolders in the namespace hierarchy appear in the dialog box. "


    • Edited by Castorix31 Wednesday, October 9, 2019 6:51 PM
    • Marked as answer by Devon_Nullman Wednesday, October 9, 2019 11:03 PM
    Wednesday, October 9, 2019 6:51 PM
  • Deleted
    Wednesday, October 9, 2019 6:56 PM
  • I'm not understanding how that fits into my question, sorry. It returns a String and the FolderBrowser wants an Integer(Emum Index)

    Wednesday, October 9, 2019 7:41 PM
  • Thanks for that, I am saving all that for a possible future use.

    Wednesday, October 9, 2019 8:25 PM
  • Deleted
    Wednesday, October 9, 2019 8:38 PM