Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / XML

Add User Shortcuts To Files/URLs to Application Menus

4.20/5 (2 votes)
22 Nov 2006CPOL2 min read 1   497  
.NET Class that loads a list of files/URLs and displays them in the menu of Windows Forms application

Sample Image - screen0.jpg

Introduction

UserMenuShortcuts is a .NET class for Windows Forms that displays a list of files or URLs in a menu. When the user clicks an item from the menu, the file/URL is launched on their machine (such as Notepad.exe or Codeproject.com). Clicked items which reference a file on the user's system will launch the item with its associated application with .NET's Process.Start() method. If the clicked item is a URL, then the user's default browser will be launched and navigate to the specified URL address.

The file that stores the user menu items is the UserShortcuts.xml file, and it is stored in the host application's directory. If a UserShortcuts.xml file is not provided/found, it will be automatically generated whenever the host application runs and cannot find the file.

Using the UserMenuShortcuts .NET Class

To use the UserMenuShortcuts in a Windows Form or another Windows .NET control, add a menu item to the form that will be replaced by the loaded menu shortcuts and then include the UserMenuShortcuts class into the project. Add the click-event handler to the placeholder menu item and then make the following method calls in your form/control class:

C#
private void Form1_Load(object sender, EventArgs e)
{
    UserShortcuts.Load(userItemsPlacehoderToolStripMenuItem,
            userItemsPlacehoderToolStripMenuItem_Click);
}

private void userItemsPlacehoderToolStripMenuItem_Click(object sender, EventArgs e)
{
    //NOTE: To override this action, remove the call to "LaunchUserShortcutItem"
    //and access the clicked item by:
    //      Convert.ToString(UserShortcuts.UserShortcutItems[sender.ToString()]);

    UserShortcuts.LaunchUserShortcutItem(sender.ToString());
}

How the UserMenuShortcuts Class Works

The UserMenuShortcuts class loads a hashtable of the menu items from the UserShortcuts.xml file and then creates a set of menu items at the same level as the placeholder menu item. The Key of each hashtable item is also used as the display text in the menu item, while the Value of the hashtable item is the target file/URL. When the menu item is clicked, a lookup of the clicked menu item's text is performed to retrieve the target file/URL, and then the target is launched with Process.Start().

C#
public class UserShortcuts
{
    ...
    ...
    private static Hashtable m_UserShortcutItems = new Hashtable();
    public static Hashtable UserShortcutItems
    {
        get { return m_UserShortcutItems; }
        set { m_UserShortcutItems = value; }
    }

    /// <summary>
    /// Reads the UserShortcutItems file and loads into the specified menu item
    /// </summary>
    /// <param name="mniUserShortcutsPlaceholder"></param>
    /// <param name="mniUserShortcutsPlaceholder_Click"></param>
    public static void Load(ToolStripMenuItem mniUserShortcutsPlaceholder,
                            EventHandler mniUserShortcutsPlaceholder_Click)
    {
        // generate a sample file if it doesn't exist
        if (File.Exists(_Uri) == false)
        {
            GenerateSampleUserShortcutFile(_Uri);
        }

        XmlDocument _Document = null;

        // all files are relative to the EXE file
        string sOldWorkingDirectory = Directory.GetCurrentDirectory();

        try
        {
            Directory.SetCurrentDirectory(Path.GetDirectoryName
                    (Application.ExecutablePath));
            _Document = new XmlDocument();
            _Document.Load(_Uri);

            m_UserShortcutItems = new Hashtable();
            m_UserShortcutItems.Clear();

            XmlNode root = _Document.DocumentElement;
            XPathNavigator nav = root.CreateNavigator();
            XPathNodeIterator nodeIterator = nav.Select("/UserShortcuts/UserShortcut");

            while (nodeIterator.MoveNext())
            {
                string sMenuLabel = nodeIterator.Current.SelectSingleNode
                        ("MenuLabel").Value.Trim();
                string sShortcutPath = nodeIterator.Current.SelectSingleNode
                        ("ShortcutPath").Value.Trim();

                if (System.Uri.IsWellFormedUriString
                    (sShortcutPath, UriKind.Absolute) == false)
                {
                    FileInfo fiInfo = new FileInfo(sShortcutPath);
                    sShortcutPath = fiInfo.FullName;
                }

                if (m_UserShortcutItems.ContainsKey(sMenuLabel) == false)
                {
                    m_UserShortcutItems.Add(sMenuLabel, sShortcutPath);
                }
            }

            LoadUserShortcutsMenu
                 (mniUserShortcutsPlaceholder, mniUserShortcutsPlaceholder_Click);
        }
        catch (Exception ex)
        {
            throw new Exception("Error Loading User Shortcuts", ex);
        }
        finally
        {
            Directory.SetCurrentDirectory(sOldWorkingDirectory);
        }
    }

    /// <summary>
    /// Load the menu items into the placeholder's location and
    /// then delete the placeholder item
    /// </summary>
    /// <param name="mniUserShortcutsPlaceholder"></param>
    private static void LoadUserShortcutsMenu
        (ToolStripMenuItem mniUserShortcutsPlaceholder,
                   EventHandler mniUserShortcutsPlaceholder_Click)
    {
        if (mniUserShortcutsPlaceholder == null)
            return;

        int iplaceholderloc = mniUserShortcutsPlaceholder.Owner.Items.IndexOf
                        (mniUserShortcutsPlaceholder);

        IDictionaryEnumerator iusershortcuts =
                UserShortcuts.UserShortcutItems.GetEnumerator();
        while (iusershortcuts.MoveNext())
        {
            string sMenuName = Convert.ToString(iusershortcuts.Key);
            ToolStripMenuItem mni = new ToolStripMenuItem(sMenuName);
            mni.Click += new EventHandler(mniUserShortcutsPlaceholder_Click);
            mniUserShortcutsPlaceholder.Owner.Items.Insert(iplaceholderloc, mni);
            iplaceholderloc += 1;
        }

        mniUserShortcutsPlaceholder.Owner.Items.Remove(mniUserShortcutsPlaceholder);
    }

    /// <summary>
    /// Launches the specified value/path/URL of the specified key (menu item)
    /// </summary>
    /// <param name="sKey"></param>
    public static void LaunchUserShortcutItem(string sKey)
    {
        string sShortcutPath = Convert.ToString(UserShortcuts.UserShortcutItems[sKey]);
        if ((System.Uri.IsWellFormedUriString(sShortcutPath, UriKind.Absolute) == true)
            || (File.Exists(sShortcutPath) == true))
        {
            ProcessStartInfo psi = new ProcessStartInfo(sShortcutPath);
            psi.UseShellExecute = true;
            Process.Start(psi);
        }
    }
}   

Conclusion

I hope you find this article and class useful - it has come in handy in several applications already!

History

  • 22nd November, 2006: Article posted

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)