If you are interesting in saving a Folder path using API, the following is the code. This was written in Visual Basic 5 and works on Windows 10.
This is the code for the Main Form:
This is the code for the Module:
This is the code for the Main Form:
Code:
Dim qwDownloadPath As String
qwDownloadPath = BrowseFolders(hWnd, "Please Select a Folder:", BrowseForFolders, CSIDL_DRIVES)
' MsgBox "You selected the following path: " & qwDownloadPath, vbOKOnly, "Download Path"
Code:
Private Type BROWSEINFO
hwndOwner As Long ' A handle to the owner window for the dialog box.
pidlRoot As Long ' A PIDL that specifies the location of the root folder from which to start browsing.
pszDisplayName As Long ' Pointer to a buffer to receive the display name of the folder selected by the user. The size of this buffer is assumed to be MAX_PATH characters.
lpszTitle As Long ' Pointer to a null-terminated string that is displayed above the tree view control in the dialog box. This string can be used to specify instructions to the user.
ulFlags As Long ' Flags that specify the options for the dialog box.
lpfn As Long ' Pointer to an application-defined function that the dialog box calls when an event occurs. For more information, see the BrowseCallbackProc function. This member can be NULL.
lParam As Long ' An application-defined value that the dialog box passes to the callback function, if one is specified in lpfn.
iImage As Long ' An integer value that receives the index of the image associated with the selected folder, stored in the system image list.
End Type
'Browsing type.
Public Enum BrowseType
BrowseForFolders = &H1
BrowseForComputers = &H1000
BrowseForPrinters = &H2000
BrowseForEverything = &H4000
End Enum
'Folder Type
Public Enum FolderType
CSIDL_DESKTOP = &H0
CSIDL_PROGRAMS = &H2
CSIDL_CONTROLS = &H3
CSIDL_PRINTERS = &H4
CSIDL_PERSONAL = &H5
CSIDL_FAVORITES = &H6
CSIDL_STARTUP = &H7
CSIDL_RECENT = &H8
CSIDL_SENDTO = &H9
CSIDL_DESKTOPDIRECTORY = &H10
CSIDL_DRIVES = &H11
CSIDL_NETWORK = &H12
CSIDL_NETHOOD = &H13
CSIDL_FONTS = &H14
CSIDL_TEMPLATES = &H15
CSIDL_COMMON_STARTMENU = &H16
CSIDL_COMMON_PROGRAMS = &H17
CSIDL_COMMON_STARTUP = &H18
CSIDL_COMMON_DESKTOPDIRECTORY = &H19
CSIDL_INTERNET_CACHE = &H20
CSIDL_COOKIES = &H21
CSIDL_HISTORY = &H22
CSIDL_COMMON_APPDATA = &H23
CSIDL_WINDOWS = &H24
CSIDL_SYSTEM = &H25
CSIDL_PROGRAM_FILES = &H26
CSIDL_MYPICTURES = &H27
CSIDL_PROFILE = &H28
CSIDL_SYSTEMX86 = &H29
CSIDL_ADMINTOOLS = &H30
CSIDL_CONNECTIONS = &H31
CSIDL_COMMON_MUSIC = &H35
CSIDL_COMMON_PICTURES = &H36
CSIDL_COMMON_VIDEO = &H37
CSIDL_RESOURCES = &H38
CSIDL_RESOURCES_LOCALIZED = &H39
CSIDL_FLAG_PER_USER_INIT = &H800
CSIDL_FLAG_NO_ALIAS = &H1000
CSIDL_FLAG_DONT_VERIFY = &H4000
CSIDL_FLAG_CREATE = &H8000
CSIDL_BITBUCKET = &HA
CSIDL_STARTMENU = &HB
CSIDL_MYDOCUMENTS = &HC
CSIDL_MYMUSIC = &HD
CSIDL_MYVIDEO = &HE
CSIDL_APPDATA = &H1A
CSIDL_CDBURN_AREA = &H3B
CSIDL_COMMON_ADMINTOOLS = &H2F
CSIDL_COMMON_ALTSTARTUP = &H1E
CSIDL_COMMON_DOCUMENTS = &H2E
CSIDL_COMMON_FAVORITES = &H1F
CSIDL_COMMON_OEM_LINKS = &H3A
CSIDL_COMMON_TEMPLATES = &H2D
CSIDL_COMPUTERSNEARME = &H3D
CSIDL_FLAG_MASK = &HFF00
CSIDL_LOCAL_APPDATA = &H1C
CSIDL_PRINTHOOD = &H1B
CSIDL_PROGRAM_FILES_COMMON = &H2B
CSIDL_PROGRAM_FILES_COMMONX86 = &H2C
CSIDL_PROGRAM_FILESX86 = &H2A
End Enum
Private Const MAX_PATH = 260
' Part of: ulFlags
Public Const BIF_RETURNONLYFSDIRS As Long = &H1 ' Only return file system directories. If the user selects folders that are not part of the file system, the OK button is grayed.
Public Const BIF_DONTGOBELOWDOMAIN As Long = &H2 ' Do not include network folders below the domain level in the dialog box's tree view control.
Public Const BIF_STATUSTEXT As Long = &H4 ' Include a status area in the dialog box. The callback function can set the status text by sending messages to the dialog box. This flag is not supported when BIF_NEWDIALOGSTYLE is specified.
Public Const BIF_RETURNFSANCESTORS As Long = &H8 ' Only return file system ancestors. An ancestor is a subfolder that is beneath the root folder in the namespace hierarchy. If the user selects an ancestor of the root folder that is not part of the file system, the OK button is grayed.
Public Const BIF_EDITBOX As Long = &H10 ' Version 4.71. Include an edit control in the browse dialog box that allows the user to type the name of an item.
Public Const BIF_VALIDATE As Long = &H20 ' Version 4.71. If the user types an invalid name into the edit box, the browse dialog box calls the application's BrowseCallbackProc with the BFFM_VALIDATEFAILED message. This flag is ignored if BIF_EDITBOX is not specified.
Public Const BIF_NEWDIALOGSTYLE As Long = &H40 ' Version 5.0. Use the new user interface. Setting this flag provides the user with a larger dialog box that can be resized. The dialog box has several new capabilities, including: drag-and-drop capability within the dialog box, reordering, shortcut menus, new folders, delete, and other shortcut menu commands. Note If COM is initialized through CoInitializeEx with the COINIT_MULTITHREADED flag set, SHBrowseForFolder fails if BIF_NEWDIALOGSTYLE is passed.
Public Const BIF_BROWSEINCLUDEURLS As Long = &H80 ' Version 5.0. The browse dialog box can display URLs. The BIF_USENEWUI and BIF_BROWSEINCLUDEFILES flags must also be set. If any of these three flags are not set, the browser dialog box rejects URLs. Even when these flags are set, the browse dialog box displays URLs only if the folder that contains the selected item supports URLs. When the folder's IShellFolder::GetAttributesOf method is called to request the selected item's attributes, the folder must set the SFGAO_FOLDER attribute flag. Otherwise, the browse dialog box will not display the URL.
Public Const BIF_UAHINT As Long = &H100 ' Version 6.0. When combined with BIF_NEWDIALOGSTYLE, adds a usage hint to the dialog box, in place of the edit box. BIF_EDITBOX overrides this flag.
Public Const BIF_NONEWFOLDERBUTTON As Long = &H200 ' Version 6.0. Do not include the New Folder button in the browse dialog box.
Public Const BIF_NOTRANSLATETARGETS As Long = &H400 ' Version 6.0. When the selected item is a shortcut, return the PIDL of the shortcut itself rather than its target.
Public Const BIF_BROWSEFORCOMPUTER As Long = &H1000 ' Only return computers. If the user selects anything other than a computer, the OK button is grayed.
Public Const BIF_BROWSEFORPRINTER As Long = &H2000 ' Only allow the selection of printers. If the user selects anything other than a printer, the OK button is grayed. In Windows XP and later systems, the best practice is to use a Windows XP-style dialog, setting the root of the dialog to the Printers and Faxes folder (CSIDL_PRINTERS).
Public Const BIF_BROWSEINCLUDEFILES As Long = &H4000 ' Version 4.71. The browse dialog box displays files as well as folders.
Public Const BIF_SHAREABLE As Long = &H8000 ' Version 5.0. The browse dialog box can display sharable resources on remote systems. This is intended for applications that want to expose remote shares on a local system. The BIF_NEWDIALOGSTYLE flag must also be set.
Public Const BIF_BROWSEFILEJUNCTIONS As Long = &H10000 ' Windows 7 and later. Allow folder junctions such as a library or a compressed file with a .zip file name extension to be browsed.
Private Declare Sub CoTaskMemFree Lib "ole32.dll" (ByVal hMem As Long)
Private Declare Function lstrcat Lib "kernel32.dll" Alias "lstrcatA" (ByVal lpString1 As String, ByVal lpString2 As String) As Long
Private Declare Function SHBrowseForFolder Lib "shell32.dll" (lpbi As BROWSEINFO) As Long
Private Declare Function SHGetPathFromIDList Lib "shell32.dll" (ByVal pidList As Long, ByVal lpBuffer As String) As Long
Private Declare Function SHGetFolderLocation Lib "shell32.dll" (ByVal hwndOwner As Long, ByVal nFolder As Long, ByVal hToken As Long, ByVal dwReserved As Long, ppidl As Long) As Long
Public Function BrowseFolders(hwndOwner As Long, sMessage As String, _
Browse As BrowseType, ByVal RootFolder As FolderType) As String
Dim Nullpos As Integer
Dim qwFolderID As Long
Dim qwFolderPath As String
Dim qwBI As BROWSEINFO
Dim RootID As Long
SHGetFolderLocation hwndOwner, RootFolder, 0, 0, RootID
qwBI.hwndOwner = hwndOwner
If RootID <> 0 Then qwBI.pidlRoot = RootID
qwBI.lpszTitle = lstrcat(sMessage, "")
qwBI.ulFlags = BIF_NEWDIALOGSTYLE ' Starts at Desktop level
' qwBI.ulFlags = BIF_RETURNONLYFSDIRS ' Starts at root level
' qwBI.ulFlags = Browse ' Non-expandeable dialog box
qwFolderID = SHBrowseForFolder(qwBI)
If qwFolderID <> 0 Then
qwFolderPath = String(MAX_PATH, 0)
SHGetPathFromIDList qwFolderID, qwFolderPath ' Converts the PIDL to a Path
Call CoTaskMemFree(qwFolderID)
Nullpos = InStr(qwFolderPath, vbNullChar)
If Nullpos <> 0 Then
qwFolderPath = Left(qwFolderPath, Nullpos - 1)
End If
End If ' qwFolderID <> 0
BrowseFolders = qwFolderPath
Call CoTaskMemFree(qwBI.pidlRoot)
End Function