|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Visual Basic Browse/ PIDL / CSIDL
Routines SHBrowseForFolder: Browse for Folders New UI Features |
||
Posted: | Saturday May 17, 1997 | |
Updated: | Monday December 26, 2011 | |
Applies to: | VB4-32, VB5, VB6 | |
Developed with: | VB4-32, Windows 95 | |
OS restrictions: | None | |
Author: | VBnet - Randy Birch | |
Related: | BROWSE: SHBrowseForFolder: Browse Folders Dialog Overview SHBrowseForFolder: Browse for Folders Dialog SHBrowseForFolder: Browse for Folders Callback Overview SHBrowseForFolder: Pre-selecting Folders using a Browse Callback SHBrowseForFolder: Browse to Obtain Network Machines or Shares CSIDL / Folders: |
|
Prerequisites |
Internet Explorer 4 or better. |
|
This page is wider than I prefer
in order to to accommodate the Browse constant's descriptions. It will appear fine pasted into a VB
project.
As has been the history with past releases of Internet Explorer, new Shell32 functionality has become available in each version of Internet Explorer's Shell updates or the shell of newer operating systems. IE4 added the BIF_EDITBOX and BIF_VALIDATE callback functionality, allowing a Browse Dialog using a callback to retrieve a user's typed-in file or path name. Shell Version 5 (Windows 2000 and IE5) added BIF_BROWSEINCLUDEFILES which displays the dialog with both the normal folder/virtual folder chosen as well as files under those folders. Windows 2000, IE6 and Windows XP can use the BIF_USENEWUI flag providing within the Browse dialog a new user-interface including a larger dialog that can be resized, as well as several new capabilities including drag and drop within the dialog box, a new folder button, item reordering and a right-click context menu containing the standard commands you'd expect when selecting a file system or namespace item. This demo, loosely based on the original Browse demo code provided to VBnet by Brad Martinez, performs several functions. On load, a combo is populated with strings representing all available Constants, except those for the RISC platform. Illustrations 1/2/3 show setting up and calling an old-style Browse dialog, returning My Computer as the user's selection. Pictures 4/5/6 repeat this same selection using the new dialog UI and edit box. Figures 7/8/9 show the result of selecting a shortcut when BIF_NOTRANSLATESTARGETS is set. This demo does not utilize a callback - other pages on VBnet address adding that feature, something that would be trivial for this demo. This means the BIF_VALIDATE flag is of no value as it is meant to be used by the callback to signal the user's changing of the selection in the edit box. Remember that some of the items listed are available only on later OS versions. Use GetVersionEx() wrappers to restrict feature selection to valid options. The code shows doing this for one option - the BIF_NOTRANSLATETARGETS flag, which when set allows the user to select a shortcut and the dialog will return that shortcut as the full path. Normal pre-XP behavior is to resolve the selected shortcut and return the path to the actual item pointed to by the shortcut. Finally, it must be noted that while the new features provide access to the contents of virtual folders (i.e. Recycle Bin, Fonts, Internet etc), I can only strongly recommend that you do not use the return values from the Browse dialog to directly manipulate those files, especially Recycle Bin. |
BAS Module Code |
None |
|
Form Code |
This form isn't really too complicated; the Load event will set the appropriate captions. Add a command button (Command1), a combo (Combo1) with Sorted=True, six check boxes (Check1 through Check6) and four textboxes (Text1-Text4). Labels are optional. Size the combo, check boxes and Text3 and Text4 fairly wide. Add the following to the form: |
|
Option Explicit '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Copyright ©1996-2011 VBnet/Randy Birch, All Rights Reserved. ' Some pages may also contain other copyrights by the author. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ' Distribution: You can freely use this code in your own ' applications, but you may not reproduce ' or publish this code on any web site, ' online service, or distribute as source ' on any media without express permission. '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' Private Const VER_PLATFORM_WIN32_NT As Long = 2 Private Const S_OK As Long = 0 Private Const MAX_PATH As Long = 260 'BROWSEINFO.ulFlags values Private Const BIF_RETURNONLYFSDIRS As Long = &H1 'only file system directories Private Const BIF_DONTGOBELOWDOMAIN As Long = &H2 'no network folders below domain level Private Const BIF_STATUSTEXT As Long = &H4 'include status area for callback Private Const BIF_RETURNFSANCESTORS As Long = &H8 'only return file system ancestors Private Const BIF_EDITBOX As Long = &H10 'add edit box Private Const BIF_NEWDIALOGSTYLE As Long = &H40 'use the new dialog layout Private Const BIF_UAHINT As Long = &H100 Private Const BIF_NONEWFOLDERBUTTON As Long = &H200 'hide new folder button Private Const BIF_NOTRANSLATETARGETS As Long = &H400 'return lnk file Private Const BIF_USENEWUI As Long = BIF_NEWDIALOGSTYLE Or BIF_EDITBOX Private Const BIF_BROWSEFORCOMPUTER As Long = &H1000 'only return computers Private Const BIF_BROWSEFORPRINTER As Long = &H2000 'only return printers Private Const BIF_BROWSEINCLUDEFILES As Long = &H4000 'browse for everything Private Const BIF_SHAREABLE As Long = &H8000 'sharable resources, requires BIF_USENEWUI 'class ID values Private Const CSIDL_DESKTOP As Long = &H0 Private Const CSIDL_INTERNET As Long = &H1 Private Const CSIDL_PROGRAMS As Long = &H2 Private Const CSIDL_CONTROLS As Long = &H3 Private Const CSIDL_PRINTERS As Long = &H4 Private Const CSIDL_PERSONAL As Long = &H5 Private Const CSIDL_FAVORITES As Long = &H6 Private Const CSIDL_STARTUP As Long = &H7 Private Const CSIDL_RECENT As Long = &H8 Private Const CSIDL_SENDTO As Long = &H9 Private Const CSIDL_BITBUCKET As Long = &HA Private Const CSIDL_STARTMENU As Long = &HB Private Const CSIDL_MYDOCUMENTS As Long = &HC Private Const CSIDL_MYMUSIC As Long = &HD Private Const CSIDL_MYVIDEO As Long = &HE Private Const CSIDL_UNUSED1 As Long = &HF '&HF not currently implemented Private Const CSIDL_DESKTOPDIRECTORY As Long = &H10 Private Const CSIDL_DRIVES As Long = &H11 Private Const CSIDL_NETWORK As Long = &H12 Private Const CSIDL_NETHOOD As Long = &H13 Private Const CSIDL_FONTS As Long = &H14 Private Const CSIDL_TEMPLATES As Long = &H15 Private Const CSIDL_COMMON_STARTMENU As Long = &H16 Private Const CSIDL_COMMON_PROGRAMS As Long = &H17 Private Const CSIDL_COMMON_STARTUP As Long = &H18 Private Const CSIDL_COMMON_DESKTOPDIRECTORY As Long = &H19 Private Const CSIDL_APPDATA As Long = &H1A Private Const CSIDL_PRINTHOOD As Long = &H1B Private Const CSIDL_LOCAL_APPDATA As Long = &H1C Private Const CSIDL_ALTSTARTUP As Long = &H1D Private Const CSIDL_COMMON_ALTSTARTUP As Long = &H1E Private Const CSIDL_COMMON_FAVORITES As Long = &H1F Private Const CSIDL_INTERNET_CACHE As Long = &H20 Private Const CSIDL_COOKIES As Long = &H21 Private Const CSIDL_HISTORY As Long = &H22 Private Const CSIDL_COMMON_APPDATA As Long = &H23 Private Const CSIDL_WINDOWS As Long = &H24 Private Const CSIDL_SYSTEM As Long = &H25 Private Const CSIDL_PROGRAM_FILES As Long = &H26 Private Const CSIDL_MYPICTURES As Long = &H27 Private Const CSIDL_PROFILE As Long = &H28 Private Const CSIDL_SYSTEMX86 As Long = &H29 'RISC only Private Const CSIDL_PROGRAM_FILESX86 As Long = &H2A 'RISC only Private Const CSIDL_PROGRAM_FILES_COMMON As Long = &H2B Private Const CSIDL_PROGRAM_FILES_COMMONX86 As Long = &H2C 'RISC only Private Const CSIDL_COMMON_TEMPLATES As Long = &H2D Private Const CSIDL_COMMON_DOCUMENTS As Long = &H2E Private Const CSIDL_COMMON_ADMINTOOLS As Long = &H2F Private Const CSIDL_ADMINTOOLS As Long = &H30 Private Const CSIDL_CONNECTIONS As Long = &H31 Private Const CSIDL_COMMON_MUSIC As Long = &H35 Private Const CSIDL_COMMON_PICTURES As Long = &H36 Private Const CSIDL_COMMON_VIDEO As Long = &H37 Private Const CSIDL_RESOURCES As Long = &H38 Private Const CSIDL_RESOURCES_LOCALIZED As Long = &H39 Private Const CSIDL_COMMON_OEM_LINKS As Long = &H3A Private Const CSIDL_CDBURN_AREA As Long = &H3B Private Const CSIDL_UNUSED2 As Long = &H3C '&H3C not currently implemented Private Const CSIDL_COMPUTERSNEARME As Long = &H3D 'special flags Private Const CSIDL_FLAG_PER_USER_INIT As Long = &H800 Private Const CSIDL_FLAG_NO_ALIAS As Long = &H1000 Private Const CSIDL_FLAG_DONT_VERIFY As Long = &H4000 Private Const CSIDL_FLAG_CREATE As Long = &H8000 Private Const CSIDL_FLAG_MASK As Long = &HFF00 'windows-defined type OSVERSIONINFO Private Type OSVERSIONINFO OSVSize As Long dwVerMajor As Long dwVerMinor As Long dwBuildNumber As Long PlatformID As Long szCSDVersion As String * 128 End Type 'parameters for SHBrowseForFolder Private Type BROWSEINFO 'BI hOwner As Long pidlRoot As Long pszDisplayName As String lpszTitle As String ulFlags As Long lpfn As Long lParam As Long iImage As Long End Type Private Declare Function SHGetPathFromIDList Lib "shell32.dll" _ Alias "SHGetPathFromIDListA" _ (ByVal pidl As Long, _ ByVal pszPath As String) As Long Private Declare Function SHBrowseForFolder Lib "shell32.dll" _ Alias "SHBrowseForFolderA" _ (lpBrowseInfo As BROWSEINFO) As Long Private Declare Function SHGetSpecialFolderLocation Lib "shell32.dll" _ (ByVal hwndOwner As Long, _ ByVal nFolder As Long, _ pidl As Long) As Long Private Declare Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" _ (lpVersionInformation As OSVERSIONINFO) As Long Private Declare Sub CoTaskMemFree Lib "ole32.dll" _ (ByVal pv As Long) Private Sub Form_Load() Command1.Caption = "Browse" Check1.Caption = "Include files as well as folders in dialog" Check2.Caption = "Use new dialog style (resizable w/new folder button)" Check3.Caption = "Include edit box" Check4.Caption = "Use UA Hint (edit box overrides)" Check5.Caption = "Hide the New Folder button" Check6.Caption = "Return shortcut; don't traverse to file ( XP or later )" Text1.Text = "" Text2.Text = "" Text3.Text = "" Text4.Text = "" Check2_Click Check6.Enabled = IsWinXPPlus() Call LoadCombo End Sub Private Sub Command1_Click() Dim dwFlags As Long Dim sTitle As String Dim csidl As Long 'build dwFlags according to the options selected If Check1.Value = vbChecked Then dwFlags = dwFlags Or BIF_BROWSEINCLUDEFILES If Check2.Value = vbChecked Then dwFlags = dwFlags Or BIF_NEWDIALOGSTYLE If Check3.Value = vbChecked Then dwFlags = dwFlags Or BIF_EDITBOX If Check4.Value = vbChecked Then dwFlags = dwFlags Or BIF_UAHINT If Check5.Value = vbChecked Then dwFlags = dwFlags Or BIF_NONEWFOLDERBUTTON If Check6.Value = vbChecked Then dwFlags = dwFlags Or BIF_NOTRANSLATETARGETS sTitle = Combo1.List(Combo1.ListIndex) csidl = Combo1.ItemData(Combo1.ListIndex) Text4.Text = Browse(csidl, dwFlags, sTitle) End Sub Private Sub Combo1_Click() Dim csidl As Long csidl = Combo1.ItemData(Combo1.ListIndex) Text1.Text = csidl Text2.Text = "&H" & CStr(Hex(csidl)) End Sub Private Sub Check2_Click() Check3.Enabled = Check2.Value = vbChecked Check4.Enabled = Check2.Value = vbChecked Check5.Enabled = Check2.Value = vbChecked End Sub Private Function Browse(csidl As Long, BIF_FLAGS As Long, sTitle As String) As String Dim pidl As Long Dim bi As BROWSEINFO Dim sPath As String Dim pos As Integer 'Fill BROWSEINFO structure data With bi .hOwner = Me.hWnd .pidlRoot = CSIDLToPIDL(csidl) .lpszTitle = "Browsing " & sTitle .ulFlags = BIF_FLAGS .pszDisplayName = Space$(MAX_PATH) End With 'show dialog returning pidl to selected item pidl = SHBrowseForFolder(bi) 'if pidl is valid, parse & return the user's selection sPath = Space$(MAX_PATH) If SHGetPathFromIDList(ByVal pidl, ByVal sPath) Then 'SHGetPathFromIDList returns the absolute 'path to the selected item pos = InStr(sPath, Chr$(0)) If pos > 0 Then Browse = Left(sPath, pos - 1) End If 'pszDisplayName contains the string 'representing the users last selection. 'Even when SHGetPathFromIDList is empty, 'this should return the selection, making 'it the choice for obtaining user information 'when selecting Printers, Control Panel etc, 'or any of the other virtual folders that 'do not normally return a path pos = InStr(bi.pszDisplayName, Chr$(0)) If pos > 0 Then Text3.Text = Left(bi.pszDisplayName, pos - 1) Else Text3.Text = "" End If 'free the pidl Call CoTaskMemFree(pidl) End Function Private Function CSIDLToPIDL(ByVal csidl As Long) As Long Dim pidl As Long If csidl > 0 Then If SHGetSpecialFolderLocation(Me.hWnd, csidl, pidl) = S_OK Then CSIDLToPIDL = pidl End If Else CSIDLToPIDL = 0& End If End Function Private Function IsWinXPPlus() As Boolean 'returns True if running Windows XP or later Dim osv As OSVERSIONINFO osv.OSVSize = Len(osv) If GetVersionEx(osv) = 1 Then IsWinXPPlus = (osv.PlatformID = VER_PLATFORM_WIN32_NT) And _ (osv.dwVerMajor >= 5 And osv.dwVerMinor >= 1) End If End Function Private Sub LoadCombo() With Combo1 .AddItem "Desktop (default browse)": .ItemData(.NewIndex) = CSIDL_DESKTOP .AddItem "Internet Explorer (icon on desktop)" .ItemData(.NewIndex) = CSIDL_INTERNET .AddItem "Start Menu\Programs" .ItemData(.NewIndex) = CSIDL_PROGRAMS .AddItem "Control Panel" .ItemData(.NewIndex) = CSIDL_CONTROLS .AddItem "Printers" .ItemData(.NewIndex) = CSIDL_PRINTERS .AddItem "My Documents" .ItemData(.NewIndex) = CSIDL_PERSONAL .AddItem "Favorites (Current User)" .ItemData(.NewIndex) = CSIDL_FAVORITES .AddItem "Start Menu\Programs\Startup" .ItemData(.NewIndex) = CSIDL_STARTUP .AddItem "Recent (Current User)" .ItemData(.NewIndex) = CSIDL_RECENT .AddItem "SendTo (Current User)" .ItemData(.NewIndex) = CSIDL_SENDTO .AddItem "Recycle Bin (desktop)" .ItemData(.NewIndex) = CSIDL_BITBUCKET .AddItem "Start Menu (Current User)" .ItemData(.NewIndex) = CSIDL_STARTMENU .AddItem "WinXP+ : Logical My Documents desktop icon" .ItemData(.NewIndex) = CSIDL_MYDOCUMENTS .AddItem "WinXP+ : My Music folder" .ItemData(.NewIndex) = CSIDL_MYMUSIC .AddItem "WinXP+ : My Videos folder" .ItemData(.NewIndex) = CSIDL_MYVIDEO .AddItem "Desktop Directory (Current User)" .ItemData(.NewIndex) = CSIDL_DESKTOPDIRECTORY .AddItem "My Computer" .ItemData(.NewIndex) = CSIDL_DRIVES .AddItem "Network Neighborhood" .ItemData(.NewIndex) = CSIDL_NETWORK .AddItem "NetHood (Current User)" .ItemData(.NewIndex) = CSIDL_NETHOOD .AddItem "Fonts" .ItemData(.NewIndex) = CSIDL_FONTS .AddItem "Templates" .ItemData(.NewIndex) = CSIDL_TEMPLATES .AddItem "Start Menu (All Users) (NT or later)" .ItemData(.NewIndex) = CSIDL_COMMON_STARTMENU .AddItem "Programs (All Users) (NT or later)" .ItemData(.NewIndex) = CSIDL_COMMON_PROGRAMS .AddItem "Startup (All Users) (NT or later)" .ItemData(.NewIndex) = CSIDL_COMMON_STARTUP .AddItem "Desktop Directory (All Users)" .ItemData(.NewIndex) = CSIDL_COMMON_DESKTOPDIRECTORY .AddItem "Application Data (Current User)" .ItemData(.NewIndex) = CSIDL_APPDATA .AddItem "PrintHood (Current User)" .ItemData(.NewIndex) = CSIDL_PRINTHOOD .AddItem "Win2k+ : Application Data (Current User, non roaming)" .ItemData(.NewIndex) = CSIDL_LOCAL_APPDATA .AddItem "Non-localized Startup" .ItemData(.NewIndex) = CSIDL_ALTSTARTUP .AddItem "Non-localized Common Startup (NT or later)" .ItemData(.NewIndex) = CSIDL_COMMON_ALTSTARTUP .AddItem "Common Favorites" .ItemData(.NewIndex) = CSIDL_COMMON_FAVORITES .AddItem "Internet Cache" .ItemData(.NewIndex) = CSIDL_INTERNET_CACHE .AddItem "Internet Cookies" .ItemData(.NewIndex) = CSIDL_COOKIES .AddItem "Internet History" .ItemData(.NewIndex) = CSIDL_HISTORY .AddItem "Win2k+ : Application Data (All Users)" .ItemData(.NewIndex) = CSIDL_COMMON_APPDATA .AddItem "Win2k+ : Windows Directory" .ItemData(.NewIndex) = CSIDL_WINDOWS .AddItem "Win2k+ : System Directory" .ItemData(.NewIndex) = CSIDL_SYSTEM .AddItem "Win2k+ : Program Files" .ItemData(.NewIndex) = CSIDL_PROGRAM_FILES .AddItem "Win2k+ : My Pictures" .ItemData(.NewIndex) = CSIDL_MYPICTURES .AddItem "Win2k+ : User Profile (Current User)" .ItemData(.NewIndex) = CSIDL_PROFILE .AddItem "Win2k+ : Program Files\Common (NT or later)" .ItemData(.NewIndex) = CSIDL_PROGRAM_FILES_COMMON .AddItem "Templates (All Users) (NT or later)" .ItemData(.NewIndex) = CSIDL_COMMON_TEMPLATES .AddItem "Documents (All Users) (NT or later)" .ItemData(.NewIndex) = CSIDL_COMMON_DOCUMENTS .AddItem "Win2k+ : Administrative Tools (All Users)" .ItemData(.NewIndex) = CSIDL_COMMON_ADMINTOOLS .AddItem "Win2k+ : Administrative Tools (Current User)" .ItemData(.NewIndex) = CSIDL_ADMINTOOLS .AddItem "WinXP+ : Network and Dial-up Connections" .ItemData(.NewIndex) = CSIDL_CONNECTIONS .AddItem "WinXP+ : (shared music) All Users\My Music" .ItemData(.NewIndex) = CSIDL_COMMON_MUSIC .AddItem "WinXP+ : (shared pictures) All Users\My Pictures" .ItemData(.NewIndex) = CSIDL_COMMON_PICTURES .AddItem "WinXP+ : (shared video) All Users\My Video" .ItemData(.NewIndex) = CSIDL_COMMON_VIDEO .AddItem "WinXP+ : Resource Directory (themes parent folder)" .ItemData(.NewIndex) = CSIDL_RESOURCES .AddItem "WinXP+ : Localized Resource Directory" .ItemData(.NewIndex) = CSIDL_RESOURCES_LOCALIZED .AddItem "WinXP+ : Links to All Users OEM specific apps" .ItemData(.NewIndex) = CSIDL_COMMON_OEM_LINKS .AddItem "WinXP+ : CD Burning (USERPROFILE\Local Settings\Application Data\Microsoft\)" .ItemData(.NewIndex) = CSIDL_CDBURN_AREA .AddItem "WinXP+ : Computers Near Me (computered from Workgroup membership)" .ItemData(.NewIndex) = CSIDL_COMPUTERSNEARME .ListIndex = 3 'desktop (default browse) End With End Sub |
Comments |
|
|
|
|||||
|
|||||
|
|||||
Copyright ©1996-2011 VBnet and Randy Birch. All Rights Reserved. |