VB.NET Favorites List Sample ReadMe File
January 27, 2002

Listing and manipulating Internet Explorer Favorites in VB5/6 was quite a code-intensive task. Just getting the Favorites listing itself could be daunting, particularly for a beginner. Automatically updating a displayed list of Favorites was literally impossible without MsgHook or something from Dan Appleman. 

Oleg Gdalevich's WebChecker Sample Application simplified the majority of this task quite a bit. It presents a comprehensive method for implementing Favorites manipulation that boils down loading the Favorites into a ListView control using two lines of code:

' Locate the Favorites folder
m_strFavFolder = GetSpecialFolderPath(0, CSIDL_FAVORITES)

' Fill listview with shortcuts
ListFiles m_strFavFolder, lvListView

Underneath this simple exterior lies three modules and a class module. It's quite complicated, and Oleg has, thankfully, done quite admirably in making it simple to use. The only thing missing was the automatic updating capability.

Things are different regarding listing and manipulating Favorites with VB.NET. Finding the Favorites path itself is greatly simplified, with no declarations required. Listing them becomes a simple task requiring little code that's easy to follow. And the automatic updates are a piece of cake.

This has all been bundled into a single sample. You're free to use this code as you see fit. If you redistribute this sample, it must be distributed intact.

The sample itself has just a few controls. The Favorites are listed within a ListView control set to Details mode and having a column labeled "Title". The ListView also has its Sorted property set to Ascending. An Up button is provided for maneuvering within the Favorites folder, while Add and Remove buttons help in dealing with Favorites themselves. Pages are displayed within an instance of the WebBrowser control.

Also, an ImageList control provides bitmaps for easier recognition of the entry types when the sample is running.

We only need a few things to get started, which we'll put at the top of the form's module above the Windows Form Designer Generated Code. System and System.IO are needed for a number of functions. We'll also use a module-level variable named FavePath to hold the current path to the Favorites folder. This will be manipulated within the sample.

Imports System
Imports
System.IO

Private
FavePath As String

When the form loads, the file you're now reading is opened as shown above. This uses Path.GetDirectoryName(Application.ExecutablePath) to get the folder the EXE file is in. The HTM file is in the same location.

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    ' Initialize the topic window with the ReadMe file
    AxWebBrowser1.Navigate2(Path.GetDirectoryName(Application.ExecutablePath) _
   
         & "\readme.htm")

Getting the path to the Favorites information has become the following one-liner.

    ' Locate the Favorites folder
    FavePath = Environment.GetFolderPath(Environment.SpecialFolder.Favorites)

Using the path to the Favorites folder, we'll then load the Favorites into the ListView. Don't worry about what this does quite yet ... I'll explain it shortly.

    LoadFaves()

One of the more interesting aspects of VB.NET is that system messages are quite easy to snag. We'll be wanting to keep an eye on the Favorites folder itself. If any changes are made to it, we'll update our own Favorites list to keep everything synchronized. Within the Form_Load event handler, we'll use a new instance of FileSystemWatcher to let us know when something happens within the Favorites folder.

    ' Create a new FileSystemWatcher and set its properties
    ' to keep an eye on the Faves folder and update as required
    Dim watcher As New FileSystemWatcher()
    watcher.Path = Environment.GetFolderPath(Environment.SpecialFolder.Favorites)

    ' Add event handlers.
    AddHandler watcher.Changed, AddressOf OnChanged
    AddHandler watcher.Created, AddressOf OnChanged
    AddHandler watcher.Deleted, AddressOf OnChanged
    AddHandler watcher.Renamed, AddressOf OnRenamed

    ' Begin watching.
    watcher.EnableRaisingEvents =
True

End Sub

The OnChanged and OnRenamed events will be described in a moment.

The LoadFaves routine, which is initially called during the Form_Load event handler, lists the Favorites in the ListView, including any subfolders. The subfolders are listed first as they are in the Favorites menu in Internet Explorer. 

First, we'll declare our variables and clear the ListView. Note that the subfolders and file names within the Favorites folder are retrieved as the variables are declared.

Private Sub LoadFaves()

    ' ** Load everything for the Favorites tab
    Dim dri As DirectoryInfo
    Dim fri As FileInfo
    Dim i As Integer = 0
    Dim di As New DirectoryInfo(FavePath)
    Dim diArr As DirectoryInfo() = di.GetDirectories
    Dim fiArr As FileInfo() = di.GetFiles()

    ' Fill the listview with folder names
    FavesList.Items.Clear()

Once this is done we can load the names of the subfolders in the Favorites folder.

    For Each dri In diArr
        Dim str As String
        Dim itemX As ListViewItem

        ' Add a space to the directory names to list them first
        ' Also add three periods to show there's more info...

        str = Chr(32) & dri.Name & "..."

        itemX =
New ListViewItem(str, 0)
        FavesList.Items.Add(itemX)
    Next dri

We then do the same with the *.url files. There's also a desktop.ini file in there, which we'll ignore.

    ' Fill the listview with shortcuts
    For Each fri In fiArr
        Dim strTemp As String
        Dim str(1) As String
        Dim itemX As ListViewItem

        If fri.Name <> "desktop.ini" Then
            ' List the item, discarding ".url"
            strTemp = Microsoft.VisualBasic.Strings.Left(fri.Name, _
                Len(fri.Name) - 4)
            str(0) = strTemp
            itemX =
New ListViewItem(str, 1)
            FavesList.Items.Add(itemX)
        End If

    Next fri

Finally, we'll disable the Remove button. When the list is loaded, no entries are selected. If the remove button is clicked under this condition, an error is generated. We'll simply not allow this to occur.

    RemoveButton.Enabled = False

End Sub

The OnChanged and OnRenamed event handlers are quite simple. Whenever any folder or file is changed, created, deleted, or renamed, the Favorites are reloaded in the ListView via the LoadFaves routine. Even on a PIII 500 with 320M RAM, the ListView will still generally be updated within a second of a new Favorite being added via Internet Explorer itself.

Private Sub OnChanged(ByVal source As Object, ByVal e As FileSystemEventArgs)

    ' Reload the Favorites
    LoadFaves()

End Sub

Private Sub OnRenamed(ByVal source As Object, ByVal e As RenamedEventArgs)

    ' Reload the Favorites
    LoadFaves()

End Sub

Now that everything is in place, we can start using the Favorites as listed. We can safely enable the Remove button the first time an entry in the list is highlighted.

Private Sub FavesList_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles FavesList.Click

    RemoveButton.Enabled =
True

End
Sub

When the ListView is double-clicked, we'll first look to see if a folder has been selected. If it has, we'll adjust the value of FavePath appropriatelyand reload the Favorites. We'll also enable the Up button so the user can go back to the previous level.

Private Sub FavesList_DoubleClick(ByVal sender As Object, ByVal e As System.EventArgs) Handles FavesList.DoubleClick

    Dim NextLevel As String
    Dim sr As StreamReader

    If Microsoft.VisualBasic.Strings.Right(FavesList.FocusedItem.Text, _
        3) = "..."
Then
        ' This is a folder, so open the next level
        NextLevel = Microsoft.VisualBasic.Strings.Mid(FavesList.FocusedItem.Text, _
            2, Len(FavesList.FocusedItem.Text) - 4)
        FavePath = FavePath & "\" & NextLevel

        LoadFaves()
        UpButton.Enabled =
True

If a Favorite has been double-clicked, we'll use the StreamReader class to open the *.url file, extract the link in the URL= entry and navigate to it. We'll then close the instance of the StreamReader class on the way out.

    Else
        ' Open the file to read.
        Try
            sr = File.OpenText(FavePath & "\" & _
                FavesList.FocusedItem.Text & ".url")
            ' Find the URL in each file
            ' When the end of the file is reached,
            ' return the value "-1".
            Dim x As String
 

            While
sr.Peek <> -1
                x = sr.ReadLine()
                If Microsoft.VisualBasic.Strings.Left(x, 4) = "URL=" = True Then
                    ' Navigate to the URL
                    AxWebBrowser1.Navigate2(Microsoft.VisualBasic.Strings.Right(x, Len(x) - 4))
                End If
            End While

            sr.Close()
        Catch ThisExcept As System.IO.FileNotFoundException
            ' Not sure why this error happens yet,
            ' but we'll do nothing anyhow
        End Try
    End If

End Sub

The Up button is disabled when the sample starts. As described in the FavesList_DoubleClick event handler, if a folder name is double-clicked in the ListView, the list switches to the contents of the selected folder. The Up button is used for reverting to the next highest level without moving above the Favorites folder itself. First, we'll parse the current value of FavePath to find out where we are and determine what the next-highest path is.

Private Sub UpButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles UpButton.Click

    Dim intPos As Integer

    ' Get the next-highest path
    intPos = Microsoft.VisualBasic.Strings.InStrRev(FavePath, "\")
    FavePath = Microsoft.VisualBasic.Strings.Left(FavePath, intPos - 1)

We'll then reload the ListView with the next highest path. 

    ' Reload the Favorites
    LoadFaves()

If the current value of FavePath is the Favorites folder, we'll disable the Up button so the user can go no higher.

    ' Set the condition of the Up button,
    ' topping out at the Faves folder
    If FavePath = Environment.GetFolderPath(Environment.SpecialFolder.Favorites) Then
        UpButton.Enabled =
False
    End If

End Sub

The Add button uses Internet Explorer's own Add Favorite dialog to allow the user to add the current page in any desired organizational scheme. This is quite similar to the VB5/6 method with a few twists.

Private Sub AddButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddButton.Click

    ' Add the current page to the Faves
    Dim UIHelper As New SHDocVw.ShellUIHelperClass()

    If
AxWebBrowser1.LocationURL <> "about:blank"
Then
        UIHelper.AddFavorite(AxWebBrowser1.LocationURL, _
            AxWebBrowser1.LocationName)
    End If

End Sub

The Remove button allows the user to delete favorites or complete folders from the Favorites folder. To do so, we use the new System.IO.Directory.Delete and System.IO.File.Delete methods. First we'll declare our variables and then check to see if we're dealing with a folder.

Private Sub RemoveButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RemoveButton.Click

    Dim intResponse As Integer
    Dim strFolder2Delete As String
    Dim strFave2Delete As String

    If Microsoft.VisualBasic.Strings.Right(FavesList.FocusedItem.Text, 3) = "..." Then

If it's a folder, we'll first ask for confirmation, then if it's confirmed, we'll delete the folder and everything in it using System.IO.Directory.Delete.

        ' This is a folder, so treat it as such
        strFolder2Delete = Microsoft.VisualBasic.Strings.Mid(FavesList.FocusedItem.Text, _
            2, Len(FavesList.FocusedItem.Text) - 4)
        intResponse = MessageBox.Show("Are you sure you want to delete the folder '" _
            & strFolder2Delete & "' and all of its contents?", _
            "Remove Folder?", MessageBoxButtons.YesNo, _
            MessageBoxIcon.Question)

        If intResponse = vbYes Then
            ' Delete the selected folder and anything in it
            strFolder2Delete = FavePath & "\" & strFolder2Delete
            System.IO.Directory.Delete(strFolder2Delete,
True)
        End If

If it's a page, we'll do the same using System.IO.File.Delete.

    Else
        ' If a page ...
        intResponse = MessageBox.Show("Are you sure you want to delete '" _
            & FavesList.FocusedItem.Text & "'?", _
            "Remove Favorite?", MessageBoxButtons.YesNo, _
            MessageBoxIcon.Question)

        If
intResponse = vbYes
Then
            ' Delete the Favorite
            strFave2Delete = FavePath & "\" & FavesList.FocusedItem.Text & ".url"
            System.IO.File.Delete(strFave2Delete)
        End If
    End If

End Sub

With this as a base, there are many other functions possible. A Favorites editor could also be constructed, and the same site-specific icons which appear on Internet Explorer's Favorites menu could also be used within the ListView. 

If you have questions or comments on this sample or this page, please email me via the HTML Help Center.

©2002 David Liske, Delmar Computing Services
All Rights Reserved