Solved

Allow user to select a directory

Posted on 2006-11-02
6
200 Views
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.


0
Comment
Question by:mlcktmguy
[X]
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
6 Comments
 
LVL 35

Accepted Solution

by:
mvidas earned 250 total points
ID: 17860616
mlcktmguy,

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:

'&H1000
'Only return computers. If the user selects anything other than a computer, the
'OK button is grayed.
Private Const BIF_BROWSEFORCOMPUTER = &H1000

'&H2000
'Only return printers. If the user selects anything
'other than a printer, the OK button is grayed.
Private Const BIF_BROWSEFORPRINTER = &H2000

'&H4000
'The browse dialog will display files as well as folders.
Private Const BIF_BROWSEINCLUDEFILES = &H4000

'&H2
'Do not include network folders below the domain level in the tree view control.
Private Const BIF_DONTGOBELOWDOMAIN = &H2

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

'&H40
'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.
Private Const BIF_NEWDIALOGSTYLE = &H40

'&H8
'Only return file system ancestors. If the user selects anything other than a file
'system ancestor, the OK button is grayed.
Private Const BIF_RETURNFSANCESTORS = &H8

'&H1
'Only return file system directories. If the user selects folders that are not part
'of the file system, the OK button is grayed.
Private Const BIF_RETURNONLYFSDIRS = &H1

'&H4
'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


Type BROWSEINFO
 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."
 Else
  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

Matt
0
 
LVL 13

Expert Comment

by:rettiseert
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
    Const BIF_RETURNONLYFSDIRS = 1
   
    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
        .ulFlags = BIF_RETURNONLYFSDIRS
    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
0
 
LVL 1

Author Comment

by:mlcktmguy
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
0
Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

 
LVL 35

Expert Comment

by:mvidas
ID: 17860938
Hi,

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.
Matt
0
 
LVL 1

Author Comment

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

 Set shFolderItem = shFolder.Items.Item

shFolderItem is higlighted
0
 
LVL 35

Expert Comment

by:mvidas
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

0

Featured Post

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

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

When designing a form there are several BorderStyles to choose from, all of which can be classified as either 'Fixed' or 'Sizable' and I'd guess that 'Fixed Single' or one of the other fixed types is the most popular choice. I assume it's the most p…
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 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…
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
Course of the Month10 days, 18 hours left to enroll

628 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