[API]
GetOpenFileNameA
GetOpenFileNameW
lstrlenA
lstrlenW
LocalAlloc
LocalFree
RtlMoveMemory

[INCLUDE]
OPENFILENAME
UIntAddUInt
PeekS

[DEFINE]
Private Type GetOpenFileNameStruct
  hMem As Long
  hMemPos As Long
  hMemEnd As Long
  LenPath As Long
  End Type
Private Const GetOpenFileNameStructLen As Long = 16&

[CODE]
Public Function GetOpenFileName_MultiOpen(ByRef xType1 As OPENFILENAME, ByVal OpenMultipleFiles As Boolean) As Long
  Dim xType2 As OPENFILENAME_Real
  Dim xType3 As GetOpenFileNameStruct
  Dim xLong1 As Long
  Dim xChar1 As String

  Call OPENFILENAME_Patch(xType1, xType2)
  xType2.Flags = &H81004 - &H200 * CLng(OpenMultipleFiles)
  If IsUnicode Then
    xLong1 = GetOpenFileNameW(xType2)
    Else
    xLong1 = GetOpenFileNameA(xType2)
    End If
  If Not xLong1 = 0& Then
    xChar1 = String(OPENFILENAME_DataSize, vbNullChar)
    If IsUnicode Then
      Call RtlMoveMemory(ByVal StrPtr(xChar1), ByVal xType2.lpstrFile, OPENFILENAME_DataSizeW)
      Else
      Call RtlMoveMemory(ByVal xChar1, ByVal xType2.lpstrFile, OPENFILENAME_DataSize)
      End If
    xType3.LenPath = InStr(xChar1, vbNullChar)
    xType3.hMemEnd = InStr(xType3.LenPath, xChar1, vbNullChar & vbNullChar)
    If Not xType3.hMemEnd = 0& Then
      If xType3.LenPath = xType3.hMemEnd Then
        xType3.LenPath = 0&
        'xType3.hMemPos = 0&
        Else
        xType3.hMemPos = xType3.LenPath ' + 1&
        xType3.LenPath = xType3.LenPath - 1&
        End If
      'xType3.hMemEnd = xType3.hMemEnd + 1&
      GetOpenFileName_MultiOpen = LocalAlloc(0&, GetOpenFileNameStructLen)
      If Not GetOpenFileName_MultiOpen = 0& Then
        xType3.hMem = xType2.lpstrFile
        xType2.lpstrFile = 0&
        If IsUnicode Then
          xType3.hMemPos = xType3.hMemPos * 2&
          xType3.hMemEnd = xType3.hMemEnd * 2&
          xType3.LenPath = xType3.LenPath * 2&
          End If
        UIntAddUInt xType3.hMemEnd, xType3.hMem
        UIntAddUInt xType3.hMemPos, xType3.hMem
        Call RtlMoveMemory(ByVal GetOpenFileName_MultiOpen, xType3, GetOpenFileNameStructLen)
        End If
      End If
    End If
  Call OPENFILENAME_Free(xType2)
  End Function

Public Function GetOpenFileName_MultiEnum(ByRef hOpenFiles As Long, ByRef xFilename As String) As Boolean
  Dim xType1 As GetOpenFileNameStruct
  Dim xLong1 As Long

  If hOpenFiles = 0& Then
    xFilename = ""
    Else
    Call RtlMoveMemory(xType1, ByVal hOpenFiles, GetOpenFileNameStructLen)
    If xType1.LenPath = 0& Then
      xFilename = PeekS(xType1.hMemPos)
      Else
      xFilename = PeekS(xType1.hMem, xType1.LenPath) + "\" + PeekS(xType1.hMemPos)
      End If
    If IsUnicode Then
      xLong1 = lstrlenW(xType1.hMemPos)
      xType1.hMemPos = xType1.hMemPos + (xLong1 + 1&) * 2&
      Else
      xLong1 = lstrlenA(xType1.hMemPos)
      xType1.hMemPos = xType1.hMemPos + xLong1 + 1&
      End If
    GetOpenFileName_MultiEnum = True
    If xType1.hMemPos = xType1.hMemEnd Then
      Call GetOpenFileName_MultiClose(hOpenFiles)
      GoTo Finished
      End If
    Call RtlMoveMemory(ByVal hOpenFiles, xType1, GetOpenFileNameStructLen)
Finished:
    End If
  End Function

Public Sub GetOpenFileName_MultiClose(ByRef hOpenFiles As Long)
  Dim xType1 As GetOpenFileNameStruct
  
  If Not hOpenFiles = 0& Then
    Call RtlMoveMemory(xType1, ByVal hOpenFiles, GetOpenFileNameStructLen)
    Call LocalFree(xType1.hMem)
    Call LocalFree(hOpenFiles)
    hOpenFiles = 0&
    End If
  End Sub
