Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

BrowseFolder (API0002 at mvps.org) question

15 views
Skip to first unread message

Salad

unread,
Sep 16, 2005, 3:21:45 AM9/16/05
to
Using the code at http://www.mvps.org/access/api/api0002.htm, is it
possible to set/open to a folder instead of MyComputer?

Ex: BrowseFolder("Select a folder","C:\Windows\System32") and it would
go open the dialog to "C:\Windows\System32"

I would like to open the dialog to the folder currently used. I'm
supposing I need to add the folder name to "type" BROWSEINFO, but I'm
not sure what property I need to send. Anybody know?

lylefair

unread,
Sep 16, 2005, 7:47:55 AM9/16/05
to
I think the shell object takes a little less space than the API call.
What is the "folder currently used"? If it's the current directory then
something like this is likely to work. If it's something else, then we
will need to know what.

Dim o As Object
Dim f As Object
Set o = CreateObject("Shell.Application")
Set f = o.BrowseForFolder(0, "Select a folder", 0, CurDir())
If f Is Nothing Then
MsgBox Nz("Action Cancelled")
Else
MsgBox "You selected the folder: " & f.Title
End If
Set f = Nothing
Set o = Nothing

(Of course this can be used with early binding (enabling intellisense)
by setting a reference to shell32.dll).

Wayne Morgan

unread,
Sep 16, 2005, 8:00:58 AM9/16/05
to
Right above the code is a link to Stephen Lebans's site. The line says that
he has added functionality to do this. Follow that link and it will take you
to it.

--
Wayne Morgan
MS Access MVP


"Salad" <o...@vinegar.com> wrote in message
news:douWe.10940$Wd7....@newsread1.news.pas.earthlink.net...

Salad

unread,
Sep 16, 2005, 10:29:09 AM9/16/05
to
lylefair wrote:

Hi Lyle, this almost worked and the code is easy. The problem is that
there is no method I see to traverse upwards. For example, if I specify
c:\windows\system32, I am dropped there...but I can't go up. About
All I can do is create a new folder.

Salad

unread,
Sep 16, 2005, 11:38:57 AM9/16/05
to
Wayne Morgan wrote:

> Right above the code is a link to Stephen Lebans's site. The line says that
> he has added functionality to do this. Follow that link and it will take you
> to it.
>

Thanks for the update. Works fine.

In case anyone needs this and they only have A97 on the machine, they
may need to change the references.

lylefair

unread,
Sep 16, 2005, 12:04:40 PM9/16/05
to
TTBOMK being willing to go down only is a preference of all
BrowseForFolder functions. I know of no solution except the following
!!!!HACK!!!! of GetOpenFileName in which one selects a folder and
clicks OPEN to return its name. (SELECT AND OPEN!). It will go up as
well as down. I should be happy to be enlightened as to a simpler and
more conventional function.

Please, bear in mind that this is TRES old code which I have recovered
from my archives. It runs fine on this Win XP-Acc 2003 combination. You
could test it by running testgetPath. Please, correct line feed errors
inserted by News Clients.

Private Declare Function CommDlgExtendedError Lib "comdlg32.dll" () As
Long
Private Declare Function GetOpenFileName Lib "comdlg32.dll" _
Alias "GetOpenFileNameA" _
(pOpenfilename As OPENFILENAME) As Long

Private Type OPENFILENAME
lStructSize As Long
hwndOwner As Long
hInstance As Long
lpstrFilter As String
lpstrCustomFilter As String
nMaxCustFilter As Long
nFilterIndex As Long
lpstrFile As String
nMaxFile As Long
lpstrFileTitle As String
nMaxFileTitle As Long
lpstrInitialDir As String
lpstrTitle As String
flags As Long
nFileOffset As Integer
nFileExtension As Integer
lpstrDefExt As String
lCustData As Long
lpfnHook As Long
lpTemplateName As String
End Type

Private Const OFN_HIDEREADONLY = &H4
Private Const OFN_NOCHANGEDIR = &H8
Private Const OFN_SHAREAWARE = &H4000
Private Const MAX_PATH = 260

Public Function getFile(Optional InitialDir As String, _
Optional FilterMessage As String = "Choose File", _
Optional FilterSkelton As String = "*.md?", _
Optional File As String = "Jet Databases", _
Optional Title As String = "Use the Open Button to Select") As
String
getFile = getPath(CurDir$, FilterMessage, FilterSkelton, File,
Title)
End Function

Public Function getPath( _
Optional InitialDir As String, _
Optional FilterMessage As String = "Choose Folder Only", _
Optional FilterSkelton As String = "*|*", _
Optional File As String = "Folders Only", _
Optional Title As String = "Use the Open Button to Select") As
String
Dim CommDlgError As Long
Dim OFN As OPENFILENAME
If Len(InitialDir) = 0 Then InitialDir = CurDir$()
With OFN
.lStructSize = Len(OFN)
.lpstrFilter = FilterMessage & vbNullChar & FilterSkelton &
String(2, vbNullChar)
.lpstrFile = File & String(MAX_PATH - Len(File), vbNullChar)
.nMaxFile = MAX_PATH
.lpstrInitialDir = InitialDir & vbNullChar
.lpstrTitle = Title
.flags = OFN_HIDEREADONLY Or OFN_NOCHANGEDIR Or OFN_SHAREAWARE
If GetOpenFileName(OFN) <> 0 Then
If FilterSkelton = "*|*" Then
getPath = Left(.lpstrFile, .nFileOffset)
Else
getPath = .lpstrFile
End If
Else
CommDlgError = CommDlgExtendedError
' if not just a cancel
If CommDlgError <> 0 Then
MsgBox "Common Dialog Error # " & CommDlgError _
& vbCrLf _
& vbCrLf _
& "Consult Common Dialog Documumentation" _
& vbCrLf _
& "(in MSDN Library)" _
& vbCrLf _
& vbCrLf _
& "for meaning.", _
vbCritical, _
"Cyriv Solutions"
End If
End If
End With
End Function

Sub testgetPath()
MsgBox getPath
End Sub

Sub testgetFile()
MsgBox getFile
End Sub

jimfo...@compumarc.com

unread,
Sep 16, 2005, 1:43:37 PM9/16/05
to
lylefair wrote:
> TTBOMK being willing to go down only is a preference of all
> BrowseForFolder functions. I know of no solution except the following
> !!!!HACK!!!! of GetOpenFileName in which one selects a folder and
> clicks OPEN to return its name. (SELECT AND OPEN!). It will go up as
> well as down. I should be happy to be enlightened as to a simpler and
> more conventional function.

I'm not that enlightened but I think I can help you here.

The CalendarAnnotate program I posted has an example of this.

Original post:

http://groups.google.com/group/comp.databases.ms-access/msg/1b176f58cab46186?hl=en&

Download location:

http://www.oakland.edu/~fortune/CalendarAnnotate.zip

I think this is all the code that's required (except for code that
needs to be added for specifying the root folder for browsing):

'-----Beginning of modAPIFunctions
Option Compare Database
Option Explicit

Declare Function SHBrowseForFolder Lib "shell32.dll" (ByRef lpbi As _
MyBrowseInfo) As Long
Declare Function SHGetPathFromIDList Lib "shell32.dll" (pidl As Long, _
ByVal sPath As String) As Long

Type MyBrowseInfo
hwndOwner 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
'-----End of modAPIFunctions

'-----Beginning of code behind form
Private Sub cmdSelectOutputDirectory_Click()
'Code adapted from post by Emile Besseling
Dim BInfo As MyBrowseInfo
Dim strDir As String
Dim strFile As String
Dim BrowseView As Long
Dim lngID As Long
Dim strFolder As String

With BInfo
.pidlRoot = 0
.lpszTitle = "Please choose an output directory."
.lpfn = 0
.lParam = 0
.iImage = 0
End With
lngID = SHBrowseForFolder(BInfo)
strDir = Space(255)
If lngID <> 0 Then
If SHGetPathFromIDList(ByVal lngID, strDir) Then
strFolder = Left(strDir, InStr(strDir, Chr(0)) - 1)
End If
End If
txtOutputDirectory.Value = strFolder
End Sub
'-----End of code behind form

It is rumored that the pidlRoot is a pointer to an item identifier list
(ITEMIDLIST) that specifies the location of the root folder to browse
from. Check out the Win32 help file to see if that rumor is true.

James A. Fortune

lylefair

unread,
Sep 16, 2005, 5:14:54 PM9/16/05
to
Thank you. I think there may be many ways of selecting a folder.
For instance, if we set a reference to Office11 then the follwing two
lines return the full path of a selected folder.

FileDialog(msoFileDialogFolderPicker).Show
MsgBox FileDialog(msoFileDialogFolderPicker).SelectedItems(1)

The dialog lets us move up and down the file folder tree, and allows us
to select multiple items, which I'm guessing, one can access with
various indexes.
In addition one can browse for files with msoFileDialogOpen and save
files with msoFileDialogSaveAs.

Can these be run in mde's, ade's? I don't know. I recall some problem
with this in the distant past.

jimfo...@compumarc.com

unread,
Sep 18, 2005, 12:41:36 AM9/18/05
to

From:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/programmersguide/shell_basics/shell_basics_programming/folder_id.asp

"When the user selects a folder, SHBrowseForFolder returns the folder's
fully-qualified PIDL..."

That seems to indicate you could just pick the folder you want to be
the default, return the PIDL using SHBrowseForFolder, then use that
PIDL to set the default folder in the BROWSEINFO structure. I still
haven't tried this yet. I'm sure there are many good ways to select a
folder. I like it when a few simple API calls will do the job. That
should work just about anywhere. You were right about this NG having
less people who are willing to try out new ideas than before. I
appreciate the fact that 'Ulysses' Fairfield is trying out the
Shell.Application stuff and sailing into new waters. The multiple
selection is interesting. Hmm.., the code at mvps.org looks a lot
closer to what I use than the hack they had there before. Terry did
enhance the idea a little so that's good. Being able to make a few API
calls doesn't warrant copyright enforcement in my opinion but that's
their right :-). Maybe I should recode some of the mvps.org solutions
without looking at what they wrote to see if I can make some
improvements. That'll go over well.

James A. Fortune

No new U.S. holidays have been added since MLK in 1983. --
http://uscode.house.gov/download/pls/5C61.txt

Stephen Lebans

unread,
Sep 19, 2005, 7:12:39 PM9/19/05
to
Last year I adapted the VB code from the MVP site to use the functionality
you described.
http://www.lebans.com/callbackbrowser.htm

Bug Fix! June 13/2003 The calling functions must reside in the Form's Class
module or you will GPF at intermittent times. Thanks to Richard Bernstein
for the head up!

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:

Adapted from a sample here:

http://www.mvps.org/vbnet/index.html?code/callback/browsecallback.htm

A2KCallbackBrowse.zip - For A2K or higher

A97CallBackBrowse.zip - For A97

Version 4 June 13/2003

Fixed intermittent GPF bug. The GPF's were caused by memory allocation
issues for the pathname string when the code resides in a standard Code
module. This code must reside in the form's Class module.

Version 3

Added ability to force File Dialog window to open at current cursor
coordinates.


--

HTH
Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
<jimfo...@compumarc.com> wrote in message
news:1127018496....@g44g2000cwa.googlegroups.com...

jimfo...@compumarc.com

unread,
Sep 20, 2005, 2:18:55 PM9/20/05
to

Stephen,

Thanks for adding this functionality. I have not looked at your
solution but I am confident that it works. Please continue to supply
Access solutions.

Sincerely,
James A. Fortune

jimfo...@compumarc.com

unread,
Sep 21, 2005, 11:08:03 AM9/21/05
to
Stephen Lebans wrote:
> Last year I adapted the VB code from the MVP site to use the functionality
> you described.
> http://www.lebans.com/callbackbrowser.htm
>
> Bug Fix! June 13/2003 The calling functions must reside in the Form's Class
> module or you will GPF at intermittent times. Thanks to Richard Bernstein
> for the head up!

You seem to be implying that I didn't write this code before it was on
mvps.org. Maybe someone, perhaps Piet, can verify that at the time of
this post:

http://groups.google.com/group/comp.databases.ms-access/msg/b10410ec42d02213?hl=en&

the code on mvps.org was a lot closer to the hack exposed by Lyle than
to what it is now. I specifically recall what I posted being much
simpler than what was at mvps.org. Did anyone notice the difference?

James A. Fortune

Stephen Lebans

unread,
Sep 21, 2005, 11:38:41 AM9/21/05
to
I don't know what the hell you are talking about Jim as I was not implying
anything in my post. I simply and quickly read through the relevant thread
and thought I might help you by pointing you to some older code on my site.

My mistake for trying to help you.
--


Stephen Lebans
http://www.lebans.com
Access Code, Tips and Tricks
Please respond only to the newsgroups so everyone can benefit.
<jimfo...@compumarc.com> wrote in message

news:1127315283.6...@z14g2000cwz.googlegroups.com...

jimfo...@compumarc.com

unread,
Sep 21, 2005, 12:45:57 PM9/21/05
to

Stephen,

My comments were not about the code you wrote. What you wrote was
totally original. Don't you remember what was at

http://www.mvps.org/access/api/api0002.htm

before? Anyone? I'm not making this up. I don't mind what happened.
I just don't like the way it happened. Thanks to Lyle for catching it.
I have no complaint with you or your attempt to help.

James A. Fortune

jimfo...@compumarc.com

unread,
Sep 21, 2005, 1:13:22 PM9/21/05
to

jimfo...@compumarc.com wrote:
> before? Anyone? I'm not making this up. I don't mind what happened.
> I just don't like the way it happened. Thanks to Lyle for catching it.
> I have no complaint with you or your attempt to help.
>
> James A. Fortune

I did some Googling and found that the code Terry put on mvps.org is
original. He has posted similar code before in this NG. It's just
that that was not the code that was on mvps.org when I wrote my
version.

James A. Fortune

lylefair

unread,
Sep 21, 2005, 1:28:06 PM9/21/05
to
Actually, I have no idea what this is about.
I think it's difficult for MVPS.org to do what it does. It tries to be
a resource. But, today, there is scarcely anything one can list as a
resource, that someone else may not have thought of, played with, or
posted first (or, sometimes in my case, DREAMED or IMAGINED that he
thought of first!). Finding references to all such occurences, and
deciding which was first could take forever, and still not be correct.
I generally ignore MVPS.org; it has too big a job and too few
(outstanding as they are) contributors to be current and fresh.
Now if you want to get your dander up, learn another language whose
users develop in Access, and investigate some of the web sites and
sources for Access in this new language. I've been quite astounded at
what has been discovered (and even copyrighted) competely independently
just a few weeks after it has been posted in CDMA. The names of
procedures and comments are given in the new language, but the "Access"
words and phrasing is identical with the English version. Well, one
would expect that, as coding styles are not so dissimilar. And I
suppose things might be discovered by English speaking members shortly
after having been posted in another language as well.
I used to have a more proprietary feeling about code etc than I do now.
When I examine things I have written I realize they are the product of
my interaction with many people and many sources. While they are mine,
they are not just mine, they are the world's as well.
Newton said, "If I have seen further than others it is because I have
stood on the shoulders of giants." In Access and all other aspects of
coding and developing there are lots of giants, and often we stand on
their shoulders without even knowing it.
So if someone stands on mine, I don't mind, even if she forgets to wear
a mini, ooops, I mean even if he/she forgets to say, "Conceived while
standing on Lyle's shoulders".

Mike Preston

unread,
Sep 21, 2005, 1:40:39 PM9/21/05
to

I have a offline version of API002 as of 4/14/02 and it is identical
to what exists today. So, if there were any changes, they were a long
time ago.

Sure you aren't thinking of something else?

mike

jimfo...@compumarc.com

unread,
Sep 21, 2005, 2:16:29 PM9/21/05
to
Mike Preston wrote:

> I have a offline version of API002 as of 4/14/02 and it is identical
> to what exists today. So, if there were any changes, they were a long
> time ago.
>
> Sure you aren't thinking of something else?
>
> mike

In that case I extend a profound apology to Terry Kreft. I don't think
I would have written code had I seen anything similar to what I wrote
existing at mvps.org. Given the facts I have to assume I was not
looking at API002. If I write any improvements to anything at mvps.org
in the future I'll be sure to document everything more carefully.
Thanks for the information.

James A. Fortune

jimfo...@compumarc.com

unread,
Sep 21, 2005, 2:28:43 PM9/21/05
to

Whatever I was looking at was as long as:

http://groups.google.com/group/comp.databases.ms-access/msg/8674331564b8d925?hl=en&

Perhaps I was looking at API001.

James A. Fortune

Mike Preston

unread,
Sep 21, 2005, 8:35:21 PM9/21/05
to

Perhaps. However, the only difference between the API001 "back then"
and the API001 "now" is the line:

ahtCommonFileOpenSave = "NoFile"

was changed to

ahtCommonFileOpenSave = vbNullString

This is a comparison of everything from the start of the code to the
end of the code. It does not compare the introductions, which are
markedly dissimilar.

mike


jimfo...@compumarc.com

unread,
Sep 21, 2005, 9:22:59 PM9/21/05
to

Mike,

Thanks for helping me try to determine what happened. What I meant was
that perhaps I assumed that the API001 code was meant to do the API002
task. I don't think that was what happened but the evidence seems to
suggest something like that happening. Perhaps the long version shown
in the post above was at the site temporarily. I'm not sure what
happened yet because I can't believe I would mix up a link to code to
browse files with a link to code to browse folders but at the moment
it's the likeliest possibility. I remember thinking that the code I
saw a year ago was overkill for the task and that entirely different
API functions to do it were being used in a way similar to the code
Lyle posted. BTW, where did Lyle dig up that code? It almost had to
be from someone in this NG (not me!). Maybe the answer will come to me
in my sleep.

James A. Fortune

lylefair

unread,
Sep 21, 2005, 9:46:58 PM9/21/05
to
I stole it from
http://groups.google.ca/group/comp.databases.ms-access/msg/9a8da6c9e0d233f8?hl=en&
Nov 24 2000.

Some guy named Fairfield started the thread with this comment:
**** begin quote ****
I suppose others have written custom dialogs to allow folder as
opposed to file selection, but some quick searches didn't pop up
anything that was quickly pastable.

So, needing something like that this morning, I'm air coding my
own, which is going to send GOFN an illegal filter, "|", so it
will show no file names, ... and chop off the file name returned
on clicking open, (since no file is or can be "chosen", what is
returned is the path comprised of what ever folder you are in
and the name (never seen) of the default file sent originally.

This seem pretty simple and it also seems to work; I'll post if
anyone is interested.
**** end quote ****

Later in the thread he posted the code:

**** begin code ****
Option Explicit

Function getFolder(Optional ByVal InitialDir As String)


Dim CommDlgError As Long
Dim OFN As OPENFILENAME
If Len(InitialDir) = 0 Then InitialDir = CurDir$()
With OFN
.lStructSize = Len(OFN)

.hwndOwner = Access.hWndAccessApp
.lpstrFilter = "Folders Only" & vbNullChar & "|" &
String(2, vbNullChar)
.lpstrFile = "Choose a Folder" & String(MAX_PATH - 4,


vbNullChar)
.nMaxFile = MAX_PATH
.lpstrInitialDir = InitialDir & vbNullChar

.lpstrTitle = "Use the Open Button to Select a Folder"


.flags = OFN_HIDEREADONLY Or OFN_NOCHANGEDIR Or
OFN_SHAREAWARE
If GetOpenFileName(OFN) <> 0 Then

getFolder = Left(.lpstrFile, .nFileOffset)


Else
CommDlgError = CommDlgExtendedError
' if not just a cancel
If CommDlgError <> 0 Then

msgbox "Common Dialog Error # " & CommDlgError _


& vbCrLf _
& vbCrLf _
& "Consult Common Dialog Documumentation" _
& vbCrLf _

& "(in MSDN Lirrary)" _


& vbCrLf _
& vbCrLf _
& "for meaning.", _
vbCritical, _
"Cyriv Solutions"
End If
End If
End With
End Function

**** end code ****

Clearly, I've modified his work.

Did someone post this code previously and thus "beat Fairfield to the
pole"? Who knows? As many have pointed out, Google is not as precise as
Deja Vu and it's difficult to find everything. But I'm pretty sure he
didn't copy anything; you'll see his position on this if you read the
whole thread.

David W. Fenton

unread,
Sep 21, 2005, 11:43:01 PM9/21/05
to
mbpa...@pacbell.net.invalid (Mike Preston) wrote in
news:43319aea....@news.INDIVIDUAL.NET:

> I have a offline version of API002 as of 4/14/02 and it is
> identical to what exists today. So, if there were any changes,
> they were a long time ago.

Does everyone know about the WayBack Machine?

http://archive.org

It archives web pages on the Internet on a regular basis. If you go
to:

http://web.archive.org/web/*/http://http://www.mvps.org/access/api/ap
i0002.htm

you can see the history of that page. If you compare the first and
last versions of it, there is really very little difference. Note,
though, that the last version in the archive is not the same as the
version currently on the site.

I don't know what the kerfuffle is here, but just thought it was a
good place to plug the WayBack Machine for resolving this kind of
dispute.

--
David W. Fenton http://www.bway.net/~dfenton
dfenton at bway dot net http://www.bway.net/~dfassoc

jimfo...@compumarc.com

unread,
Sep 22, 2005, 10:47:43 AM9/22/05
to

Many thanks David. It's great to know that site exists. I obviously
did not see api0002.htm back then.

James A. Fortune

Larry Linson

unread,
Sep 23, 2005, 1:22:06 PM9/23/05
to
"lylefair" <lyle...@yahoo.ca> wrote

> So if someone stands on mine, I don't mind,
> even if she forgets to wear a mini, ooops, I
> mean even if he/she forgets to say, "Conceived
> while standing on Lyle's shoulders".

Conceived? Ooops.

That is a really difficult position for conception, Lyle. :-)


0 new messages