in vsintegration/src/FSharp.ProjectSystem.PropertyPages/Common/Utils.vb [633:721]
Friend Function GetFilesViaBrowse(ByVal ServiceProvider As System.IServiceProvider, ByVal ParentWindow As IntPtr, _
ByVal InitialDirectory As String, ByVal DialogTitle As String, _
ByVal Filter As String, ByVal FilterIndex As UInteger, ByVal MutiSelect As Boolean, _
Optional ByVal DefaultFileName As String = Nothing, _
Optional ByVal NeedThrowError As Boolean = False) As ArrayList
Dim uishell As IVsUIShell = _
CType(ServiceProvider.GetService(GetType(IVsUIShell)), IVsUIShell)
Dim fileNames As New ArrayList()
InitialDirectory = NormalizeInitialDirectory(InitialDirectory)
If InitialDirectory = "" Then
InitialDirectory = Nothing
End If
Filter = GetNativeFilter(Filter)
Dim MaxPathName As Integer = Interop.win.MAX_PATH + 1
If MutiSelect Then
MaxPathName = (Interop.win.MAX_PATH + 1) * VSDPLMAXFILES
End If
Dim vsOpenFileName As VSOPENFILENAMEW()
Dim defaultName(MaxPathName) As Char
If DefaultFileName IsNot Nothing Then
DefaultFileName.CopyTo(0, defaultName, 0, DefaultFileName.Length)
End If
Dim stringMemPtr As IntPtr = System.Runtime.InteropServices.Marshal.AllocHGlobal(MaxPathName * 2 + 2)
System.Runtime.InteropServices.Marshal.Copy(defaultName, 0, stringMemPtr, defaultName.Length)
Try
vsOpenFileName = New VSOPENFILENAMEW(0) {}
vsOpenFileName(0).lStructSize = CUInt(System.Runtime.InteropServices.Marshal.SizeOf(vsOpenFileName(0)))
vsOpenFileName(0).hwndOwner = ParentWindow
vsOpenFileName(0).pwzDlgTitle = DialogTitle
vsOpenFileName(0).nMaxFileName = CUInt(MaxPathName)
vsOpenFileName(0).pwzFileName = stringMemPtr
vsOpenFileName(0).pwzInitialDir = InitialDirectory
vsOpenFileName(0).pwzFilter = Filter
vsOpenFileName(0).nFilterIndex = FilterIndex
vsOpenFileName(0).nFileOffset = 0
vsOpenFileName(0).nFileExtension = 0
vsOpenFileName(0).dwHelpTopic = 0
If MutiSelect Then
vsOpenFileName(0).dwFlags = &H200
Else
vsOpenFileName(0).dwFlags = 0
End If
Dim hr As Integer = uishell.GetOpenFileNameViaDlg(vsOpenFileName)
If VSErrorHandler.Succeeded(hr) Then
Dim buffer(MaxPathName) As Char
System.Runtime.InteropServices.Marshal.Copy(stringMemPtr, buffer, 0, buffer.Length)
Dim path As String = Nothing
Dim i As Integer = 0
For j As Integer = 0 To buffer.Length - 1
If buffer(j) = Chr(0) Then
If i = j Then
Exit For
End If
If i = 0 Then
path = New String(buffer, 0, j)
Else
fileNames.Add(path & IO.Path.DirectorySeparatorChar & New String(buffer, i, j - i))
End If
i = j + 1
End If
Next
If fileNames.Count = 0 AndAlso path IsNot Nothing Then
fileNames.Add(path)
End If
ElseIf NeedThrowError Then
If hr = Interop.win.OLE_E_PROMPTSAVECANCELLED Then
Else
VSErrorHandler.ThrowOnFailure(hr)
End If
End If
Finally
System.Runtime.InteropServices.Marshal.FreeHGlobal(stringMemPtr)
End Try
Return fileNames
End Function