MRU Lists


MDI and SDI interfaces provide different ways to manage documents. Another tool that helps users manage documents is a Most Recently Used (MRU) list. The MRU list is a series of menu items (usually at the bottom of an application’s File menu) that displays the files most recently accessed by the user. If the user clicks on one of these menu items, the program reopens the corresponding file. Figure 10-10 shows an MRU list in a simple editing application.

image from book
Figure 10-10: An MRU list makes it easier for users to reopen the files they have used most recently.

By convention, these menu items begin with the accelerator characters 1, 2, 3, and so forth. If you opened the File menu shown in Figure 10-10 and pressed 2, for example, the program would reopen the file SDIEdit.sln.

When the user opens a new file or saves a file with a new name, that file is placed at the top of the list. Most applications display up to four items in the MRU list and, if the list ever contains more items, the oldest are removed.

Most applications remove a file from the MRU list if the applications try to open it and fail. For example, if the user selects an MRU menu item but the corresponding file has been removed from the system, the program removes the file’s menu item.

Building an MRU list isn’t too difficult in Visual Basic. The following code shows a simple MruList class. The class has its own private variables to store the application’s name, a reference to the main program’s File menu (or whichever menu should hold the MRU list), and the maximum number of MRU list entries that it should display. It also uses private collections to hold the names of the files in the MRU list and references to the menu items it has added to the File menu.

After declaring the private variables, the class declares a public OpenFile event. It raises this event to tell the main program that the user has selected one of the MRU files.

The class’s constructor takes as parameters the application’s name, a reference to the File menu, and the maximum number of entries it should display. It stores those values, calls LoadMruList to load the MRU list that was saved the last time the program ran, and then calls DisplayMruList to add the MRU items to the File menu.

The subroutine LoadMruList loops through the numbers 1 to the maximum number of entries it should display and uses GetSetting to fetch a file name from the System Registry. These values are stored in the Registry area named for the application (in the section named MruList). The values themselves are named FileName1, FileName2, and so forth.

The program passes the call to GetSetting a default value of “”, so it returns a zero-length string if the value is not in the Registry. If GetSetting returns a nonblank string, the code adds it to the m_FileNames collection.

The subroutine SaveMruList saves the MRU list’s current file names into the registry. It starts by using GetSetting to see if there is a FileName1 entry. If this entry is present, the program uses the DeleteSetting statement to remove the entire MruList section from the program’s area in the Registry. Then SaveMruList loops through the m_FileNames collection, making the appropriate Registry entries.

The subroutine DisplayMruList builds the MRU menu items. First it loops through the m_MenuItems collection and removes any menu items that it created previously. Next, if the m_FileNames collection contains any file names, the subroutine adds a separator to the File menu. In Figure 10-10, this is the horizontal gray line above the first MRU item and below the Properties item. The routine creates this item, saves a reference to it in the m_MenuItems collection, and adds the item to the File menu.

DisplayMruList then loops through the MRU file names making their menu items. For each file, it makes a new menu item with an appropriate caption. The caption starts with an ampersand followed by a number. That makes the number appear underlined in the menu and makes the number the item’s accelerator. For example, the caption “&1 Text.txt” would be displayed as “1 Test.txt.” If you opened the File menu and pressed 1, this menu item would fire.

The subroutine DisplayMruList assigns the MruItem_Click event handler with the new menu item’s Click event, saves a reference to the new item in the m_MenuItems collection, and then adds the item to the File menu.

The MruItem_Click event handler executes when the user clicks one of the MRU menu items. It uses DirectCast to convert the sender parameter into the ToolStripMenuItem object that raised the event. It then loops through the m_MenuItems collection looking for that item. When it finds the item, the code looks up the corresponding file name and raises the OpenFile event, passing it the file name. Note that the indexes in the m_MenuItems and m_FileNames collections differ by one, because the separator has an entry in the m_MenuItems collection but not in m_FileNames.

The subroutines Add and Remove let the main program control the MruList object. Add takes as a parameter the name of a file to add to the MRU list. It uses the FileNameIndex function to see if the file is already on the list, and it removes the file if it is present. Add then inserts the file at the front of the MRU list. If this makes the list too long, the routine removes the last entry from the m_FileNames collection. Finally, the program calls DisplayMruList to recreate the MRU list’s File menu items and calls SaveMruList to update the list’s registry entries.

The FileNameIndex helper function loops through the m_FileNames collection and returns a file name’s index if it is present.

Finally, the subroutine Remove takes as a parameter the name of a file to remove from the MRU list. It uses FileNameIndex to get the file’s index in the m_FileNames collection. If the file is present, the code removes if from the collection, calls DisplayMruList to recreate the menu items, and calls SaveMruList to update the list’s registry entries.

  Imports System.IO Public Class MruList     Private m_ApplicationName As String     Private m_FileMenu As ToolStripMenuItem     Private m_NumEntries As Integer     Private m_FileNames As Collection     Private m_MenuItems As Collection     Public Event OpenFile(ByVal file_name As String)     Public Sub New(ByVal application_name As String, _      ByVal file_menu As ToolStripMenuItem, ByVal num_entries As Integer)         m_ApplicationName = application_name         m_FileMenu = file_menu         m_NumEntries = num_entries         m_FileNames = New Collection         m_MenuItems = New Collection         ' Load saved file names from the Registry.         LoadMruList()         ' Display the MRU list.         DisplayMruList()     End Sub ' Load previously saved file names from the Registry. Private Sub LoadMruList()     Dim file_name As String     For i As Integer = 1 To m_NumEntries         ' Get the next file name and title.         file_name = GetSetting(m_ApplicationName, _             "MruList", "FileName" & i, "")         ' See if we got anything.         If file_name.Length > 0 Then             ' Save this file name.             m_FileNames.Add(file_name, file_name)         End If     Next i End Sub ' Save the MRU list into the Registry. Private Sub SaveMruList()     ' Remove previous entries.     If GetSetting(m_ApplicationName, "MruList", _      "FileName1", "").Length > 0 Then         DeleteSetting(m_ApplicationName, "MruList")     End If     ' Make the new entries.     For i As Integer = 1 To m_FileNames.Count         SaveSetting(m_ApplicationName, _             "MruList", "FileName" & i, _             m_FileNames(i).ToString)     Next i End Sub ' Display the MRU list. Private Sub DisplayMruList()     ' Remove old menu items from the File menu.     For Each mnu As ToolStripItem In m_MenuItems         m_FileMenu.DropDownItems.Remove(mnu)     Next mnu     m_MenuItems = New Collection     ' See if we have any file names.     If m_FileNames.Count > 0 Then         ' Make the separator.         Dim sep As New ToolStripSeparator()         m_MenuItems.Add(sep)         m_FileMenu.DropDownItems.Add(sep)         ' Make the other menu items.         Dim mnu As ToolStripMenuItem         For i As Integer = 1 To m_FileNames.Count             mnu = New ToolStripMenuItem()             mnu.Text = "&" & i & " " & _                New FileInfo(m_FileNames(i).ToString).Name             AddHandler mnu.Click, AddressOf MruItem_Click             m_MenuItems.Add(mnu)             m_FileMenu.DropDownItems.Add(mnu)         Next i     End If End Sub ' MRU menu item event handler. Private Sub MruItem_Click(ByVal sender As System.Object, _  ByVal e As System.EventArgs)     Dim mnu As ToolStripMenuItem     mnu = DirectCast(sender, ToolStripMenuItem)     ' Find the menu item that raised this event.     For i As Integer = 1 To m_FileNames.Count         ' See if this is the item. (Add 1 for the separator.)         If m_MenuItems(i + 1) Is mnu Then             ' This is the item. Raise the OpenFile              ' event for its file name.             RaiseEvent OpenFile(m_FileNames(i).ToString)             Exit For         End If     Next i End Sub ' Add a file to the MRU list. Public Sub Add(ByVal file_name As String)     ' Remove this file from the MRU list     ' if it is present.     Dim i As Integer = FileNameIndex(file_name)     If i > 0 Then m_FileNames.Remove(i)     ' Add the item to the begining of the list.     If m_FileNames.Count > 0 Then         m_FileNames.Add(file_name, file_name, m_FileNames.Item(1))     Else         m_FileNames.Add(file_name, file_name)     End If     ' If the list is too long, remove the last item.     If m_FileNames.Count > m_NumEntries Then         m_FileNames.Remove(m_NumEntries + 1)     End If     ' Display the list.     DisplayMruList()     ' Save the updated list.     SaveMruList() End Sub     ' Return the index of this file in the list.     Private Function FileNameIndex(ByVal file_name As String) As Integer         For i As Integer = 1 To m_FileNames.Count             If m_FileNames(i).ToString = file_name Then Return i         Next i         Return 0     End Function     ' Remove a file from the MRU list.     Public Sub Remove(ByVal file_name As String)         ' See if the file is present.         Dim i As Integer = FileNameIndex(file_name)         If i > 0 Then             ' Remove the File.             m_FileNames.Remove(i)             ' Display the list.             DisplayMruList()             ' Save the updated list.             SaveMruList()         End If     End Sub End Class  

The following code shows how a main program can use the MruList class. This program is a simple text viewer that lets the user open and view files.

This program declares an MruList variable named m_MruList. It uses the WithEvents keyword so that it is easy to catch the object’s OpenFile event.

The form’s New event handler initializes the MruList object, passing it the application’s name, the File menu, and the number of items the MRU list should hold.

When the user selects the File menu’s Open command, the program displays an open file dialog box. If the user selects a file and clicks OK, the program calls subroutine OpenFile, passing it the name of the selected file.

If the user selects a file from the MRU list, the m_MruList_OpenFile event handler executes and calls subroutine OpenFile, passing it the name of the selected file.

Subroutine OpenFile loads the file’s contents into the txtContents TextBox control. It then calls the MruList object’s Add method, passing it the file’s name. It finishes by setting the form’s caption to the file’s name without its directory path.

  Imports System.IO Public Class Form1     Private WithEvents m_MruList As MruList     ' Initialize the MRU list.     Private Sub Form1_Load(ByVal sender As Object, _      ByVal e As System.EventArgs) Handles Me.Load         m_MruList = New MruList("SdiMruList", mnuFile, 4)     End Sub     ' Let the user open a file.     Private Sub mnuFileOpen_Click(ByVal sender As System.Object, _      ByVal e As System.EventArgs) Handles mnuFileOpen.Click         If dlgOpen.ShowDialog() = Windows.Forms.DialogResult.OK Then             OpenFile(dlgOpen.FileName)         End If     End Sub     ' Open a file selected from the MRU list.     Private Sub m_MruList_OpenFile(ByVal file_name As String) _      Handles m_MruList.OpenFile         OpenFile(file_name)     End Sub     ' Open a file and add it to the MRU list.     Private Sub OpenFile(ByVal file_name As String)         txtContents.Text = File.ReadAll(file_name)         txtContents.Select(0, 0)         m_MruList.Add(file_name)         Me.Text = "[" & New FileInfo(file_name).Name & "]"     End Sub End Class  

You could easily convert the MruList class into a component. If you give the component ApplicationName, FileMenu, and MaxEntries properties, you can set those values at design time. For more information about building components, see Chapter 12.




Visual Basic 2005 with  .NET 3.0 Programmer's Reference
Visual Basic 2005 with .NET 3.0 Programmer's Reference
ISBN: 470137053
EAN: N/A
Year: 2007
Pages: 417

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net