Allow user to select a directory

Posted on 2006-11-02
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
  • 3
  • 2
LVL 35

Accepted Solution

mvidas earned 250 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
Netscaler Common Configuration How To guides

If you use NetScaler you will want to see these guides. The NetScaler How To Guides show administrators how to get NetScaler up and configured by providing instructions for common scenarios and some not so common ones.

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

PRTG Network Monitor: Intuitive Network Monitoring

Network Monitoring is essential to ensure that computer systems and network devices are running. Use PRTG to monitor LANs, servers, websites, applications and devices, bandwidth, virtual environments, remote systems, IoT, and many more. PRTG is easy to set up & use.

Question has a verified solution.

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

There are many ways to remove duplicate entries in an SQL or Access database. Most make you temporarily insert an ID field, make a temp table and copy data back and forth, and/or are slow. Here is an easy way in VB6 using ADO to remove duplicate row…
Article by: Martin
Here are a few simple, working, games that you can use as-is or as the basis for your own games. Tic-Tac-Toe This is one of the simplest of all games.   The game allows for a choice of who goes first and keeps track of the number of wins for…
As developers, we are not limited to the functions provided by the VBA language. In addition, we can call the functions that are part of the Windows operating system. These functions are part of the Windows API (Application Programming Interface). U…
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…

773 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