Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

SHBrowseForFolder API Question 1

Status
Not open for further replies.

Elena

Technical User
Oct 20, 2000
112
0
0
US
Hi,

I am using the API function to allow the user to select a folder only, and this is working fine. I would like to add the ability to save the folder's path to the registry (or somewhere else) , so that next time the user clicks the browse button, the search starts in the last directory they selected. I tried using the ipLRoot in the BrowseInfo type, but that doesn't show the rest of the folders. I just want it to start there and let the user browse.

Where can I find a detailed explanation of the SHBrowseForFolder function? I have Dan Appleman's book, but it's not in there.

Thanks,
Elena
 
CajunCenturion,

Thank you very much for the link. It was most helpful. I am having trouble figuring out one thing. I am new at this, so please bear with me.

I have several browse buttons on this form and I want each one to remember where it left off. So I think I need to set up a single function in a module to call from the buttons. Now I want to pass it the title string and the start folder string(which I would get from the registry) and the function would return the string of the folder that the user selects. What I can't figure out is how to get the start folder to the callback procedure. Or maybe you could tell me how to get the handle from the browse dialog so I could use the SendMessage function to send the start folder from within the calling function?

Thanks,

Elena
 
Perhaps if you were to post the code that you have so far, we can all take a look at it. I'll be in an out, and will check regularly, but there are lots of folks here who may be able to spot the problem. Good Luck
--------------
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 

Actually, I figured it out, but I will post it anyway, in case there is something I missed, or maybe someone else could use this. The trick was a global variable for the StartFolder.

>>In the module:

Option Explicit

Private Const BIF_RETURNONLYFSDIRS = 1
Private Const BIF_DONTGOBELOWDOMAIN = 2
Private Const MAX_PATH = 260


Public Declare Function SHBrowseForFolder Lib "shell32" _
(lpbi As BrowseInfo) As Long

Public Declare Function SHGetPathFromIDList Lib "shell32" _
(ByVal pidList As Long, ByVal _
lpBuffer As String) As Long
Public Declare Function lstrcat Lib "kernel32" Alias _
"lstrcatA" (ByVal lpString1 _
As String, ByVal lpString2 As _
String) As Long

Public Declare Function SendMessage Lib "user32.dll" Alias _
"SendMessageA" (ByVal hWnd As Long, _
ByVal Msg As Long, wParam _
As Any, lParam As Any) As Long

Public Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal pv As Long)

Public Declare Function GetActiveWindow Lib "user32" () As Long

Public 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

Const BFFM_ENABLEOK = &H465
Const BFFM_SETSELECTION = &H466
Const BFFM_SETSTATUSTEXT = &H464
Const BFFM_INITIALIZED = 1
Const BFFM_SELCHANGED = 2
Const BFFM_VALIDATEFAILED = 3

Global StartFolder As String

>>Then the Dummy Function for the Callback Procedure

Public Function DummyFunc(ByVal param As Long) As Long
DummyFunc = param
End Function

>> Then the callback function itself.

Public Function BrowseCallbackProc(ByVal hWnd As Long, ByVal uMsg _
As Long, ByVal lParam As Long, ByVal lpData As Long) As Long

Dim retval As Long ' return value

' If the BFFM_INITIALIZED message is received, set the
' default selection to the StartFolder.
Select Case uMsg
Case BFFM_INITIALIZED

retval = SendMessage(hWnd, BFFM_SETSELECTION, ByVal CLng(1), ByVal StartFolder)

End Select
BrowseCallbackProc = 0 ' the function should always return 0
End Function

>> And finally, the BrowseFolder Function

Public Function BrowseFolder(ByVal szTitle As String) As String

Dim lpIDList As Long
Dim sBuffer As String
Dim retval
Dim tBrowseInfo As BrowseInfo

With tBrowseInfo
.hWndOwner = Form1.hWnd
.lpszTitle = lstrcat(szTitle, "")
.ulFlags = BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN
.lpfnCallback = DummyFunc(AddressOf BrowseCallbackProc)

End With

lpIDList = SHBrowseForFolder(tBrowseInfo)
ActHwnd = GetActiveWindow
retval = SendMessage(ActHwnd, BFFM_SETSELECTION, ByVal CLng(1), ByVal StartFolder)


If (lpIDList) Then
sBuffer = Space(MAX_PATH)
SHGetPathFromIDList lpIDList, sBuffer
sBuffer = Left(sBuffer, InStr(sBuffer, vbNullChar) - 1)
BrowseFolder = sBuffer

End If
End Function

>> In the form's browse button

Private Sub Command1_Click()

StartFolder = "C:\SomeFolder"
Text1.Text = BrowseFolder("This is a test")
End Sub


Thanks for the help.

Elena
 
Oops,

I forgot to remove some of the stuff I was playing with.

Remove the 'ActHwnd = GetActiveWindow' line - it is not needed.

Also, I added 'CoTaskMemFree lpIDlist' at the bottom.

Thanks,
Elena
 
you need to add more code like this:

Public Type BrowseInfo
hWndOwner As Long
pIDLRoot As Long
pszDisplayName As String
lpszTitle As Long
ulFlags As Long
lpfnCallback As Long
lParam As Long
iImage As Long
End Type

Private Function procAddress(ByVal n As Long) As Long
procAddress = n
End Function

Public Function BrowseFolder(ByVal szTitle As String, Optional ByVal defaultfolder$ = "") As String

Dim default_path() As Byte
If defaultfolder <> &quot;&quot; Then
default_path = StrConv(defaultfolder, vbFromUnicode)
End If
Dim lpIDList As Long
Dim sBuffer As String
Dim retval
Dim tBrowseInfo As BrowseInfo

With tBrowseInfo
.hWndOwner = Form1.hWnd
.lpszTitle = lstrcat(szTitle, &quot;&quot;)
.pszDisplayName = defaultfolder & Space$(MAX_PATH)
.ulFlags = BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN
.lpfnCallback = DummyFunc(AddressOf BrowseCallbackProc)
If defaultfolder <> &quot;&quot; Then
.lpfnCallback = procAddress(AddressOf BrowseCallbackProc)
.lParam = VarPtr(default_path(0))
Else
.lpfnCallback = 0&
.lParam = 0&
End If
End With

lpIDList = SHBrowseForFolder(tBrowseInfo)
ActHwnd = GetActiveWindow
retval = SendMessage(ActHwnd, BFFM_SETSELECTION, ByVal CLng(1), ByVal StartFolder)


If (lpIDList) Then
sBuffer = Space(MAX_PATH)
SHGetPathFromIDList lpIDList, sBuffer
sBuffer = Left(sBuffer, InStr(sBuffer, vbNullChar) - 1)
BrowseFolder = sBuffer

End If
End Function

>> In the form's browse button

Private Sub Command1_Click()

StartFolder = &quot;C:\SomeFolder&quot;
Text1.Text = BrowseFolder(&quot;This is a test&quot;,StartFolder )
End Sub
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top