Allow user to select a directory

Posted on 2006-11-02
Medium Priority
Last Modified: 2010-04-30
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.

Question by:mlcktmguy
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
LVL 35

Accepted Solution

mvidas earned 1000 total points
ID: 17860616

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

LVL 13

Expert Comment

ID: 17860637
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

Author Comment

ID: 17860835
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

LVL 35

Expert Comment

ID: 17860938

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.

Author Comment

ID: 17861029
That got me past that statement.  Now I am getting the same error on:

 Set shFolderItem = shFolder.Items.Item

shFolderItem is higlighted
LVL 35

Expert Comment

ID: 17861089
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


Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Background What I'm presenting in this article is the result of 2 conditions in my work area: We have a SQL Server production environment but no development or test environment; andWe have an MS Access front end using tables in SQL Server but we a…
You can of course define an array to hold data that is of a particular type like an array of Strings to hold customer names or an array of Doubles to hold customer sales, but what do you do if you want to coordinate that data? This article describes…
Get people started with the process of using Access VBA to control Outlook using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Microsoft Outlook. Using automation, an Access applic…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…
Suggested Courses

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question