Welcome to The Windows Blog 


Developing for the Windows 7 Taskbar – Jump into Jump Lists – Part 3

So far, you have seen how you can opt into the Windows 7 Taskbar Jump List experience by creating a Jump List for your application (in the Developing for the Windows 7 Taskbar – Jump into Jump Lists – Part 2 post.) You have also seen the Windows 7 default support for listing “Recent” or “Frequent” destinations as well as how to create your own custom categories. In this post, we will explore more of the Jump List features and discover how easy it is to add Tasks to your application's Jump List.

User tasks are customized tasks that get their own Tasks category. As a developer, you can set the title of the displayed task, the icon on the left and, more important, and the “application” that is launched once you activate this task. You can view user’s tasks as shortcuts to the functionality our applications can provide. As you might remember, user tasks are the verbs in our vocabulary; for example, Windows Media Player provides a “Resume last playlist” task and Sticky Notes provides a “New note” task.

A user task is usually an IShellLink object that launches any given application (your application or any other one you choose) with specific command line parameters. While you cannot categorize tasks, you can separate them using a special separator object. Here’s an example of a Jump List that uses a separator to split three tasks into a group of two plus an additional task:

image

So what does it take to add tasks to a Jump List? Well, not that much. Basically it is a single call to the AddUserTasks function in an interface that we are already familiar with, the ICustomDestinationList (ICustomDestinationList::AddUserTasks(IObjectArray) Method). Looking at the code, you will see a single line of code, hr = pcdl->AddUserTasks(poa);. However, as always, someone needs to create and build that poa, IObjectArray, and parameter and fill it with relevant information. Let’s review that process now.

We are going to create a collection of IShellLinks. This collection will be later cast to the required IObjectArray parameter. The following code is the beginning of that process.

IObjectCollection *poc;
HRESULT hr = CoCreateInstance(
D_EnumerableObjectCollection, NULL, CLSCTX_INPROC, IID_PPV_ARGS(&poc));
if (SUCCEEDED(hr))
{
IShellLink * psl;
hr = _CreateShellLink(L"/Task1", L"Task 1", &psl);
if (SUCCEEDED(hr))
{
hr = poc->AddObject(psl);
psl->Release();
}
}

Here you can see that we used COM (again) and CoCreate and IObjectCollection, poc. Next, we call to a helper function called CreateShellLink that receives three parameters:

  • The first parameter is the command line argument to the task
  • The second parameter is the title that will be displayed
  • The last parameter is a pointer to IShellLink

The object is then filed according to the relevant information.

Last, we add the recently created IShellLink to the object collection. You may ask yourself where the parameter that provides the path to the executable that we plan to launch is. Well that is a good question. For simplicity, we have hard-coded that information as shown in the following code snippet:

if (SUCCEEDED(hr))
{
hr = _CreateShellLink2(
L"C:\\Users\\<my user>\\Documents\\new text file.txt",
L"NotePad",
&psl);

if (SUCCEEDED(hr))
{
hr = poc->AddObject(psl);
psl->Release();
}
}

Here you can see we call to a hard-coded _CreateShellLink2 function. This receives a path to a text file as one of its parameters and, as you can see, we are launching Notepad.

Here is the code for the CreateShellLink2 function:

HRESULT _CreateShellLink2(
PCWSTR pszArguments, PCWSTR pszTitle,
IShellLink **ppsl)
{
IShellLink *psl;
HRESULT hr = CoCreateInstance(
CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&psl));
if (SUCCEEDED(hr))
{
hr = psl->SetPath(c_szNotePadExecPath);
if (SUCCEEDED(hr))
{
hr = psl->SetArguments(pszArguments);
if (SUCCEEDED(hr))
{
// The title property is required on Jump List items
// provided as an IShellLink instance. This value is used
// as the display name in the Jump List.
IPropertyStore *pps;
hr = psl->QueryInterface(IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr))
{
PROPVARIANT propvar;
hr = InitPropVariantFromString(pszTitle, &propvar);
if (SUCCEEDED(hr))
{
hr = pps->SetValue(PKEY_Title, propvar);
if (SUCCEEDED(hr))
{
hr = pps->Commit();
if (SUCCEEDED(hr))
{
hr = psl->QueryInterface
(IID_PPV_ARGS(ppsl));
}
}
PropVariantClear(&propvar);
}
pps->Release();
}
}
}
else
{
hr = HRESULT_FROM_WIN32(GetLastError());
}
psl->Release();
}
return hr;
}

To start with, again we need to use COM and CoCreate to create an IShellLink COM object. A quick look at the SDK reveals that the IShellLink object has many functions. Here are few that we will use:

  • GetPath Gets the path and file name of a Shell link object, that is the path to the executable
  • GetShowCmd Gets the show command for a Shell link object, the executable name
  • SetArguments Sets the command-line arguments for a Shell link object
  • SetDescription Sets the description for a Shell link object; the description can be any application-defined string
  • SetIconLocation Sets the location (path and index) of the icon for a Shell link object SetPath Sets the path and file name of a Shell link object
  • SetWorkingDirectory Sets the name of the working directory for a Shell link object

As you can see, for each parameter we must get and set appropriate methods. There are additional parameters; take a look at the SDK - IShellLink if you want to learn more.

In the above example, we set the path to Notepad (by default in the Windows 7 installation, c:\windows\notepad.exe). We also passed a hard-coded (not a good practice) command line argument pointing to a text file in my private document folder (C:\Users\<my user>\Documents\new text file.txt.) The rest of the code sets the title property that is required on Jump List items.

We call the CreateShellLink2 and CreateShellLink a few more times to add all three shortcuts as shown in the above screen capture.

Now let’s add a separator.

To add a separator to our Task List, we need to create an IShellLink, and set the PKEY_AppUserModel_IsDestListSeparator property using the COM property variant as shown in the following code snippet:

// The Tasks category of Jump Lists supports separator items. 
// These are simply IShellLink instances that have the
// PKEY_AppUserModel_IsDestListSeparator property set to TRUE.
// All other values are ignored when this property is set.
HRESULT _CreateSeparatorLink(IShellLink **ppsl)
{
IPropertyStore *pps;
HRESULT hr = CoCreateInstance(
CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr))
{
PROPVARIANT propvar;
hr = InitPropVariantFromBoolean(TRUE, &propvar);
if (SUCCEEDED(hr))
{
hr = pps->SetValue(PKEY_AppUserModel_IsDestListSeparator, propvar);
if (SUCCEEDED(hr))
{
hr = pps->Commit();
if (SUCCEEDED(hr))
{
hr = pps->QueryInterface(IID_PPV_ARGS(ppsl));
}
}
PropVariantClear(&propvar);
}
pps->Release();
}
return hr;
}

Here you can see that we used CoCreate to create an IShellLink object. Next, we set a PROPVARIANT, propvar, to true and set the IShellLink object PKEY_AppUserModel_IsDestListSeparator property to true. This will instruct the OS to render this IShellLink as a separator and not just as regular IShellLink.

OK, that was long. Now let’s look at the short version, using .NET. For that we are going to use the Windows API Code pack for the .NET Framework.

As we can expect from .NET, we get abstraction from most of the “COM code behind” that is required. The Microsoft.WindowsAPICodePack.Shell.Taskbar namespace includes a JumpListLink object that extends the ShellLink object and implements IJumpListTasks.

The JumpList class contains the UserTasks collection of IJumpListTasks to which you can simple add new JumpListLink objects as shown in the following code snippet:

// Path to Windows system folder
string systemFolder =
Environment.GetFolderPath(Environment.SpecialFolder.System);

jumpList.UserTasks.Add(new JumpListLink
{
Title = "Open Notepad",
Path = Path.Combine(systemFolder, "notepad.exe"),
IconReference = new IconReference(
(systemFolder, "notepad.exe"), 0)
});

Using the C# 3.0 syntax, we initialize a new JumpListLink object and add it to the UserTasks collection. As you can see, the managed code JumpListLink has very similar properties to the native one (which makes perfect sense). We also added an icon to the Notepad shortcut to the above code, but didn't provide any command line parameters.

You want to add a separator? Well, that is also very easy: just add a JumpListSeperator object to the UserTasks collection.

jumpList.UserTasks.Add(new JumpListSeparator());
Please note that, as always, when working with the Windows Code pack API Taskbar, you have to call the “refresh” function in order to commit the changes, as we explained in the previous post.
Taskbar.JumpList.RefreshTaskbarList();

After the refresh, the Jump List looks as follows:

image

I’ve compiled a version of a native example from the Windows 7 SDK. You can get a copy of that code from here

You can download the Windows API Code Pack that includes the manage code example we used in this post.

This concludes our Jump List discussion. Our next Taskbar topic is Icon Overlay.


What’s new at Talking About Windows.com

If you haven visited Talking About Windows.com in a while, you are missing a lot!

You missed Microsoft Engineers like Ian Burgess talking about the engineering design of DirectAccess and BitLocker and Mario Garzia discussing application compatibility and how Windows 7 works with legacy applications.

You can interact with IT pros like Darren Baker, the National Director of Infrastructure Solutions for Sogeti USA talk about how virtualization and imaging has made implementing Windows 7 in his organization easier.

Talking About Windows.com is your chance to hear what Microsoft Engineers and IT pros like you have to say and gives you a chance to interact with them.

Hear what they have to say and get heard. Join the conversation.

IAN   Darren  

Mario


SCCManager 2007 Service Pack 2 Beta aka ConfigMgr07 SP2

Today I am featuring guest Blogger Jeremy Chapman from the Windows Product Team. To see more of Jeremy, view our latest VRT on Application Compatibility. To learn more, click here. Below is his interview with Jeff Wettlaufer from the System Center Team.

I recently interviewed fellow product manager, long-time friend and fellow “automator” of operating system deployment tasks, Jeff Wettlaufer, from the System Center team. He explained the new features in the recently released System Center Configuration Manager 2007 Service Pack 2 Beta (let’s just call it “ConfigMgr07 SP2” for short), and how that will help with Windows 7 deployment and management.   

Jeremy: What is ConfigMgr07 SP2 and where do people get it?
Jeff: Thanks for having me and thanks for saying configmgr and not sccm for once… SP2 adds support for new operating systems – Windows 7 and Server 2008 R2 and Windows Vista SP2 – along with exciting enhancements around Intel AMT integration. If you have the  Intel vPro hardware, there are many things we can do. Out of Box Wired/Wireless Management: Wireless Profile Management, End Point Access Control: 802.1x support, Access Monitor: Audit Log, Remote Power Management: Power State Configuration. You were at Microsoft Management Summit in May and already saw this, but we demoed waking Windows XP PCs up wirelessly and kicking off the deployment to Windows 7 using USMT and hard-link migration. Those machines were mid range Dell latitude laptops, and we migrated to Windows 7 with 4GB user data and apps in 18 minutes.

Win7 ACT

Jeremy: I saw that, it was amazing. There is a video of that on Microsoft PressPass. And I thought I was fast with 23-minute migrations from Windows XP on my computers. Let’s take a step back for a second. From the 10,000 ft level, how does ConfigMgr07 help with client management?

Jeff: A lot of people probably know about how ConfigMgr can help with their inventory, software update (patch) management, and application distribution - but you may not be aware of things like the ability to manage PCs over the Internet, in the ‘serverless’ branch, at home, on the road and wherever people work these days.  In addition, ConfigMgr can now deploy virtual applications in the same way as SMS and ConfigMgr have always delivered traditional physical formats.  We can stream apps to desktops, or deliver the apps locally in what’s called download and execute, so even mobile laptop users can use virtual apps.  There is a lot there and I’d encourage everyone to check out http://technet.microsoft.com/en-us/configmgr/default.aspx

Jeremy: Explain Internet-based client management.

Jeff: A lot of people say that mobile workforce management is a key challenge they face today on the client. Laptops are outselling desktops and people are taking these on the road, home or otherwise not connecting to the corporate network very often. So with ConfigMgr, we can manage ConfigMgr clients when they are not connected to your company network but have a standard Internet connections. This feature has a number of advantages, including the reduced costs of not having to run virtual private networks (VPNs) and being able to deploy software updates to remote users while they are traveling or at home. 

win7 AppV

Jeremy: Explain the new client hardware compatibility reports in HW inventory.

Jeff: We’ve updated the hardware compatibility reports in ConfigMgr to include the minimum bars for Windows 7 hardware compatibility, so you can see which machines in your environment are capable of running Windows 7 in a single view.  We did this for Vista, and we found it really helped organizations understand where they were at the hardware level.  We are taking that work forward to also help customers understand from their existing inventory of managed systems, which ones meet the minimum requirements before they start for Windows 7.  As well as helping understand the hardware side of readiness, we also are providing support for applications. In the past we have provided support for the Application Compatibility Toolkit through a connector, that brings the app knowledge right into the Admin console.  As ACT moves to version 6 for Windows 7, we will update the connector to support that effort.  The ACT data is a real hidden gem, in 1 view you can see your apps – and organize your testing to compare it in that 1 view to the vendor, the community, and even Microsoft.  This information can really help make the right decisions moving forward, and ConfigMgr can help migrate apps by supporting Application virtualization where needed.

Jeremy: How about the operating system deployment support.

Jeff: With any operating system deployment, you have to migrate user files off the old system, lay down a new OS, configure it with updates, packages and apps, then restore the user files and settings you migrated off in the first step. ConfigMgr can automate the whole process and do it without you having to visit the targeted PCs. I know you’ve got a lot of videos walking through the Lite Touch Installation process on the web, but ConfigMgr can even target the PCs for installation and kick off the process for you. Along the way we encrypt your user state, passwords and product keys, so it is more automated and enterprise-class.  ConfigMgr has built on the great work in deployment technology from the Windows gang, by embracing and integrating the tools usage like WinPE, USMT, BitLocker and more.  Our Task Sequencer helps to truly separate the hardware from the OS and application layers, by using the boot.wim and install.wim formats from Windows, and then providing a console UI experience to chain user data migration, applications and other settings. 

win7 Task Seq

Jeremy: Are all the Windows 7 deployment enhancements like the image servicing in DISM (Deployment Image Servicing and Management), hard-link migration, and Multicast included in the ConfigMgr SP2’s OS deployment?

Jeff: Like you saw at MMS, we do support USMT in ConfigMgr07, including hard-link migration. The Microsoft Deployment Toolkit 2010 Beta 2 extensions for SP2 enable hard-link migration without additional customization, or you can call the User State Migration Tool in a custom task to use the hard-link commands.  Multicast is also supported and since we use the Windows 7 deployment tools, dism.exe is leveraged as well.

Jeremy: When can we expect RTM release of SP2?

Jeff: We recently made the Beta available and the final version should be ready within 90 days of Windows 7 RTM. Everything depends on the customer feedback we get from the Beta though – quality is the priority.

Jeremy: Thanks Jeff. If you have ConfigMgr and want try to SP2 Beta, visit connect.microsoft.com, join the System Center Configuration Manager 2007 Service Pack 2 Connection and download SP2.


Remaining Windows Vista SP2 Languages Released to Windows Update

Back on May 26th, we announced Windows Vista SP2 and Windows Server 2008 SP2 hit the RTW milestone. The first wave of languages (English, German, French, Spanish, and Japanese) was made available on Windows Update at that time. Today, we are releasing the remaining languages for Windows Vista and Windows Server 2008 SP2 to Windows Update.

For more information, including languages, on Windows Vista and Windows Server 2008 SP2 click here.

If you have Windows Update configured to download updates automatically, Windows Update will notify you when Windows Vista SP2 and Windows Server 2008 SP2 is ready to be installed.

Digg This


The Springboard Application Compatibility VRT rebroadcast is live!

Last week we posted the promo teaser here on the Springboard Blog for the Virtual Roundtable on Application Compatibility. As of today, the rebroadcast is live and ready for you to view.

If you missed the live broadcast, here’s your chance to hear Aaron Margosis, Paul Schnell; Darren Baker (also watch for Darren’s interview on TalkingAboutWindows next week), Greg Lambert Michael Sciacqua, Gov Maharaj, Celine Allee, Jeremy Chapman, and of course Mark Russinovich discuss the issues in getting your Windows XP and Windows Vista applications to work with Windows 7 quickly and effectively. From ACT 5.5 and Shims to discussions on key resources and tools, this VRT is a must see for those IT pros looking to make the jump to Windows 7.

To view the complete VRT, click here. 

Also, here are some of our previous VRTs you can view as well.

 clip_image001[5]clip_image001[7]

 

 

clip_image001


Internet Explorer 8 helps you save time with Accelerators

There’s been a great deal of more talk lately about browser performance. You may have seen some previous discussion about page load performance as you saw here in a video and whitepaper in March. Page load ensures that you get to where you want to go quickly. But page load time differences actually measure about the length it takes for a person to blink their eye once, making a win for any browser pretty inconsequential as far as time savings go.

However, Internet Explorer 8 today offers a feature that saves you time and clicks and lets you get things done more quickly: Accelerators. Accelerators optimize the browser experience by removing repetitive, time consuming actions and give people easy access to the online services they use most. You can discover new Accelerators for Internet Explorer 8 at the Internet Explorer 8 Add-ons Gallery.

With all the talk about performance, we wanted to see what features like Accelerators really meant for time savings when people use the web, so we created another video looking at common tasks people actually do in four browsers: Safari 4.0, Chrome 2.0 beta, Firefox 3.5 beta 99 and Internet Explorer 8. Please note, all tests were performed using the default installation settings for each browser. No additional add-ons or extensions were added. 

Here is a video that shows off how Accelerators in Internet Explorer 8 make your browsing experience quicker and easier:


Accelerators in IE8 Help Save Time!


Windows 7 Keyboard Shortcuts

I love keyboard shortcuts. Using a combination of two or more keys that, when pressed, can be used to perform a task that would typically require a mouse or other pointing device saves me time and effort both in Windows and other programs.

Here are some of my favorite Windows 7 shortcuts that you may not be familiar with that are great time savers. For a complete list of all shortcuts, check out this page here.

Windows logo key Picture of Windows logo key +T

Cycle through programs on the taskbar

Windows logo key Picture of Windows logo key +Spacebar

Preview the desktop

Windows logo key Picture of Windows logo key +X

Open Windows Mobility Center

Windows logo key Picture of Windows logo key +P

Choose a presentation display mode

Shift+Windows logo key Picture of Windows logo key+number

Start a new instance of the program pinned to the taskbar in the position indicated by the number

Alt+Windows logo key Picture of Windows logo key+number

Open the Jump List for the program pinned to the taskbar in the position indicated by the number

Ctrl+Windows logo key Picture of Windows logo key+number

Switch to the last active window of the program pinned to the taskbar in the position indicated by the number

Do you have a favorite that you can’t do without? Share it with us in the comments area.


Important Update Regarding Windows Live Movie Maker Beta

Starting July 1st, 2009, when you launch Windows Live Movie Maker Beta you will be prompted to implement a software update which will extend the beta. You can download the software update here to continue to use the software without any interruption. If you choose not to install the software update, you will be unable to continue to use the Windows Live Movie Maker Beta.

WLMovieMaker_256x256

The folks on the Windows Live Movie Maker Team are hard at work on “V1” which should be out sometime this year. For more information on the future of Windows Live Movie Maker, see this excellent blog post by Lead Program Manager Mike Torres from the Windows Live Team Blog.

I’m pretty excited for what they have in store for Windows Live Movie Maker!


Developing for the Windows 7 Taskbar – Jump into Jump Lists – Part 2

This is the second post about the Taskbar Jump List in a series of Windows 7 Taskbar posts. In the previous post, Developing for the Windows 7 Taskbar – Jump into Jump Lists – Part 1, we introduced the elements that comprise the Taskbar Jump Lists: the destination (also referred to as “nouns”) and the Tasks (also referred to as “verbs”). As developer, you have a large amount of control over these elements. In this post, we walk through the different APIs that you can use when programming the Taskbar Jump Lists.

Before we begin, there is one very important thing you need to know. “Items” in the Recent category, or in any other category (any destination), must have a registered file handler for your application in the registry. This doesn’t mean that your application must be the default handler for that specific file type, it just means that your application must have a registered handler for all the files that you want to be visible in the Jump List. Therefore, “items” can only be files. Remember, by clicking on one of the items in the Jump List, the OS executes the command associated with that file as it relates to your application. When you register a file handler, you also specify the application that handles this file, and you define how to pass the input parameter for the application. Another important note to remember: All the items (files) have to be local – that is, on the local hard drive, and accessible to your application. Therefore, we can say that each and every item among the Jump List destinations is an accessible, local file, with a file handler registered to your application.

As we explain in the following section, once you have registered your file handlers, the OS actually helps you keep track of all your files. We will cover file handler registration in the next post.

Step 1 – Use the Out-of-the-Box Windows Experience and Default Behavior

By default, a Jump List contains a Recent category that is populated automatically for file-based applications through the SHAddToRecentDocs function. This function adds the used “item” (file) to the Shell's list of recently used documents. In addition to updating its list of recent documents, the Shell adds a shortcut to the user's Recent directory. The Windows 7 Taskbar uses that list and the Recent directory to populate the list of recent items in the Jump Lists.

Windows can also do the work for you if your application's file type is registered. Anytime you double click on a file type with a registered handler, before Windows launches your application it automatically calls SHAddToRecentDocs on your application's behalf. This inserts the item in the Windows Recent list and eventually into the Jump List Recent Category. The same automatic behavior occurs when using the Windows Common File Dialog (CFD) to open files through our applications. Therefore, this is another good reason to use the CFD introduced in the Windows Vista timeframe, and it also plays a vital role regarding libraries, as we explained in the Light Up with Windows 7 Libraries post.

Both of the above cases exploit default Windows behavior in cases where you have a registered handler and an Application ID by which the files are associated with Recent and Frequent lists. In both cases, Windows automatically inserts the items into the Jump Lists unless you specifically remove this functionality by using the COM API. Obviously, users also have the option to remove any items from their Jump Lists. By explicitly removing an item from the Jump List, you insert it into the Removed Items List, which we will discuss below.

Step 2 – Create Your Own Category

If the default Recent or Frequent categories do not meet your application's needs, it is time to create your own custom category. In order to do so, you need to use the ICustomDestinationList interface to create a custom Destination List.

The ICustomDestinationList exposes methods that allow an application to provide a custom Jump List, including destinations and tasks, for display in the Taskbar. Here are the methods that we are using for the example below:

  • AppendCategory Defines a custom category and the destinations that it contains for inclusion in a custom Jump List
  • AppendKnownCategory Specifies that the Frequent or Recent category should be included in the Jump List
  • BeginList Initiates a building session for a custom Jump List
  • CommitList Declares that the Jump List initiated by a call to BeginList is complete and ready for display

The following code snippet shows how to create a new custom list called “Custom Lists” and appends a few items to it:

void CreateJumpList()
{
ICustomDestinationList *pcdl;
HRESULT hr = CoCreateInstance(
CLSID_DestinationList,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&pcdl));
if (SUCCEEDED(hr))
{
//important to setup App Id for the Jump List
hr = pcdl->SetAppID(c_szAppID);
if (SUCCEEDED(hr))
{
UINT uMaxSlots;
IObjectArray *poaRemoved;
hr = pcdl->BeginList(
&uMaxSlots,
IID_PPV_ARGS(&poaRemoved));
if (SUCCEEDED(hr))
{
hr = _AddCategoryToList(pcdl, poaRemoved);
if (SUCCEEDED(hr))
{
pcdl->CommitList();
}
poaRemoved->Release();
}
}
}
}

Here you see that we started with a standard COM initialization call. We call CoCreateInstance to initialize the ICustomDestinationList object (this is the joy of working with COM….). Next, we set the Application ID in order to allow you to start populating items to the list.

The BeginList function initiated the build session for the custom Jump List. This function returns the maximum number of items that can fit in a given Jump List; the default is 10. You may note the Remove item parameter, IObjectArray *poaRemoved, that the BeginList() returned as an out parameter. This holds any specific items that the user removed from the Jump List in his current session. We discuss the Removed Items List later in this post.

Next we called a helper function, _AddCategoryToList(), to do the actual work of adding items into the custom category.

// This is the helper function that actually appends the items to a collection 
// object HRESULT _AddCategoryToList(ICustomDestinationList *pcdl,
// IObjectArray *poaRemoved)
{
IObjectCollection *poc;
HRESULT hr = CoCreateInstance
(CLSID_EnumerableObjectCollection,
NULL,
CLSCTX_INPROC_SERVER,
IID_PPV_ARGS(&poc));
if (SUCCEEDED(hr))
{
for (UINT i = 0; i < ARRAYSIZE(c_rgpszFiles); i++)
{
IShellItem *psi;
if (SUCCEEDED(SHCreateItemInKnownFolder(
FOLDERID_Documents,
KF_FLAG_DEFAULT,
c_rgpszFiles[i],
IID_PPV_ARGS(&psi)))
)
{
if(!_IsItemInArray(psi, poaRemoved))
{
poc->AddObject(psi);
}

psi->Release();
}
}

IObjectArray *poa;
hr = poc->QueryInterface(IID_PPV_ARGS(&poa));
if (SUCCEEDED(hr))
{
pcdl->AppendCategory(L"Custom category", poa);
poa->Release();
}
poc->Release();
}
return hr;
}

Another new interface that we use is the IObjectCollection that represents a collection of objects that support IUnknown. To this collection we add IShellItems. Each item (file) that we added to the Jump List is of an IShellItem type. In the above code, we created a Shell item object for a single file that exists inside a known folder, Documents. However, before we actually added the new item to the collection, we needed to determine if the user had already removed it. If the user explicitly removed an item from the Jump List, that item will be in the Removed Items List (again associated with the AppID), and, as developers, we need to respect the user's requests and avoid adding that item to the Jump List. We already have the list of removed items, IObjectArray *poaRemoved, that we got when we called the BeginList(…) function when we initiated creation of a new list.

At this stage, you have a collection of Shell items that the user expects to see in the Jump List. Next we added that collection to the ICustomDestinationList object and created a new category named “Custom category”, pcdl->AppendCategory (L"Custom category", poa);.

So now you have successfully created a new category in the Taskbar called “Custom category” and populated it with four items. However, our work is not done yet. The final step in the CreateJumpList function is to call CommitList() to end the “transaction” that began with calling BeginList(). Only after our call to CommitList() are the new category and new items displayed. Calling CommitList() causes the stored list of removed items to be cleared and a new Removed Items List to begin. The ICustomDestinationList interface provides a "transactional base" API.

In order to ensure a positive end user experience, make sure that a safe copy of the new repopulated list is complete and ready for use, and that the only operation the Taskbar must perform is to switch the pointer to the new list. The end result looks like:

image

Using the Windows API Code Pack we can write the same application using managed code.

Once we are sure that we are using the same AppID with all the Taskbar elements, we can create an instance of the Taskbar Jump List for the button that we are working on, as shown in the following code snippet. This code snippet is part of the CTOR of the main application window:

// Set the application specific id
Taskbar.AppId = appId;
// Retrieve the taskbar jump list
jumpList = Taskbar.JumpList;
category1 = new CustomCategory("Custom Category 1");
category2 = new CustomCategory("Custom Category 2");
// Add custom categories
jumpList.CustomCategories.Add(category1);
jumpList.CustomCategories.Add(category2);
// Default values for jump lists
comboBoxKnownCategoryType.SelectedItem = "Recent";

Here you can see that we set the AppID using the AppId property and created an instance of the Taskbar Jump List using the Taskbar.JumpList static property. We also create two categories, named Custom Category 1 and Custom Category 2. Next, we add these categories to the Jump List custom categories container. Last we set the Known category of this Taskbar Jump List to Recent. This will automatically get populated as described above.

After we set up the custom category, it is time to put some content in it. To do so, we just need to call the Add function to add a JumpListItem to the JumpListCollection. The JumpListItemCollection is a generic collection (of<IJumpListItem>) holding IJumpListItem items. IJumpListItem item is basically some sort of wrapper for the native IShellItem.

// Specify path for shell item
string path = String.Format("{0}\\test{1}.txt",
executableFolder,
category1.JumpListItems.Count);
// Add shell item to custom category
category1.JumpListItems.Add(new JumpListItem(path));
First, we need to construct a path to the file we want to include in the Jump List. Please remember that we can call the Add function only if this file is local and accessible to your user. The above code (along with a few other methods that we will describe in future posts), results in a Taskbar dialog that looks like:
image
Finally, we need to call the Taskbar.JumpList.RefreshTaskbarList() Function. As with the native Jump List implementation, we need to “commit” the changes made to the Jump List. A closer look at this Refresh function (you have access to it in the Code Pack API) shows a call to the AppendCustomCategories function that appends any custom categories to the Taskbar button Jump List. Within this function, you can find a managed code implementation of the native code shown above. It includes a call to the AppendCateogry function that is a wrapper for the native AppendCategory function above.
 
IObjectCollection categoryContent =
(IObjectCollection)new CEnumerableObjectCollection();

// Add each link's shell representation to the object array
foreach (IJumpListItem link in category.JumpListItems)
categoryContent.AddObject(link.GetShellRepresentation());

// Add current category to destination list
HRESULT hr = customDestinationList.AppendCategory(
category.Name,
(IObjectArray)categoryContent);
 

As you can see, it is easy to opt into the Windows 7 Taskbar functionality. Windows automatically performs most of the work for you and, if you do need to create your own category, that is also very easy.

In the next post we will describe how you can add new Tasks to the Jump List and how to register a file handler.


Announcing the Windows 7 Upgrade Option Program & Windows 7 Pricing – Bring on GA!

Today we have some news to share around Windows 7 including answering what may be some of the “hottest” questions people have as we head toward General Availability (GA) on October 22nd.

I had the opportunity to sit down with Brad Brooks, Corporate VP for Windows Consumer Marketing, to talk about today’s announcements.


Announcing the Windows 7 Upgrade Option Program & Windows 7 Pricing

Special thanks to Brad for taking the time to talk through these details with me. You’ll find a transcript of the video here.

As Brad discussed in the video, today we’re announcing details for the Windows 7 Upgrade Option Program, pricing, and a special pre-order offer for select markets.

But first, I want to talk a little bit more about GA and the worldwide availability of Windows 7. We’ve really focused a lot of our efforts on getting the product out to as many people around the world as quickly as possible. OEMs will start shipping PCs with Windows 7 in all language versions beginning on GA, October 22nd.

And for our retail software, we’ve made significant strides in terms of timing. Gone are the days when it could take months for all language versions to be available. In fact – we’ve narrowed the gap to just over ONE week!

On October 22nd, Windows 7 will be available in the following 14 languages: English, Spanish, Japanese, German, French, Italian, Dutch, Russian, Polish, Brazilian Portuguese, Korean, Simplified Chinese, Traditional Chinese and Chinese (Hong Kong).

Then on October 31st, the remaining 21 languages will become available: Turkish, Czech, Portuguese, Hungarian, Swedish, Danish, Norwegian, Finnish, Greek, Ukrainian, Romanian, Arabic, Lithuanian, Bulgarian, Estonian, Slovenian, Hebrew, Thai, Croatian, Serbian Latin, and Latvian.

Windows 7 truly is a global release and I’m excited to be able to tell my international friends that when I say Windows 7 will be available for the holidays – I mean everywhere in the world.

But, you don’t have to wait until GA to get a new Windows PC. In fact, we know many people need that new PC sooner – for back to school specifically. And we have the answer for people who need a new PC now but still want to get Windows 7 and that’s the Windows 7 Upgrade Option Program, which kicks off tomorrow, June 26th! Anyone who buys a PC from a participating OEM or retailer with Windows Vista Home Premium, Business or Ultimate on it will all receive an upgrade to the corresponding version of Windows 7 at little or no cost to customers. The Windows 7 Upgrade Option Program will be available until January 31st, 2010 – and is global! For more information on taking advantage of the Windows 7 Upgrade Option Program, visit www.windows.com/upgradeoffer.

Another one of the most common questions I get is: how much will Windows 7 cost? Well, today we’re sharing these details.

For Windows 7, we are reducing the price on our most popular retail product for customers, the Home Premium Upgrade, by approximately 10% (depending on the market). In the U.S., this means a customer buying Windows 7 Home Premium upgrade will pay only $119.99 instead of the $129.99 being charged today for its predecessor.

Overall, customers will be paying less and getting more with Windows 7. This includes fun new features such as HomeGroup, Device Stage, Aero Shake, Snap, Peek, Jump Lists and our completely redesigned Windows Taskbar (one of my favorite new features in Windows 7 today). These new features make your PC simpler and much easier to use.

So here’s the low-down on pricing for Windows 7. The estimated retail prices for upgrade packaged retail product of Windows 7 in the U.S. are:

  • Windows 7 Home Premium (Upgrade): $119.99
  • Windows 7 Professional (Upgrade): $199.99
  • Windows 7 Ultimate (Upgrade): $219.99

And the estimated retail prices for full packaged retail product of Windows 7 in the U.S. are:

  • Windows 7 Home Premium (Full): $199.99
  • Windows 7 Professional (Full): $299.99
  • Windows 7 Ultimate (Full): $319.99

This means that Windows 7 Home Premium full retail product is $40.00 less than Windows Vista Home Premium today.

As Brad describes in the video, for Europe, we will not have a separate upgrade SKU for the packaged retail product versions of Windows 7 at GA. But we will be offering upgrade pricing on our full licenses to make sure that European customers who want to upgrade have the pricing options available in the rest of the world.

Finally, as a way of saying thank you to our loyal Windows customers, we are excited to introduce a special time limited offer! We will offer people in select markets the opportunity to pre-order Windows 7 at a more than 50% discount. In the US, this will mean you can pre-order Windows 7 Home Premium for USD $49.99 or Windows 7 Professional for USD $99.99. You can take advantage of this special offer online via select retail partners such as Best Buy or Amazon, or the online Microsoft Store (in participating markets).

This program begins tomorrow in the U.S., Canada and Japan. The offer ends July 11th in the U.S. and Canada and on July 5th for Japan or while supplies last. Customers in the UK, France and Germany, can pre-order their copy of Windows 7 starting July 15th and will run until August 14th (or supplies last) to ensure folks don’t miss out on this. Act fast if you want to be the first in line to get Windows 7 at this screaming deal! Note: The special low pre-order price will vary per country.

For more information on this special pre-order offer, click here.

I am really excited to be sharing these Windows 7 announcements with you today. Because of the great feedback we received from you, we are confident we are poised to deliver a great product this fall!

Digg This