Option Explicit
    '----------------------------------------------------------------------
    ' 64 bit VBA 7 version of File and Folder Browswers
    ' FileBrowseOpen() ' FileBrowseSave() ' FolderBrowse()
    '----------------------------------------------------------------------
     
    Public Declare PtrSafe Function SendMessageA Lib "user32" _
    (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As LongPtr
     
    Private Declare PtrSafe Function SHBrowseForFolder Lib "shell32.dll" _
    Alias "SHBrowseForFolderA" (lpBrowseInfo As BROWSEINFO) As LongPtr
     
    Private Declare PtrSafe Function SHGetPathFromIDList Lib "shell32.dll" _
    Alias "SHGetPathFromIDListA" (ByVal pidList As LongPtr, ByVal lpBuffer As String) As Boolean
     
    Private Declare PtrSafe Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMem As LongPtr)
     
    Private Declare PtrSafe Function GetOpenFileName Lib "comdlg32.dll" Alias _
    "GetOpenFileNameA" (pOpenfilename As OPENFILENAME) As Long
     
    Private Declare PtrSafe Function GetSaveFileName Lib "comdlg32.dll" Alias _
    "GetSaveFileNameA" (pOpenfilename As OPENFILENAME) As Long
     
    Private Const BIF_RETURNONLYFSDIRS As Long = 1
    Private Const CSIDL_DRIVES As Long = &H11
    Private Const WM_USER As Long = &H400
    Private Const MAX_PATH As Long = 260
     
    '// message from browser
    Private Const BFFM_INITIALIZED As Long = 1
    Private Const BFFM_SELCHANGED As Long = 2
    Private Const BFFM_VALIDATEFAILEDA As Long = 3 '// lParam:szPath ret:1(cont),0(EndDialog)
    Private Const BFFM_VALIDATEFAILEDW As Long = 4 '// lParam:wzPath ret:1(cont),0(EndDialog)
    Private Const BFFM_IUNKNOWN As Long = 5 '// provides IUnknown to client. lParam: IUnknown*
     
    '// messages to browser
    Private Const BFFM_SETSTATUSTEXTA As Long = WM_USER + 100
    Private Const BFFM_ENABLEOK As Long = WM_USER + 101
    Private Const BFFM_SETSELECTIONA As Long = WM_USER + 102
    Private Const BFFM_SETSELECTIONW As Long = WM_USER + 103
    Private Const BFFM_SETSTATUSTEXTW As Long = WM_USER + 104
    Private Const BFFM_SETOKTEXT As Long = WM_USER + 105 '// Unicode only
    Private Const BFFM_SETEXPANDED As Long = WM_USER + 106 '// Unicode only
     
    Public Const OFN_ALLOWMULTISELECT As Long = &H200
    Public Const OFN_CREATEPROMPT As Long = &H2000
    Public Const OFN_ENABLEHOOK As Long = &H20
    Public Const OFN_ENABLETEMPLATE As Long = &H40
    Public Const OFN_ENABLETEMPLATEHANDLE As Long = &H80
    Public Const OFN_EXPLORER As Long = &H80000
    Public Const OFN_EXTENSIONDIFFERENT As Long = &H400
    Public Const OFN_FILEMUSTEXIST As Long = &H1000
    Public Const OFN_HIDEREADONLY As Long = &H4
    Public Const OFN_LONGNAMES As Long = &H200000
    Public Const OFN_NOCHANGEDIR As Long = &H8
    Public Const OFN_NODEREFERENCELINKS As Long = &H100000
    Public Const OFN_NOLONGNAMES As Long = &H40000
    Public Const OFN_NONETWORKBUTTON As Long = &H20000
    Public Const OFN_NOREADONLYRETURN As Long = &H8000& '*see comments
    Public Const OFN_NOTESTFILECREATE As Long = &H10000
    Public Const OFN_NOVALIDATE As Long = &H100
    Public Const OFN_OVERWRITEPROMPT As Long = &H2
    Public Const OFN_PATHMUSTEXIST As Long = &H800
    Public Const OFN_READONLY As Long = &H1
    Public Const OFN_SHAREAWARE As Long = &H4000
    Public Const OFN_SHAREFALLTHROUGH As Long = 2
    Public Const OFN_SHAREWARN As Long = 0
    Public Const OFN_SHARENOWARN As Long = 1
    Public Const OFN_SHOWHELP As Long = &H10
    Public Const OFN_ENABLESIZING As Long = &H800000
    Public Const OFS_MAXPATHNAME As Long = 260
     
        Type OPENFILENAME
            lStructSize As Long
            hwndOwner As LongPtr
            hInstance As LongPtr
            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 LongPtr
            lpfnHook As LongPtr
            lpTemplateName As String
            pvReserved As LongPtr
            dwReserved As Long
            FlagsEx As Long
    End Type
     
    Public Type BROWSEINFO
            hwndOwner As LongPtr
            pidlRoot As LongPtr
            pszDisplayName As String
            lpszTitle As String
            ulFlags As Long
            lpfnCallback As LongPtr
            lParam As LongPtr
            iImage As Long
    End Type
     
    '====== Folder Browser for 64 bit VBA 7 ========
    ' call: fold = FolderBrowse("", fldnam) ' full path
    ' fldnam: start path
    
    Public Function FolderBrowse(ByVal sDialogTitle As String, ByVal sInitFolder As String) As String
    Dim ReturnPath As String
     
    Dim b(MAX_PATH) As Byte
    Dim pItem As LongPtr
    Dim sFullPath As String
    Dim bi As BROWSEINFO
    Dim ppidl As Long
     
    sInitFolder = CorrectPath(sInitFolder)
     
    ' Note VBA windows and dialogs do not have an hWnd property.
    bi.hwndOwner = 0 'Windows Main Screen handle.
     
    bi.pidlRoot = 0 'ppidl
     
    bi.pszDisplayName = VarPtr(b(0))
    bi.lpszTitle = sDialogTitle
    bi.ulFlags = BIF_RETURNONLYFSDIRS
    If FolderExists(sInitFolder) Then bi.lpfnCallback = PtrToFunction(AddressOf BFFCallback)
    bi.lParam = StrPtr(sInitFolder)
     
    pItem = SHBrowseForFolder(bi)
     
    If pItem Then ' Succeeded
    sFullPath = space$(MAX_PATH)
    If SHGetPathFromIDList(pItem, sFullPath) Then
    ReturnPath = Left$(sFullPath, InStr(sFullPath, vbNullChar) - 1) ' Strip nulls
    CoTaskMemFree pItem
    End If
    End If
     
    If ReturnPath <> "" Then
    If Right$(ReturnPath, 1) <> "\" Then
    ReturnPath = ReturnPath & "\"
    End If
    End If
     
    FolderBrowse = ReturnPath
    End Function
     
    '@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@
    ' Display and use the File open dialog
    ' call  strFileName = ShowOpen()
    ' Public strFileName As String        ' full path
    '@~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~@
    Public Function ShowOpen() As String
    Dim strTemp As String
    Dim of As OPENFILENAME
    of.lStructSize = LenB(of)
    of.hwndOwner = 0
    of.lpstrFilter = "Excel files" & vbNullChar & "*.xlsx;*.xlsm" & vbNullChar & vbNullChar & vbNullChar
    of.lpstrFile = space$(256000)
    of.nMaxFile = 256001
    of.lpstrFileTitle = space$(256000)
    of.nMaxFileTitle = 256001
    of.lpstrInitialDir = CurDir
    of.lpstrTitle = "Excel files selection"
    of.flags = OFN_HIDEREADONLY + OFN_EXPLORER ' OFN_HIDEREADONLY + OFN_ALLOWMULTISELECT + OFN_EXPLORER
    If GetOpenFileName(of) Then
     strTemp = (Trim(of.lpstrFile))
     ShowOpen = strTemp
    End If
    End Function
 
    ' typedef int (CALLBACK* BFFCALLBACK)(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
    Private Function BFFCallback(ByVal hWnd As LongPtr, ByVal uMsg As LongPtr, ByVal lParam As LongPtr, ByVal sData As String) As LongPtr
    If uMsg = BFFM_INITIALIZED Then
    SendMessageA hWnd, BFFM_SETSELECTIONA, True, ByVal sData
    End If
    End Function
     
    Private Function PtrToFunction(ByVal lFcnPtr As LongPtr) As LongPtr
    PtrToFunction = lFcnPtr
    End Function
     
    Private Function CorrectPath(ByVal sPath As String) As String
    If Right$(sPath, 1) = "\" Then
    If Len(sPath) > 3 Then sPath = Left$(sPath, Len(sPath) - 1) ' Strip backslash from non-root
    Else
    If Len(sPath) = 2 Then sPath = sPath & "\" ' Append backslash to root
    End If
    CorrectPath = sPath
    End Function
     
    Public Function FolderExists(ByVal sFolderName As String) As Boolean
    Dim att As Long
    On Error Resume Next
    att = GetAttr(sFolderName)
    If Err.Number = 0 Then
    FolderExists = True
    Else
    Err.Clear
    FolderExists = False
    End If
    On Error GoTo 0
    End Function