Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


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
  • 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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

Introduction While answering a recent question about filtering a custom class collection, I realized that this could be accomplished with very little code by using the ScriptControl (SC) library.  This article will introduce you to the SC library a…
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…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…
This lesson covers basic error handling code in Microsoft Excel using VBA. This is the first lesson in a 3-part series that uses code to loop through an Excel spreadsheet in VBA and then fix errors, taking advantage of error handling code. This l…
Suggested Courses
Course of the Month10 days, 8 hours left to enroll

572 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