Modifying Ghudson's Browsing Example

BrokenBiker

ManicMechanic
Local time
Today, 15:50
Joined
Mar 22, 2006
Messages
128
I'm using a browsing function to allow the user to select where previously selected files will be moved to. There are many examples/means to open a dialog box to select files, but I've only been able to find one that selects the folder location.

Ghudson's example works great, but I can't seem to find where to modify the code for it to default to a certain folder--"C:\MyFolder\" for instance.

Here's the module:
Code:
Option Compare Database
Option Explicit
'http://www.mvps.org/access/api/api0002.htm
'Code courtesy of Terry Kreft
Private 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
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" Alias "SHGetPathFromIDListA" (ByVal pidl As Long, ByVal pszPath As String) As Long
Private Declare Function SHBrowseForFolder Lib "shell32.dll" Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As Long
Private Const BIF_RETURNONLYFSDIRS = &H1
Public Function BrowseDirectory(szDialogTitle As String) As String
On Error GoTo Err_BrowseDirectory
    Dim X As Long, bi As BROWSEINFO, dwIList As Long
    Dim szPath As String, wPos As Integer
    With bi
        .hOwner = hWndAccessApp
        .lpszTitle = szDialogTitle
        .ulFlags = BIF_RETURNONLYFSDIRS
    End With
    dwIList = SHBrowseForFolder(bi)
    szPath = Space$(512)
    X = SHGetPathFromIDList(ByVal dwIList, ByVal szPath)
    If X Then
        wPos = InStr(szPath, Chr(0))
        BrowseDirectory = Left$(szPath, wPos - 1)
    Else
        BrowseDirectory = ""
    End If
Exit_BrowseDirectory:
    Exit Function
Err_BrowseDirectory:
    MsgBox Err.Number & " - " & Err.Description
    Resume Exit_BrowseDirectory
End Function

Public Function TestOpeningDirectory()
On Error GoTo Err_TestOpeningDirectory
    Dim sDirectoryName As String
    sDirectoryName = BrowseDirectory("Find and select where to export the Excel report files.")
    If sDirectoryName <> "" Then MsgBox "You selected the '" & sDirectoryName & "' directory.", vbInformation
Exit_TestOpeningDirectory:
    Exit Function
Err_TestOpeningDirectory:
    MsgBox Err.Number & " - " & Err.Description
    Resume Exit_TestOpeningDirectory
End Function



...And here's the Sub from the form's button:


Code:
Private Sub btn_BrowseMoveOld_Click()
    Dim sDirectoryName As String
    Me.tbHidden.SetFocus
    sDirectoryName = BrowseDirectory("Find and select where to export the report files.")
    tbDirectoryName = sDirectoryName
    End Sub
 
I use this:

A2KCallbackBrowse
Functions to allow you to specify the opening folder to be displayed when calling the Browser Folder Dialog window. Also allow you to specify position for the standard windows File Dialog to open at

Hope this helps ...
 
If you want it dead simple you can just do...
Code:
[FONT="Tahoma"][SIZE="1"]Public Function GetFolder(Optional StartAt As Variant) As String
   On Error Resume Next    [COLOR="Green"]'when cancelled the .Self property returns 'nothing' and the .Path property fails[/COLOR]
   GetFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Please choose a folder", &H200, StartAt).Self.Path
End Function[/SIZE][/FONT]
The &H200 disables the 'Create Folder' button.
Other options for this parameter at...
http://msdn.microsoft.com/en-us/library/bb773205(VS.85).aspx
 
If you want it dead simple you can just do...
Code:
[FONT="Tahoma"][SIZE="1"]Public Function GetFolder(Optional StartAt As Variant) As String
   On Error Resume Next    [COLOR="Green"]'when cancelled the .Self property returns 'nothing' and the .Path property fails[/COLOR]
   GetFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Please choose a folder", &H200, StartAt).Self.Path
End Function[/SIZE][/FONT]
The &H200 disables the 'Create Folder' button.
Other options for this parameter at...
http://msdn.microsoft.com/en-us/library/bb773205(VS.85).aspx

Now that is really simple ... I like it! :D
 
that is very nice lagbolt. wondering if you can shed some light on that function for me.

- it looks like the SHBrowseForFolder function wants a BROWSEINFO structure passed in.
- the BROWSEINFO structure has what looks like 8 members but you have only included 4.
- i experimented with it by excluding some members and it didn't work at all (from immediate window). for ex, i removed &H200 and it no longer worked.
- BIF_NONEWFOLDERBUTTON flag is listed as 0x0200 but you have &H200. i guess there's a name for this process of converting the 'format' but don't know what it is.
- the function didn't require any declarations which i've never seen before. why? is that the difference between using 'apis' and 'win32' calls?

trying to work with api, win32, etc more but having trouble putting it all together. can you explain it a little bit using your GetFolder example? where to go for more help on these things?
 
Wow! OK. First things first...the code listed at A2KCallbackBrowse had a couple of small issues when I tried to run it.

I created a module and pasted the code in. I then created the form w/ the two buttons and two text fields, and changed the defualt "C:\" folder to a new location. The only actual problem that came up was a 'SetFocus' issue.

I had to set the focus to either Text1 or Text2, depending on the function running at the time, in five different places throughout the form's code: Form_Load (1ea), Command1_Click(2ea), & Command2_Click(2ea). A simple "Me.Text1.SetFocus" (or Text2) worked fine. The de-bugger brought me to the specific lines. No problems.

I did notice something else. Text2 (the returned folder from the browser) doesn't include a '\' at the end of it. No biggie. I just wanted to point that out as it can affect other functions.

Last thing for this method: The code consists of two parts--folder name & folder pidl. What's the difference between the two?


Now, for the next bit o' code from Lagbolt. That code opens a dialog box, but I don't know two things: 1) how to return the selected folder to use w/ other functions, 2) how to have the browser default to a specific folder.
 
hi brokenbiker, seems noone else is online right now so...
to use lagbolt's code:
Code:
Dim strFldr as String 
strFldr = GetFolder
strFldr now contains the path to the folder (without a final backslash).

to start at a specific folder add the optional parameter:
Code:
Dim strFldr as String 
[COLOR=green]'for example:[/COLOR]
strFldr = GetFolder("C:\Documents and Settings\you\My Documents\MSDN")
 
by the way, i've sorted out the hexadecimal bit. still looking up other stuff. any good links appreciated.
 
You can specify the initial directory like this:

Dim path As String
path = GetFolder("C:\Windows")
MsgBox path
 
Here's an early bound and more verbose version of what goes on in the GetFolder() function, above.
The Shell32 reference is called 'Microsoft Shell Controls And Automation' in the references dialog (see image below), and the file on my Vista machine is "C:\Windows\system32\SHELL.dll"
Code:
[FONT="Verdana"]Sub alskjdfh()
   Debug.Print Test
End Sub

Function Test(Optional OpenAt As Variant) As String
   Dim shll As New Shell32.Shell
   Dim fd As Shell32.Folder
   Dim fi As Shell32.FolderItem
   Set fd = shll.BrowseForFolder(0, "Please choose a folder", 0, OpenAt)
   If Not fd Is Nothing Then
      Set fi = fd.self
      Test = fi.Path
   End If
End Function[/FONT]
Step through the code with the 'Locals' window open and you can get a lot of info about each of the objects, and of course the Object Browser makes a bunch more info available.

Also, the third parameter of the BrowseForFolder method, 'Options', will accept a combination of values that in the API would have been passed in the ulFlags member of the BROWSEINFO Structure. These are detailed at the link in the original post and included below. These might be summed and passed to the function like this...
Code:
[FONT="Tahoma"]Public Function GetFolder(Optional StartAt As Variant) As String
   On Error Resume Next
   Dim options As Long
   options = &H40 Or &H200
   GetFolder = CreateObject("Shell.Application").BrowseForFolder(0, "Please choose a folder", options, StartAt).self.Path
End Function[/FONT]
Here are the constants...
Code:
[FONT="Tahoma"][SIZE="1"]
Private Const BIF_RETURNONLYFSDIRS = &H1
   'Only return file system directories. If the user selects folders that are not part of the file system, the OK button is grayed.
   'Note  The OK button remains enabled for "\\server" items, as well as "\\server\share" and directory items. However, if the
   '  user selects a "\\server" item, passing the PIDL returned by SHBrowseForFolder to SHGetPathFromIDList fails.
Private Const BIF_DONTGOBELOWDOMAIN = &H2
   'Do not include network folders below the domain level in the dialog box's tree view control.
Private Const BIF_STATUSTEXT = &H4
   'Include a status area in the dialog box. The callback function can set the status text by sending messages to the dialog box.
   'This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
Private Const BIF_RETURNFSANCESTORS = &H8
   'Only return file system ancestors. An ancestor is a subfolder that is beneath the root folder in the namespace hierarchy.
   'If the user selects an ancestor of the root folder that is not part of the file system, the OK button is grayed.
Private Const BIF_EDITBOX = &H10
   'Version 4.71. Include an edit control in the browse dialog box that allows the user to type the name of an item.
Private Const BIF_VALIDATE = &H20
   'Version 4.71. If the user types an invalid name into the edit box, the browse dialog box calls the application's BrowseCallbackProc
   'with the BFFM_VALIDATEFAILED message. This flag is ignored if BIF_EDITBOX is not specified.
Private Const BIF_NEWDIALOGSTYLE = &H40
   'Version 5.0. Use the new user interface. Setting this flag provides the user with a larger dialog box that can be resized.
   'The dialog box has several new capabilities, including: drag-and-drop capability within the dialog box, reordering, shortcut menus, new folders, delete, and other shortcut menu commands.
   'Note  If Component Object Model (COM) is initialized through CoInitializeEx with the COINIT_MULTITHREADED flag set, SHBrowseForFolder fails if BIF_NEWDIALOGSTYLE is passed.
Private Const BIF_BROWSEINCLUDEURLS = &H80
   'Version 5.0. The browse dialog box can display URLs. The BIF_USENEWUI and BIF_BROWSEINCLUDEFILES flags must also be set.
   'If any of these three flags are not set, the browser dialog box rejects URLs. Even when these flags are set, the browse dialog box
   'displays URLs only if the folder that contains the selected item supports URLs. When the folder's IShellFolder::GetAttributesOf method
   'is called to request the selected item's attributes, the folder must set the SFGAO_FOLDER attribute flag. Otherwise, the browse dialog box will not display the URL.
Private Const BIF_USENEWUI = BIF_EDITBOX And BIF_NEWDIALOGSTYLE
   'Version 5.0. Use the new user interface, including an edit box. This flag is equivalent to BIF_EDITBOX | BIF_NEWDIALOGSTYLE.
   'Note  If COM is initialized through CoInitializeEx with the COINIT_MULTITHREADED flag set, SHBrowseForFolder fails if BIF_USENEWUI is passed.
Private Const BIF_UAHINT = &H100
   'Version 6.0. When combined with BIF_NEWDIALOGSTYLE, adds a usage hint to the dialog box, in place of the edit box. BIF_EDITBOX overrides this flag.
Private Const BIF_NONEWFOLDERBUTTON = &H200
   'Version 6.0. Do not include the New Folder button in the browse dialog box.
Private Const BIF_NOTRANSLATETARGETS = &H400
   'Version 6.0. When the selected item is a shortcut, return the PIDL of the shortcut itself rather than its target.
Private Const BIF_BROWSEFORCOMPUTER = &H1000
   'Only return computers. If the user selects anything other than a computer, the OK button is grayed.
Private Const BIF_BROWSEFORPRINTER = &H2000
   'Only allow the selection of printers. If the user selects anything other than a printer, the OK button is grayed.
   'In Microsoft Windows XP and later systems, the best practice is to use a Windows XP-style dialog, setting the root of the dialog to the Printers and Faxes folder (CSIDL_PRINTERS).
Private Const BIF_BROWSEINCLUDEFILES = &H4000
   'Version 4.71. The browse dialog box displays files as well as folders.
Private Const BIF_SHAREABLE = &H8000
   'Version 5.0. The browse dialog box can display shareable resources on remote systems.
   'This is intended for applications that want to expose remote shares on a local system. The BIF_NEWDIALOGSTYLE flag must also be set.[/SIZE][/FONT]
Finally an image of the References Dialog...
Cheers,
Mark
 

Attachments

  • ShellRef.jpg
    ShellRef.jpg
    60.6 KB · Views: 160

Users who are viewing this thread

Back
Top Bottom