GetOpenFileName: lpstrFile vs lpstrFileTitle??

  • Thread starter Thread starter (PeteCresswell)
  • Start date Start date
P

(PeteCresswell)

I've got some code that I cobbled together and which has been working for a few
years - but it only handles single file selections.

Now I'm trying to make it handle multiple file selections.

I can get the CommonFile dialog to accept multiple selections, but as soon as I
specify too long a file list, it dies.

Let's assume that the user will never, ever select file titles whose length sums
up to more than 4096 bytes.

Can anybody elucidate the distinction between lpstrFile and lpstrFileTitle?

I'm guessing that one of their accompanying "nMax" parms needs to be reamed out
to something around 4096... but I'm not having any luck...
 
I'm going from memory here, Pete, so don't take this as gospel without
testing it, but my memory is that lpstrFileTitle is only relevant when *not*
selecting multiple files. When selecting multiple files, lpstrFile returns
the path, followed by a null character, followed by a null-character
separated list of selected file names. For example, here's the result of a
test in which I've replaced the null characters with "*" for readability ...

? getopenfilename2(0,"","","",0)
C:\Documents and Settings\Brendan Reynolds\My
Documents\BJECAP02*BJECAP02.ICO*BJECAP02.ldb*Thumbs.db*BJECAP02.MDB*BJECAP02.LOG*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
**

Here's some of the code that produced this result ...

Public Function GetOpenFileName2(Owner As Long, File As String, Filter As
String, _
Title As String, FilterIndex As Long) As String

Const strcProcedure = "GetOpenFileName"

Dim ofn As OPENFILENAME
Dim lngExtendedError As Long

With ofn
.Flags = OFN_ALLOWMULTISELECT Or OFN_EXPLORER
.hwndOwner = Owner
.lpstrCustomFilter = String$(40, vbNullChar)
.lpstrDefExt = "MDB"
.lpstrFile = File & String$(2048 - Len(File), vbNullChar)
.lpstrFileTitle = String$(2048, vbNullChar)
.lpstrFilter = Filter
.lpstrInitialDir = CurrentProject.Path
.lpstrTitle = Title
.lStructSize = Len(ofn)
.nFilterIndex = FilterIndex
.nMaxCustFilter = Len(.lpstrCustomFilter)
.nMaxFile = Len(.lpstrFile)
.nMaxFileTitle = Len(.lpstrFileTitle)
End With

If apiGetOpenFileName(ofn) = 0 Then
lngExtendedError = apiCommDlgExtendedError()
Select Case lngExtendedError
'error handling omitted for brevity ...
End Select
Else
GetOpenFileName2 = Replace(ofn.lpstrFile, vbNullChar, "*")
End If

End Function
 
Per Brendan Reynolds:
I'm going from memory here, Pete, so don't take this as gospel without
testing it, but my memory is that lpstrFileTitle is only relevant when *not*
selecting multiple files. When selecting multiple files, lpstrFile returns
the path, followed by a null character, followed by a null-character
separated list of selected file names. For example, here's the result of a
test in which I've replaced the null characters with "*" for readability ...

Thanks. That got me out of the woods.

One tip for others who might be playing with it in the Immediate window: I had
the bright idea of replacing vbNullChar with vbCrlf instead if "*". Naturally
2048 of those little guys exceeded the capacity of the immediate window.

So I wound up nesting two Replace() calls. The first one replaces vbNullChar &
vbNullChar with "" - effectively trimming all of the trailing nulls except maybe
one.
 
I use a 'TrimNull' function with an optional 'boolTwoNulls' argument. When
selecting a single file, the first null character marks the end of the
returned file name, so I let the optional argument default to False and trim
the string at the first null character. When selecting multiple files, you
can pass True as the optional argument, and trim the string at the first
occurrence of two null characters ...

Private Function TrimNull(ByRef strTrimThis As String, _
Optional ByRef boolTwoNulls As Boolean) As String

Dim lngPos As Long
Dim strFindThis As String
Dim strTemp As String

If boolTwoNulls Then
strFindThis = vbNullChar & vbNullChar
Else
strFindThis = vbNullChar
End If
lngPos = InStr(1, strTrimThis, strFindThis)
If lngPos > 0 Then
strTemp = Left$(strTrimThis, lngPos - 1)
Else
strTemp = strTrimThis
End If
If Len(strTemp) > 0 Then
If Right$(strTemp, 1) = vbNullChar Then
strTemp = Left$(strTemp, Len(strTemp) - 1)
End If
End If
TrimNull = strTemp

End Function
 
Back
Top