| Attribute VB_Name = "BrowseDirectorysOnly" |
| '************************************************************************* |
| ' |
| ' Licensed to the Apache Software Foundation (ASF) under one |
| ' or more contributor license agreements. See the NOTICE file |
| ' distributed with this work for additional information |
| ' regarding copyright ownership. The ASF licenses this file |
| ' to you under the Apache License, Version 2.0 (the |
| ' "License"); you may not use this file except in compliance |
| ' with the License. You may obtain a copy of the License at |
| ' |
| ' http://www.apache.org/licenses/LICENSE-2.0 |
| ' |
| ' Unless required by applicable law or agreed to in writing, |
| ' software distributed under the License is distributed on an |
| ' "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| ' KIND, either express or implied. See the License for the |
| ' specific language governing permissions and limitations |
| ' under the License. |
| ' |
| '************************************************************************* |
| |
| ' Modified as BIF_STATUSTEXT overflows for nested folders so is no longer |
| ' shown. |
| |
| '===================================================================================== |
| ' Browse for a Folder using SHBrowseForFolder API function with a callback |
| ' function BrowseCallbackProc. |
| ' |
| ' This Extends the functionality that was given in the |
| ' MSDN Knowledge Base article Q179497 "HOWTO: Select a Directory |
| ' Without the Common Dialog Control". |
| ' |
| ' After reading the MSDN knowledge base article Q179378 "HOWTO: Browse for |
| ' Folders from the Current Directory", I was able to figure out how to add |
| ' a callback function that sets the starting directory and displays the |
| ' currently selected path in the "Browse For Folder" dialog. |
| ' |
| ' |
| ' Stephen Fonnesbeck |
| ' steev@xmission.com |
| ' http://www.xmission.com/~steev |
| ' Feb 20, 2000 |
| ' |
| '===================================================================================== |
| ' Usage: |
| ' |
| ' Dim folder As String |
| ' folder = BrowseForFolder(Me, "Select A Directory", "C:\startdir\anywhere") |
| ' If Len(folder) = 0 Then Exit Sub 'User Selected Cancel |
| ' |
| '===================================================================================== |
| |
| Option Explicit |
| |
| Private Const BIF_STATUSTEXT = &H4& |
| Private Const BIF_RETURNONLYFSDIRS = 1 |
| Private Const BIF_DONTGOBELOWDOMAIN = 2 |
| Private Const MAX_PATH = 260 |
| |
| Private Const WM_USER = &H400 |
| Private Const BFFM_INITIALIZED = 1 |
| Private Const BFFM_SELCHANGED = 2 |
| Private Const BFFM_SETSELECTION = (WM_USER + 102) |
| |
| Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As String) As Long |
| Private Declare Function SHBrowseForFolder Lib "shell32" (lpbi As BrowseInfo) As Long |
| Private Declare Function SHGetPathFromIDList Lib "shell32" (ByVal pidList As Long, ByVal lpBuffer As String) As Long |
| Private Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long |
| |
| Private Type BrowseInfo |
| hWndOwner As Long |
| pIDLRoot As Long |
| pszDisplayName As Long |
| lpszTitle As Long |
| ulFlags As Long |
| lpfnCallback As Long |
| lParam As Long |
| iImage As Long |
| End Type |
| |
| Private m_CurrentDirectory As String 'The current directory |
| ' |
| |
| Public Function BrowseForFolder(owner As Form, Title As String, StartDir As String) As String |
| 'Opens a Treeview control that displays the directories in a computer |
| |
| Dim lpIDList As Long |
| Dim szTitle As String |
| Dim sBuffer As String |
| Dim tBrowseInfo As BrowseInfo |
| m_CurrentDirectory = StartDir & vbNullChar |
| |
| szTitle = Title |
| With tBrowseInfo |
| .hWndOwner = owner.hWnd |
| .lpszTitle = lstrcat(szTitle, "") |
| .ulFlags = BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN '+ BIF_STATUSTEXT |
| .lpfnCallback = GetAddressofFunction(AddressOf BrowseCallbackProc) 'get address of function. |
| End With |
| |
| lpIDList = SHBrowseForFolder(tBrowseInfo) |
| If (lpIDList) Then |
| sBuffer = Space(MAX_PATH) |
| SHGetPathFromIDList lpIDList, sBuffer |
| sBuffer = Left(sBuffer, InStr(sBuffer, vbNullChar) - 1) |
| BrowseForFolder = sBuffer |
| Else |
| BrowseForFolder = "" |
| End If |
| |
| End Function |
| |
| Private Function BrowseCallbackProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal lp As Long, ByVal pData As Long) As Long |
| |
| Dim lpIDList As Long |
| Dim ret As Long |
| Dim sBuffer As String |
| |
| On Error Resume Next 'Suggested by MS to prevent an error from |
| 'propagating back into the calling process. |
| |
| Select Case uMsg |
| |
| Case BFFM_INITIALIZED |
| Call SendMessage(hWnd, BFFM_SETSELECTION, 1, m_CurrentDirectory) |
| |
| End Select |
| |
| BrowseCallbackProc = 0 |
| |
| End Function |
| |
| ' This function allows you to assign a function pointer to a variable. |
| Private Function GetAddressofFunction(add As Long) As Long |
| GetAddressofFunction = add |
| End Function |