Click here to Skip to main content
Click here to Skip to main content

Add User Shortcuts To Files/URLs to Application Menus

, 22 Nov 2006
Rate this:
Please Sign up or sign in to vote.
.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:

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().

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

    /// <span class="code-SummaryComment"><summary></span>
    /// Reads the UserShortcutItems file and loads into the specified menu item
    /// <span class="code-SummaryComment"></summary></span>
    /// <span class="code-SummaryComment"><param name="mniUserShortcutsPlaceholder"></param></span>
    /// <span class="code-SummaryComment"><param name="mniUserShortcutsPlaceholder_Click"></param></span>
    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);
        }
    }

    /// <span class="code-SummaryComment"><summary></span>
    /// Load the menu items into the placeholder's location and
    /// then delete the placeholder item
    /// <span class="code-SummaryComment"></summary></span>
    /// <span class="code-SummaryComment"><param name="mniUserShortcutsPlaceholder"></param></span>
    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);
    }

    /// <span class="code-SummaryComment"><summary></span>
    /// Launches the specified value/path/URL of the specified key (menu item)
    /// <span class="code-SummaryComment"></summary></span>
    /// <span class="code-SummaryComment"><param name="sKey"></param></span>
    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)

About the Author

Chris Hambleton
Software Developer
United States United States
SOFTWARE: Chris Hambleton is a Software Developer with proven experience in developing both web and Windows client-server applications with WPF, ASP.NET, C#, SQL Server, VB.NET, Visual C++, and VB6.
 
Chris's website is at ChrisHambleton.com and he has a small web-hosting/consulting business called CustomersInFocus.com. He has several other websites such as EzekielWatch.com, iWriterPro.com, and BookBlitzer.com.
 
WRITING: He has also written several fiction books ("The Time of Jacob's Trouble" and "Endeavor in Time"), available at CWHambleton.com and of course, at Amazon.com (Full Amazon Profile).

Comments and Discussions

 
GeneralNice! PinmemberAlexey A. Popov23-Nov-06 21:41 
GeneralFormat Code PinmemberGh0stman23-Nov-06 2:13 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140709.1 | Last Updated 22 Nov 2006
Article Copyright 2006 by Chris Hambleton
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid