1*b1cdbd2cSJim JagielskiAttribute VB_Name = "BrowseDirectorysOnly"
2*b1cdbd2cSJim Jagielski'*************************************************************************
3*b1cdbd2cSJim Jagielski'
4*b1cdbd2cSJim Jagielski'  Licensed to the Apache Software Foundation (ASF) under one
5*b1cdbd2cSJim Jagielski'  or more contributor license agreements.  See the NOTICE file
6*b1cdbd2cSJim Jagielski'  distributed with this work for additional information
7*b1cdbd2cSJim Jagielski'  regarding copyright ownership.  The ASF licenses this file
8*b1cdbd2cSJim Jagielski'  to you under the Apache License, Version 2.0 (the
9*b1cdbd2cSJim Jagielski'  "License"); you may not use this file except in compliance
10*b1cdbd2cSJim Jagielski'  with the License.  You may obtain a copy of the License at
11*b1cdbd2cSJim Jagielski'
12*b1cdbd2cSJim Jagielski'    http://www.apache.org/licenses/LICENSE-2.0
13*b1cdbd2cSJim Jagielski'
14*b1cdbd2cSJim Jagielski'  Unless required by applicable law or agreed to in writing,
15*b1cdbd2cSJim Jagielski'  software distributed under the License is distributed on an
16*b1cdbd2cSJim Jagielski'  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17*b1cdbd2cSJim Jagielski'  KIND, either express or implied.  See the License for the
18*b1cdbd2cSJim Jagielski'  specific language governing permissions and limitations
19*b1cdbd2cSJim Jagielski'  under the License.
20*b1cdbd2cSJim Jagielski'
21*b1cdbd2cSJim Jagielski'*************************************************************************
22*b1cdbd2cSJim Jagielski
23*b1cdbd2cSJim Jagielski' Modified as BIF_STATUSTEXT overflows for nested folders so is no longer
24*b1cdbd2cSJim Jagielski' shown.
25*b1cdbd2cSJim Jagielski
26*b1cdbd2cSJim Jagielski'=====================================================================================
27*b1cdbd2cSJim Jagielski' Browse for a Folder using SHBrowseForFolder API function with a callback
28*b1cdbd2cSJim Jagielski' function BrowseCallbackProc.
29*b1cdbd2cSJim Jagielski'
30*b1cdbd2cSJim Jagielski' This Extends the functionality that was given in the
31*b1cdbd2cSJim Jagielski' MSDN Knowledge Base article Q179497 "HOWTO: Select a Directory
32*b1cdbd2cSJim Jagielski' Without the Common Dialog Control".
33*b1cdbd2cSJim Jagielski'
34*b1cdbd2cSJim Jagielski' After reading the MSDN knowledge base article Q179378 "HOWTO: Browse for
35*b1cdbd2cSJim Jagielski' Folders from the Current Directory", I was able to figure out how to add
36*b1cdbd2cSJim Jagielski' a callback function that sets the starting directory and displays the
37*b1cdbd2cSJim Jagielski' currently selected path in the "Browse For Folder" dialog.
38*b1cdbd2cSJim Jagielski'
39*b1cdbd2cSJim Jagielski'
40*b1cdbd2cSJim Jagielski' Stephen Fonnesbeck
41*b1cdbd2cSJim Jagielski' steev@xmission.com
42*b1cdbd2cSJim Jagielski' http://www.xmission.com/~steev
43*b1cdbd2cSJim Jagielski' Feb 20, 2000
44*b1cdbd2cSJim Jagielski'
45*b1cdbd2cSJim Jagielski'=====================================================================================
46*b1cdbd2cSJim Jagielski' Usage:
47*b1cdbd2cSJim Jagielski'
48*b1cdbd2cSJim Jagielski'    Dim folder As String
49*b1cdbd2cSJim Jagielski'    folder = BrowseForFolder(Me, "Select A Directory", "C:\startdir\anywhere")
50*b1cdbd2cSJim Jagielski'    If Len(folder) = 0 Then Exit Sub  'User Selected Cancel
51*b1cdbd2cSJim Jagielski'
52*b1cdbd2cSJim Jagielski'=====================================================================================
53*b1cdbd2cSJim Jagielski
54*b1cdbd2cSJim JagielskiOption Explicit
55*b1cdbd2cSJim Jagielski
56*b1cdbd2cSJim JagielskiPrivate Const BIF_STATUSTEXT = &H4&
57*b1cdbd2cSJim JagielskiPrivate Const BIF_RETURNONLYFSDIRS = 1
58*b1cdbd2cSJim JagielskiPrivate Const BIF_DONTGOBELOWDOMAIN = 2
59*b1cdbd2cSJim JagielskiPrivate Const MAX_PATH = 260
60*b1cdbd2cSJim Jagielski
61*b1cdbd2cSJim JagielskiPrivate Const WM_USER = &H400
62*b1cdbd2cSJim JagielskiPrivate Const BFFM_INITIALIZED = 1
63*b1cdbd2cSJim JagielskiPrivate Const BFFM_SELCHANGED = 2
64*b1cdbd2cSJim JagielskiPrivate Const BFFM_SETSELECTION = (WM_USER + 102)
65*b1cdbd2cSJim Jagielski
66*b1cdbd2cSJim JagielskiPrivate 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
67*b1cdbd2cSJim JagielskiPrivate Declare Function SHBrowseForFolder Lib "shell32" (lpbi As BrowseInfo) As Long
68*b1cdbd2cSJim JagielskiPrivate Declare Function SHGetPathFromIDList Lib "shell32" (ByVal pidList As Long, ByVal lpBuffer As String) As Long
69*b1cdbd2cSJim JagielskiPrivate Declare Function lstrcat Lib "kernel32" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
70*b1cdbd2cSJim Jagielski
71*b1cdbd2cSJim JagielskiPrivate Type BrowseInfo
72*b1cdbd2cSJim Jagielski  hWndOwner      As Long
73*b1cdbd2cSJim Jagielski  pIDLRoot       As Long
74*b1cdbd2cSJim Jagielski  pszDisplayName As Long
75*b1cdbd2cSJim Jagielski  lpszTitle      As Long
76*b1cdbd2cSJim Jagielski  ulFlags        As Long
77*b1cdbd2cSJim Jagielski  lpfnCallback   As Long
78*b1cdbd2cSJim Jagielski  lParam         As Long
79*b1cdbd2cSJim Jagielski  iImage         As Long
80*b1cdbd2cSJim JagielskiEnd Type
81*b1cdbd2cSJim Jagielski
82*b1cdbd2cSJim JagielskiPrivate m_CurrentDirectory As String   'The current directory
83*b1cdbd2cSJim Jagielski'
84*b1cdbd2cSJim Jagielski
85*b1cdbd2cSJim JagielskiPublic Function BrowseForFolder(owner As Form, Title As String, StartDir As String) As String
86*b1cdbd2cSJim Jagielski  'Opens a Treeview control that displays the directories in a computer
87*b1cdbd2cSJim Jagielski
88*b1cdbd2cSJim Jagielski  Dim lpIDList As Long
89*b1cdbd2cSJim Jagielski  Dim szTitle As String
90*b1cdbd2cSJim Jagielski  Dim sBuffer As String
91*b1cdbd2cSJim Jagielski  Dim tBrowseInfo As BrowseInfo
92*b1cdbd2cSJim Jagielski  m_CurrentDirectory = StartDir & vbNullChar
93*b1cdbd2cSJim Jagielski
94*b1cdbd2cSJim Jagielski  szTitle = Title
95*b1cdbd2cSJim Jagielski  With tBrowseInfo
96*b1cdbd2cSJim Jagielski    .hWndOwner = owner.hWnd
97*b1cdbd2cSJim Jagielski    .lpszTitle = lstrcat(szTitle, "")
98*b1cdbd2cSJim Jagielski    .ulFlags = BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN '+ BIF_STATUSTEXT
99*b1cdbd2cSJim Jagielski    .lpfnCallback = GetAddressofFunction(AddressOf BrowseCallbackProc)  'get address of function.
100*b1cdbd2cSJim Jagielski  End With
101*b1cdbd2cSJim Jagielski
102*b1cdbd2cSJim Jagielski  lpIDList = SHBrowseForFolder(tBrowseInfo)
103*b1cdbd2cSJim Jagielski  If (lpIDList) Then
104*b1cdbd2cSJim Jagielski    sBuffer = Space(MAX_PATH)
105*b1cdbd2cSJim Jagielski    SHGetPathFromIDList lpIDList, sBuffer
106*b1cdbd2cSJim Jagielski    sBuffer = Left(sBuffer, InStr(sBuffer, vbNullChar) - 1)
107*b1cdbd2cSJim Jagielski    BrowseForFolder = sBuffer
108*b1cdbd2cSJim Jagielski  Else
109*b1cdbd2cSJim Jagielski    BrowseForFolder = ""
110*b1cdbd2cSJim Jagielski  End If
111*b1cdbd2cSJim Jagielski
112*b1cdbd2cSJim JagielskiEnd Function
113*b1cdbd2cSJim Jagielski
114*b1cdbd2cSJim JagielskiPrivate Function BrowseCallbackProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal lp As Long, ByVal pData As Long) As Long
115*b1cdbd2cSJim Jagielski
116*b1cdbd2cSJim Jagielski  Dim lpIDList As Long
117*b1cdbd2cSJim Jagielski  Dim ret As Long
118*b1cdbd2cSJim Jagielski  Dim sBuffer As String
119*b1cdbd2cSJim Jagielski
120*b1cdbd2cSJim Jagielski  On Error Resume Next  'Sugested by MS to prevent an error from
121*b1cdbd2cSJim Jagielski                        'propagating back into the calling process.
122*b1cdbd2cSJim Jagielski
123*b1cdbd2cSJim Jagielski  Select Case uMsg
124*b1cdbd2cSJim Jagielski
125*b1cdbd2cSJim Jagielski    Case BFFM_INITIALIZED
126*b1cdbd2cSJim Jagielski      Call SendMessage(hWnd, BFFM_SETSELECTION, 1, m_CurrentDirectory)
127*b1cdbd2cSJim Jagielski
128*b1cdbd2cSJim Jagielski  End Select
129*b1cdbd2cSJim Jagielski
130*b1cdbd2cSJim Jagielski  BrowseCallbackProc = 0
131*b1cdbd2cSJim Jagielski
132*b1cdbd2cSJim JagielskiEnd Function
133*b1cdbd2cSJim Jagielski
134*b1cdbd2cSJim Jagielski' This function allows you to assign a function pointer to a vaiable.
135*b1cdbd2cSJim JagielskiPrivate Function GetAddressofFunction(add As Long) As Long
136*b1cdbd2cSJim Jagielski  GetAddressofFunction = add
137*b1cdbd2cSJim JagielskiEnd Function
138