FileDialog(msoFileDialogFolderPicker) - how to set initial path to "root" / "This PC"?
Asked Answered
Y

1

7

If .InitialFileName isn't set, the "Select Folder" dialog FileDialog(msoFileDialogFolderPicker) uses the current directory of the application.

Is there any way to force the dialog to the "root" folder in Windows explorer ("This PC" in Windows 10, "My Computer" in earlier versions) ?


Public Function GetFolderName(InitPath As String) As String

    With Application.FileDialog(msoFileDialogFolderPicker)

        If InitPath <> "" Then
            If Right$(InitPath, 1) <> "\" Then
                InitPath = InitPath & "\"
            End If
            .InitialFileName = InitPath
        Else
            .InitialFileName = ""   ' <-- What can I put here to start at "This PC" ?
        End If
        
        If .Show() = True Then
            If .SelectedItems.Count > 0 Then
                GetFolderName = .SelectedItems(1)
            End If
        End If

    End With

End Function

Shell.Application.BrowseForFolder uses the magic number 17 to specify this:

? CreateObject("Shell.Application").BrowseForFolder(0, "", &H11, 17).Self.Path

I don't like to use BrowseForFolder, because if an initial folder is specified, the user is limited to this folder and below.

Your answered 18/2, 2021 at 16:9 Comment(8)
Not sure it can be done in VBA since 'My PC' is not really a directory to be passed to the .InitialFileName string. How about a hybrid solution where you pick the dialog based on the supplied initial path? If empty, show one else the other.Exaltation
Yes, I'm afraid you are right. The hybrid solution is actually an interesting idea - although it might confuse some users.Your
The magic 17 is ssfDRIVES of the ShellSpecialFolderConstants.Goop
Hmmm... As said in a deleted comment, this unfortunately requires Common Item Dialog code, and can't work with old CommonDialog code, on which Application.FileDialog is based. Common Item Dialog is COM code, but doesn't implement IDispatch, which causes a major problem (context), and working around that requires messing with vtables or reverse engineering the TLB (resource). The sensible approach is to create a COM object in C#.Tareyn
Why not just use C:\ ?Autotomize
Because this selects and expands the C: drive, but users need to select a path on one of several network drives. So "This PC" is the best starting point. @AutotomizeYour
Does this answer your question? VBA: Get Excel FileDialogOpen to point to "My Computer" by defaultAutotomize
It's indeed quite similar, but focuses on file dialogs, not folders. @AutotomizeYour
Y
2

So apparently this is not possible with Application.FileDialog.

I applied Kostas' suggestion and implemented both methods (FileDialog and Shell.BrowseForFolder) in one function, depending on whether an initial path is passed to it.

See inline comments. This is my final version.

Public Function GetFolderName(sCaption As String, InitPath As String) As String

    Dim sPath As String
    
    ' "Hybrid" approach:
    ' If InitPath is set, use Application.FileDialog because it's more convenient for the user.
    ' If not, we want to open the Folder dialog at "This PC", which is not possible with Application.FileDialog
    '   => then use Shell.Application.BrowseForFolder
    
    If InitPath <> "" Then
    
        With Application.FileDialog(msoFileDialogFolderPicker)
        
            .Title = sCaption
            ' FileDialog needs the init path to end with \ or it will select the parent folder
            If Right$(InitPath, 1) <> "\" Then
                InitPath = InitPath & "\"
            End If
            .InitialFileName = InitPath
            
            If .Show() = True Then
                If .SelectedItems.Count > 0 Then
                    sPath = .SelectedItems(1)
                End If
            End If
            
        End With
        
    Else
        
        ' https://ss64.com/vb/browseforfolder.html  has all the flags and constants
        Const BIF_RETURNONLYFSDIRS = &H1    ' default
        Const BIF_EDITBOX = &H10            ' allow users to paste a path e.g. from Explorer
        Const BIF_NONEWFOLDER = &H200       ' use this if users shouldn't be able to create folders from this dialog

        Dim oShell As Object
        Dim oFolder As Object

        Set oShell = CreateObject("Shell.Application")
        ' 17 = ssfDRIVES  is "This PC"
        Set oFolder = oShell.BrowseForFolder(0, sCaption, BIF_RETURNONLYFSDIRS + BIF_EDITBOX, 17)
        
        If Not oFolder Is Nothing Then
            ' .Self gets FolderItem from Folder object
            ' https://devblogs.microsoft.com/scripting/how-can-i-show-users-a-dialog-box-that-only-lets-them-select-folders/
            sPath = oFolder.Self.Path
            
            If Left$(sPath, 2) = "::" Then
                sPath = ""       ' User tricked the dialog into returning a GUID - invalid!
            End If
        End If
        
    End If
    
    GetFolderName = sPath

End Function
Your answered 19/2, 2021 at 16:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.