Allow user to select a directory

In my VB6.0 app I have used CommonDialog boxes to allow users to select a particular file to take action on.  I have added new functionailty to the app and I now want the user to select a directory on their local drive.  I will place some app related files in the directory they choose.

I tried doing this with CommonDialog but it doesn't stop at the directory level, it wants the user to enter or select a file name.  Is there a parameter to allow the user to select a directory in the CommonDialog?

I noticed DirListBox and thought it might be the one but it seems very limited in what it displays.  It doesn't show the entire local drive, only some directories relative to where the app is running.  There doesn't seem to be any built in mechanism for going up the directory structure.  Also I couldn't figure how the app knows which directory the user clicked on.

Any help gettiing either of these controls (or another control) to function as I want would be greatly appreciated.

I suspect i could do this by loading the directory structure into a 'treeview' control but I'm hoping there is a more efficient (less coding) way of getting this done.

Who is Participating?
mvidasConnect With a Mentor Commented:

If less code is what you're looking for:

 Dim ShellApp As Object, shFolder As Object, folderName As String
 Set ShellApp = CreateObject("Shell.Application")
 Set shFolder = ShellApp.BrowseForFolder(0, "Select Folder to Save Output File", 0, "")
 If shFolder Is Nothing Then WScript.Quit
 Set shFolderItem = shFolder.Items.Item
 folderName = shFolderItem.path
 MsgBox folderName

However, if you want to be able to customize it, etc, take a look at the following:

'Only return computers. If the user selects anything other than a computer, the
'OK button is grayed.

'Only return printers. If the user selects anything
'other than a printer, the OK button is grayed.

'The browse dialog will display files as well as folders.

'Do not include network folders below the domain level in the tree view control.

'Include an edit control in the dialog box.
Private Const BIF_EDITBOX = &H10

'Use the new user-interface providing the user with a larger resizable dialog box
'which includes drag and drop, reordering, context menus, new folders, delete, and
'other context menu commands.

'Only return file system ancestors. If the user selects anything other than a file
'system ancestor, the OK button is grayed.

'Only return file system directories. If the user selects folders that are not part
'of the file system, the OK button is grayed.

'Include a status area in the dialog box. The callback function can set the status
'text by sending messages to the dialog box.
Private Const BIF_STATUSTEXT = &H4

 hOwner As Long
 pidlRoot As Long
 pszDisplayName As String
 lpszTitle As String
 ulFlags As Long
 lpfn As Long
 lParam As Long
 iImage As Long
End Type
Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" _
 (ByVal pidl As Long, ByVal pszPath As String) As Long
Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" _
 (lpBrowseInfo As BROWSEINFO) As Long
Option Explicit
Public Function GetDirectory(Optional Msg) As String
 Dim bInfo As BROWSEINFO, path As String, R As Long, X As Long, pos As Integer
 bInfo.pidlRoot = 0&
 If IsMissing(Msg) Then
  bInfo.lpszTitle = "Select a folder."
  bInfo.lpszTitle = Msg
 End If
 bInfo.ulFlags = &H51 'use hex or constants
 X = SHBrowseForFolder(bInfo)
 path = Space$(512)
 R = SHGetPathFromIDList(ByVal X, ByVal path)
 If R Then pos = InStr(path, Chr$(0)): GetDirectory = Left$(path, pos - 1)
End Function
Sub ExampleSubForGetDirectory()
 Debug.Print GetDirectory("hi")
End Sub

Option Explicit

Private Declare Function SHBrowseForFolder Lib "shell32" Alias "SHBrowseForFolderA" (lpbi As BrowseInfo) As Long

Private Type BrowseInfo
    hWndOwner As Long
    pIDLRoot As Long
    pszDisplayName As Long
    lpszTitle As String
    ulFlags As Long
    lpfnCallback As Long
    lParam As Long
    iImage As Long
End Type

Private Declare Function SHGetPathFromIDList Lib "shell32" (ByVal pidList As Long, ByVal lpBuffer As String) As Long
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMem As Long)

Private Sub Form_Load()

    SelectDir "Select a dir"

End Sub

Private Function SelectDir(Optional Title As String) As String
    Dim iNull As Integer, lpIDList As Long
    Dim sPath As String, udtBI As BrowseInfo
    With udtBI
        'Set the owner window
        .hWndOwner = Me.hWnd
        'lstrcat appends the two strings and returns the memory address
        .lpszTitle = Title
        'Return only if the user selected a directory
    End With
    lpIDList = SHBrowseForFolder(udtBI)
    If lpIDList Then
        sPath = String$(1024, 0)
        'Get the path from the IDList
        SHGetPathFromIDList lpIDList, sPath
        'free the block of memory
        CoTaskMemFree lpIDList
        iNull = InStr(sPath, vbNullChar)
        If iNull Then
            SelectDir = Left$(sPath, iNull - 1)
        End If
    End If
End Function
mlcktmguyAuthor Commented:
I am trying the suggestions in order.

mvidas , i tried your first suggestion that uses a minimum of code

I get a 'Variable not defined' compile error on the statement:

 If shFolder Is Nothing Then WScript.Quit

WScript is highlighted
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.


I'm sorry, I copied that from a vbscript file I have, where wscript.quit is used to exit the script.  Replace the line with

 If shFolder Is Nothing Then Exit Sub

Change 'sub' to 'function' as needed.
mlcktmguyAuthor Commented:
That got me past that statement.  Now I am getting the same error on:

 Set shFolderItem = shFolder.Items.Item

shFolderItem is higlighted
I'm doing 0 for 2 here! Very sorry

Add to the Dim statement:

 Dim ShellApp As Object, shFolder As Object, folderName As String, shFolderItem As Object

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.