TechFriday: Jumping into Jumplists

Everybody’s excited about Windows 7 and there might be a few of you guys out there wanting to take advantage of some of the new features of the OS in your applications. In this post, I’ll show you how you can quickly add Jumplist support to your existing application (Yes, even WinForms applications)

In order to keep things simple, let’s just make the assumption that this existing application of mine has 3 very useful screens: Default, Green Mode and Red Mode ( I’m a developer, I’m not very creative )

image

Because I want to save my user some additional clicks to get into green / red mode, I can take advantage of a new feature of Windows 7 called Jumplists: when a user right-clicks on my app’s icon on the Windows 7 task bar, this menu pops up and gives him access to tasks that we expect him to frequent. There are a lot of tutorials out there that teach how to add Recent/Frequent documents to this list. The samples included in the library we’ll be using will show you how.

image .

For this example, we’ll learn how to use our applications existing custom functions (and icons) with Windows 7 jumplists but first, download the Windows 7 Taskbar Developer Resource

For this example, I have a very simple Hello Windows 7 application. In the application, I have a menu bar that loads up additional screens. In this case, it’s just the same screen and switching the colors, but it could easily be a function that will load up another UserControl with different functions. Productivity is key, so I’d like to allow my user to go straight to these screens on startup.

image

In order to enable this, I’ve made a method that will allow the application to switch between user screens based on command line arguments when launching the application.

private void ProcessArguments()
{
    string[] args = Environment.GetCommandLineArgs();

    if (args.Length > 1)
    {
        if (args[1].Equals("/r"))
        {
            LoadRedScreen();
        }
        else if (args[1].Equals("/g"))
        {
            LoadGreenScreen();
        }

    }
}

In this piece of code, I’m basically checking that IF there are arguments passed when running the application, I’ll be calling a method to load the appropriate UserControl (We’ve already seen that this is the same method invoked by the menu item in our Menubar).

Now we start using the libraries provided for us to make it easier to integrate with the Windows 7 Taskbar. But first let’s import the namespace of the library, plus some additional ones we will be using along the way

using Windows7.DesktopIntegration;
using System.IO;
using System.Reflection;

Next we add the following properties to the form:

string appID = "Hello Windows 7";
JumpListManager jlm;
    

The key thing here is the JumpListManager but if you want more information on the appID and all the goodness it brings, visit http://windowsteamblog.com/blogs/developers/archive/2009/06/18/developing-for-the-windows-7-taskbar-application-id.aspx. The next thing I have to do is override

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
}

Before we start jumping into adding jumplists, we want to remember that since this is an existing application meant to be run in existing versions of Windows, we’d like to make sure that we’ll only execute the additional code IF the application is running in Windows 7, otherwise, operate as usual. To do this, we check whether the OS version is 6.1 or greater (RC builds still register Major version as 6) with this code:

OperatingSystem os = Environment.OSVersion;
if ((os.Version.Major == 6 && os.Version.Minor >= 1) || os.Version.Major > 6)
{
    //some code
}

Now for the fun part. The OS message that we want to lookout for is the message that tells us that the taskbar button has been created. Then we can start adding the Jumplist items to the button.

if (m.Msg == Windows7Taskbar.TaskbarButtonCreatedMessage)
{
    try
    {
        
        jlm = new JumpListManager(appID);
        jlm.UserRemovedItems += delegate { };

        string strAppDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
        string app = Assembly.GetEntryAssembly().GetName().Name + ".exe";


        jlm.AddUserTask(new ShellLink
        {
            Title = "Color it Red!",
            Path = Path.Combine(strAppDir, app),
            Arguments = "/r",
            IconLocation = Path.Combine(strAppDir, @"icoRed.ico")

        });

        jlm.AddUserTask(new ShellLink
        {
            Title = "Color it Green!",
            Path = Path.Combine(strAppDir, app),
            Arguments = "/g",
            IconLocation = Path.Combine(strAppDir, @"icogreen.ico")
        });
        jlm.Refresh();

        ProcessArguments();
    }
    catch (Exception)
    {
        
    }

Let’s break this down.

image

We start by creating a new instance of the JumpListManager passing the appID we’ve assigned to our app. Next we register to the UserRemovedItems event as this is required if we want to refresh the JumpList after adding items to it. In this case, we do nothing when any items are removed.

image

Here, we get the directory where the application is running as well as the app name itself, so we can tell the JumpList link what to invoke when it is clicked. Basically it’s emulating running your app from a command prompt and passing the arguments (if any). Now we can proceed to adding our JumpList items.

image

I’ve mentioned we can add a few other things such as Recent Documents & Frequent Documents  but you’ll find lots of resources on this on the net as well as the samples for the library. In this case, we’re adding a new User Task to the jumplist which results in having these links under a “Tasks” header as below:

image

Path, Arguments, and IconLocation are pretty self explanatory.

image

I need to make sure my icons are available to my application so here I’ve placed all my custom icons in one directory and set the property so the IDE knows to copy these files to the output directory.

image

After defining my JumpList links, I can call a Refresh on the JumpListManager so it loads up all my new links. After this, I make a call to my ProcessArguments method. This will make sure it runs the additional code if any arguments were passed when running the application. Of course, if you see that your users may want to run your app from a command line and pass arguments manually, you might want to put this call outside of the if statement or anywhere before your first form completes loading.

It’s that easy! If you got lost on the way, here’s the source to this project. If you manage to get your JumpLists going, feel free post a link to your app! 🙂

http://cid-bdfb7845c22e26b6.skydrive.live.com/embedrowdetail.aspx/Projects/TechFriday/Hello%20Windows%207.zip

RESOURCES:

Windows 7 RC Training Kit for Developers

Managed APIs in this sample 

Other Managed APIs available:

3 thoughts on “TechFriday: Jumping into Jumplists”

  1. whenever I am clicking on the task item, it is opening a new instance of the executable. is it possible to change the color of the same instance? if so… how?

    Like

  2. Yes it is possible, however, it’s not as easy as you’ll have to do some interprocess communication to accomplish this. In other words, there’s currently no way to invoke a method call from your jumplist tasks. 😦

    Like

Leave a reply to Aimee Cancel reply