Method | Description |
BrowseForFolder(hwnd,szTitle, nOptions, vRoot) | Runs the system tree-based dialog for choosing a folder. A simplified version of the SHBrowseForFolder can also be a special folder such as Printers, Programs, Desktop, Recycle Bin, and so on. |
CascadeWindows | Orders all the open top-level windows forming a cascade. |
ControlPanelItem(szDir) | Runs the specified Control Panel's property dialog. Note that szDir must be the name (file + ext) of a valid CPL file. |
EjectPC | Ejects the computer from its docking station. (For those computers that have an Eject command on the Start menu.) |
Explore(vDir) | Runs the Explorer from the specified folder. Note that vDir can also be a special folder such as Printers, Programs, Desktop, Recycle Bin, and so on. |
FileRun | Runs the system's Run dialog. The same as selecting Run from the Start menu. |
FindComputer | Runs the system's Find Computer dialog. The same as selecting Find | Computer from the Start menu. |
FindFiles | Runs the system's Find Files dialog. The same as selecting Find | Files or Folders from the Start menu. |
Help | The same as selecting Help from the Start menu. |
MinimizeAll | Clears the desktop iconizing all the open windows. The same as clicking the desktop button on the taskbar or pressing Windows + M. |
NameSpace(vDir) | Creates and returns a folder object for the specified path. Note that vDir can also be a special folder such as Printers, Programs, Desktop, Recycle Bin, and so on. |
Open(vDir) | Opens the specified folder as a separate window. Note that vDir can also be a special folder such as Printers, Programs, Desktop, Recycle Bin, and so on. |
RefreshMenu | Refreshes the Start menu to reflect possible changes. It's useful if you programmatically modify some of the system's policies that affect the Start menu. |
SetTime | Displays the dialog to set date and time. The same as double-clicking on the clock icon in the tray area. |
ShutdownWindows | Starts the standard procedure to exit Windows. The same as the Start menu's Shutdown command. |
Suspend | Suspends the computer. (For those computers that have a Suspend command on the Start menu.) |
TileHorizontally | Horizontally tiles all the top-level windows currently open. |
TileVertically | Vertically tiles all the top-level windows currently open. |
TrayProperties | Runs the Taskbar Properties system dialog. The same as selecting Settings | Taskbar from the Start menu. |
UndoMinimizeALL | Restores the desktop after a MinimizeAll command. The same as clicking the desktop button on the taskbar or pressing Shift + Windows + M. Note the double uppercase L in the name. |
Windows | Returns a collection of all the top-level windows currently open. |
Figure 7 Special Constants and their Folders
Constant | Special Folder | Virtual |
ssfBITBUCKET | The Recycle Bin. It refers to the directory where all the files marked for deletion are kept. | No |
ssfCONTROLS | The Control Panel. It includes all the Control Panel's applets. | Yes |
ssfDESKTOP | The Desktop. It's the object that represents the root of the shell's namespace. | Yes |
ssfDESKTOPDIRECTORY | System directory where all the files (mostly shortcuts) are displayed on the Windows desktop. | No |
ssfDRIVES | My Computer. It lists all the drives, printers, and devices on the local PC. | Yes |
ssfFAVORITES | System folder containing bookmarks to favorite folders. | No |
ssfFONTS | System folder containing the files for the installed fonts. | No |
ssfNETHOOD | System directory where references to all the objects appearing in the Network Neighborhood folder are kept. | No |
ssfNETWORK | The Network Neighborhood virtual folder. | Yes |
ssfPERSONAL | System folder containing personal files. | No |
ssfPRINTERS | System folder containing the links to the installed printers. | No |
ssfPROGRAMS | System folder which lists all the shortcuts in the Start | Programs menu. | No |
ssfRECENT | System folder containing all the recently used documents. Pointed by the Start | Documents menu. | No |
ssfSENDTO | System folder containing all the items of the Send To menu. | No |
ssfSTARTMENU | System folder containing all the customizable items of the Start menu. | No |
ssfSTARTUP | System folder containing links to all the programs that run at system startup. | No |
ssfTEMPLATES | System folder for all the document templates. | No |
Figure 12 Invoking a Properties Dialog
' Global var to store a reference to the Printers folder.
Private g_Printers As Folder
Private Sub Form_Load()
Dim o As New Shell
Set g_Printers = o.NameSpace(ssfPRINTERS)
' Starts from 1 to skip over "Add Printer"
List1.Clear
For i = 1 To g_Printers.Items.Count - 1
List1.AddItem g_Printers.Items.Item(i)
Next
Set o = Nothing
End Sub
Private Sub List1_Click()
Dim fi As FolderItem
List2.Clear
Set fi = g_Printers.Items.Item(List1.ListIndex + 1)
For i = 0 To fi.Verbs.Count - 1
List2.AddItem fi.Verbs.Item(i).Name
Next
End Sub
Private Sub List1_DblClick()
Dim fi As FolderItem
Set fi = g_Printers.Items.Item(List1.ListIndex + 1)
fi.InvokeVerb "P&roperties"
End Sub
Private Sub List2_DblClick()
Dim fi As FolderItem
Dim fiv As FolderItemVerb
Set fi = g_Printers.Items.Item(List1.ListIndex + 1)
Set fiv = fi.Verbs.Item(List2.ListIndex)
fiv.DoIt
End Sub
Figure 15 BrowseForFolderEx
Public Const MAX_PATH = 260
Type BROWSEINFO
hwndOwner 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
Declare Function SHBrowseForFolder Lib "shell32.dll" ( _
lpbi As BROWSEINFO _
) As Long
Declare Function SHGetPathFromIDList Lib "shell32.dll" ( _
ByVal pidl As String, _
ByVal pszPath As String _
) As Boolean
Declare Sub CoTaskMemFree Lib "ole32.dll" ( _
ByVal lpv As Long _
)
' --------------------------------------------------
' // Browse for folders and returns the full
' // path name as a string.
' --------------------------------------------------
Function BrowseForFolderEx( ByVal hWnd As Long, _
ByVal title As String, ByVal options As Long, _
Optional root As Variant ) As String
Dim bi As BROWSEINFO
Dim lpIdList As Long
Dim sFolderName As String
' initializes the BROWSEINFO structure
bi.hwndOwner = hWnd
bi.lpszTitle = title
bi.ulFlags = options
' defaults the missing argument to the DESKTOP
If IsMissing( root ) Then
bi.pidlRoot = 0
Else
bi.pidlRoot = root
End If
' calls the API function
lpIdList = SHBrowseForFolder( bi )
' converts the PIDL to a path name
If lpIdList Then
sFolderName = String(MAX_PATH, 0)
SHGetPathFromIDList lpIdList, sFolderName
BrowseForFolderEx = sFolderName
CoTaskMemFree lpIdList
End If
End Function
Figure 18 CustomDirList.ctl
Option Explicit
' This source code defines an ActiveX control that behaves like
' the Explorer's treeview. It lets you choose a directory from
' a treeview.
Private g_Shell As Shell
Private g_curFolder As String
Private Const sfDesktop = "Desktop"
Private Const sfMyComputer = "My Computer"
Private Const imlIdDesktop = 1
Private Const imlIdMyComputer = 2
Private Const imlIdFolder = 3
'----------------------------------------------------
'Events
'----------------------------------------------------
Event SelChange(ByVal dirName As String)
Event AddDirectory(ByVal dirName As String, canContinue As Boolean)
'----------------------------------------------------
' FOLDER property (read/write)
'----------------------------------------------------
Public Property Get Folder() As String
Folder = g_curFolder
End Property
Public Property Let Folder(ByVal New_Folder As String)
If New_Folder <> sfDesktop And New_Folder <> sfMyComputer Then
If Right(New_Folder, 1) <> "\" Then
New_Folder = New_Folder + "\"
End If
End If
g_curFolder = New_Folder
PropertyChanged "Folder"
SelectCurrentPath TreeView1
End Property
'----------------------------------------------------
'----------------------------------------------------
'Internal functions
'----------------------------------------------------
'----------------------------------------------------
Private Sub TreeView1_Expand(ByVal Node As ComctlLib.Node)
Node.Selected = True
If Node.Child = "..." Then
DoFillNode TreeView1, Node, Node.Tag
End If
End Sub
Private Sub TreeView1_KeyUp(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyPageUp Or KeyCode = vbKeyPageDown Or _
KeyCode = vbKeyUp Or KeyCode = vbKeyDown Then
g_curFolder = TreeView1.SelectedItem.Tag
RaiseEvent SelChange(g_curFolder)
End If
End Sub
Private Sub TreeView1_MouseUp(Button As Integer, Shift As Integer, _
x As Single, y As Single)
Dim n As Node
Set n = TreeView1.HitTest(x, y)
If Not n Is Nothing Then
g_curFolder = TreeView1.SelectedItem.Tag
RaiseEvent SelChange(g_curFolder)
End If
End Sub
Private Sub UserControl_Initialize()
Dim f As Folder
Dim nLen As Long
' get the My Computer's folder
Set g_Shell = New Shell
Set f = g_Shell.NameSpace(ssfDRIVES)
' initialize the member with the current path
g_curFolder = String(MAX_PATH, 0)
nLen = GetCurrentDirectory(MAX_PATH, g_curFolder)
g_curFolder = Left(g_curFolder, nLen)
' initialize the tree
DoInitTree TreeView1, f
SelectCurrentPath TreeView1
End Sub
Private Sub UserControl_Resize()
TreeView1.Move 0, 0, UserControl.Width, UserControl.Height
End Sub
Private Sub DoInitTree(ByVal Tree As TreeView, ByVal f As Folder)
Dim nodeDesktop, nodeMyComp, n As Node
Dim i, nPos As Integer
Dim sTemp As String
' add and expand the two main nodes
Set nodeDesktop = Tree.Nodes.Add(, , "R", "Desktop", imlIdDesktop)
Set nodeMyComp = Tree.Nodes.Add(nodeDesktop, tvwChild, , _
"My Computer", imlIdMyComputer)
Tree.Nodes.Item(1).Expanded = True
Tree.Nodes.Item(2).Expanded = True
nodeDesktop.Tag = sfDesktop
nodeMyComp.Tag = sfMyComputer
' add the other nodes
For i = 0 To f.Items.Count - 1
If f.Items.Item(i).IsFolder And f.Items.Item(i).IsFileSystem Then
' determine the icon for the folder
Dim sfi As SHFILEINFO
SHGetFileInfo f.Items.Item(i).path, 0, sfi, Len(sfi), _
SHGFI_ICON Or SHGFI_SMALLICON
ImageList1.ListImages.Add , , HIconToPicture(sfi.hIcon)
nPos = ImageList1.ListImages.Count
' add the drive node
Set n = AddTreeItem(Tree, nodeMyComp, f.Items.Item(i).Name, nPos)
' save the full path
n.Tag = f.Items.Item(i).path
' add a dummy node
AddDummyNode Tree, n
End If
Next
End Sub
Private Sub DoFillNode(ByVal Tree As TreeView, ByVal n As Node, _
ByVal path As String)
On Error GoTo Err_Handler
Dim canContinue As Boolean
Dim newNode As Node
Dim i As Integer
Dim dirName, sTemp As String
' remove the child dummy node
Tree.Nodes.Remove (n.index + 1)
' get the directory list
Dir1.path = path
For i = 0 To Dir1.ListCount - 1
dirName = GetDirFromPath(Dir1.List(i))
' notify that a new directory is being added
If Right(Dir1.path, 1) = "\" Then
sTemp = Dir1.path + dirName
Else
sTemp = Dir1.path + "\" + dirName
End If
canContinue = True
RaiseEvent AddDirectory(sTemp, canContinue)
If canContinue = True Then
Set newNode = AddTreeItem(Tree, n, dirName, imlIdFolder)
newNode.Tag = Dir1.List(i)
End If
' count the subdirs (if any) and add a dummy node
Dir2.path = Dir1.List(i)
If Dir2.ListCount > 0 Then
AddDummyNode Tree, newNode
End If
Next
Exit Sub
Err_Handler:
Dim sText, sTitle As String
If Err.Number = 68 Then
sText = path + " is not accessible." + vbCrLf + Err.Description
sTitle = "Exploring " + path
MsgBox sText, vbCritical Or vbRetryCancel, sTitle
End If
End Sub
Private Function AddTreeItem(ByVal Tree As TreeView, ByVal n As Node, _
ByVal text As String, ByVal index As Integer) As Node
Set AddTreeItem = Tree.Nodes.Add(n, tvwChild, , text, index)
'End If
End Function
Private Sub AddDummyNode(ByVal Tree As TreeView, ByVal n As Node)
AddTreeItem Tree, n, "...", imlIdFolder
End Sub
Private Sub SelectCurrentPath(ByVal Tree As TreeView)
Dim iStartPos, nPos, i As Integer
Dim bExit As Boolean
Dim curDrive, sTemp As String
' is it Desktop or My Computer?
If LCase(g_curFolder) = LCase(sfDesktop) Or _
LCase(g_curFolder) = LCase(sfMyComputer) Then
ExpandNode Tree, g_curFolder
Exit Sub
End If
' get and expand the current drive node
nPos = InStr(1, g_curFolder, "\")
curDrive = Left(g_curFolder, nPos)
ExpandNode Tree, curDrive
' scan the path for further directories
bExit = False
iStartPos = nPos
While Not bExit
i = InStr(iStartPos + 1, g_curFolder, "\")
If i = 0 Then
SelectNode Tree, g_curFolder
bExit = True
Else
iStartPos = i
sTemp = Left(g_curFolder, iStartPos - 1)
ExpandNode Tree, sTemp
End If
Wend
End Sub
Private Sub SelectNode(ByVal Tree As TreeView, ByVal dirName As String)
Dim path As String
Dim i As Integer
For i = 1 To Tree.Nodes.Count
path = Tree.Nodes.Item(i).Tag
If LCase(path) = LCase(dirName) Then
Tree.Nodes.Item(i).Selected = True
Tree.Nodes.Item(i).EnsureVisible
Exit For
End If
Next
End Sub
Private Sub ExpandNode(ByVal Tree As TreeView, ByVal dirName As String)
Dim path As String
Dim i As Integer
For i = 1 To Tree.Nodes.Count
path = Tree.Nodes.Item(i).Tag
If LCase(path) = LCase(dirName) Then
Tree.Nodes.Item(i).Selected = True
Tree.Nodes.Item(i).Expanded = True
Exit For
End If
Next
End Sub