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.


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

Welcome to yet another Windows 7 Taskbar post. In the previous post, Developing for the Windows 7 Taskbar – Get to Know Your Application ID , we introduced a very important component of the underlying architecture of the Taskbar, the Application ID (AppID), which is the key controller of how different applications are grouped under the same Taskbar button. The AppID also has a direct affect on how Jump List items are aggregated and populated in the Jump List.

Microsoft designed the Windows 7 Taskbar to provide users with quick and easy access to those “things” they use most frequently. “Things” can be any type of content such as pictures, music, word documents or links and shortcuts to applications or folders, or any other type of “clickable” item in Windows. By quick and easy access, we mean the ability to access commonly used programs with a single mouse click or with a significantly reduced number of clicks per operation. Quick and easy access also means users should be able to “jump” directly to those things they want to work with and start working with them in a single mouse click. To provide this functionality, the Windows 7 Taskbar introduces the concept of “Jump Lists.” More info about the reasons and background for creating the Taskbar Jump List can be found in Chaitanya’s Engineering Windows 7: The Windows 7 Taskbar post, and Windows 7 New Taskbar - An Overview video on Channel 9.

As much as I love talking about the reasons for creating the new Taskbar (since I love user functionality and usability in general) I am going to focus on the API for using the Taskbar. As a developer, you should think of a Jump List as your application's own mini Start Menu. Jump Lists bring to the surface commonly used destinations (nouns) and tasks (verbs) of a program. This enables easy user access to destinations by eliminating the need to launch the application and then load the relevant content, or by performing common tasks without launching the application in advance. The following picture illustrates how Jump Lists work with Microsoft Office Word 2007. You can see that under the “Recent” category, there is a list of recent documents that I’ve used with Office Word. Clicking on one of the items in the “Recent” list will launch Office Word with the relevant document already loaded.

image
We previously identified Word 2007 as an example of an application that “plays” nicely with the Windows 7 Taskbar even if that application was released a long time before the Windows 7 Taskbar was available. The Taskbar buttons are all grouped under the same Taskbar icon and the Jump list is automatically populated with the most recently used Word documents. In the next post, I will explain in detail how Jump List are populated automatically like Office Word 2007 and word documents. For this post, let’s focus on the different Jump Lists players.

The default Out-of-The-Box tasks that are shipped provide the means to launch a new instance of the application, to pin or unpin an application to the taskbar, and to close the application. You can access the Jump List by right clicking on an application icon in the Taskbar. However, as the following picture illustrates, you can opt to take more control of the Taskbar experience by customizing the context of the Jump List for your application.

image 

Definitions from the Windows 7 SDK:

”… Destinations are items that appear in the Recent, Frequent, or custom categories (the 'Important' category in the diagram above), based on the user’s item usage. Destinations can be files, folders, Web sites, or other content-based items, but are not necessarily file-backed. Destinations can be pinned to or removed from the Jump List by the user. They are generally represented by IShellItem objects, but they can also be IShellLink objects…”

”…Tasks are common actions performed in applications that apply to all users of the application regardless of the individual usage patterns. Task can’t be pinned or removed. Tasks are represented by IShellLink objects because they are actually links (with parameters – optional) to commands – 'Actions'…”

As developer, you can:

  1. Control Application Destinations (that is control the items you want users to be able to “Jump” directly into and start working on)
    1. Destinations can be any one of the known categories such as Recent or Frequent.
    2. The Custom category is just like any other Destination category, except that it allows you to create a new name for that category as well as populate it with items of your choice.
    3. The Pinned category is provided for pinned items that users want to keep permanently in their Jump Lists. Please note: ONLY users can pin items in the Jump List, there is NO supported programmatic way that you, as developer, can pin an item.
    4. You can completely remove the Pinned category from the Jump List so the user cannot pin items – but you might want to think twice before preventing users from pinning items in your application.
  2. Define Common User Tasks
    1. The Taskbar surfaces its own out-of-the-box tasks such as launching, pinning/unpinning, or closing the application. As developers we have no control over the Taskbar Tasks. However, we do control the User Tasks.
    2. User Tasks are common tasks the application developer wants to surface at the Jump List level that will enable users to perform a task directly from the Jump List (for example, Play all music in media player without switching to media player). Usually, this will result in launching an instance of the application and performing the task, or launching another application, like Internet Explorer, when clicking on the “Go to MSN Home Page” task in the Windows Live Messenger Jump List as shown in the next picture. Again, all of the above Jump List functionality saves time and reduces the number of clicks needed to achieve the user's end goal, thereby making the user happy.

imageIn the next post, we will dive into the Taskbar Jump List API. But first, we need to address the Taskbar programming model. The Taskbar exposes its set of APIs like any other Windows Shell component, through a set of COM interfaces. However, there are a few actions we developers can do even before starting to use the Windows Taskbar COM APIs.


Developing for the Windows 7 Taskbar – Application ID – Part 2

[June 19th - I added a code sample and new screenshots.]

In response to some of the comments I included a link to the download and new screenshots to show the effect of changing Application ID in run time. And Just to make sure we are all on the same page here are two images to illustrate the power of AppID. You can clearly see that the same application (with the same original application ID) can have two different Taskbar buttons. You can also download the code for this application.

Taskbar_buttons_Multiplebuttone1

 Taskbar_buttons_Multiplebuttone2

Just a note as response to one of the comments. Yes you can place a different Taskbar button between to windows with different AppID!

download the code for this application

You can find the managed code Taskbar object in the Windows API Code pack project.


Developing for the Windows 7 Taskbar – Application ID

This is the first post in a new Windows 7 Taskbar series. One of the first Windows 7 changes that developers should pay attention to is the new Windows Taskbar. We all need to understand the functionality this feature introduces so that we can ensure that our applications work well with the Taskbar, resulting in an enhanced experience for our end users.

I assume that by now you are familiar with the basic functionality that Windows 7 Taskbar offers and the reasons behind the change we made from previous taskbar versions. If you are not familiar with and haven’t seen any demonstrations of the Windows 7 Taskbar, please watch the Windows 7 Taskbar Overview webcast on Channel 9. There are also great posts on the E7 blog like The Windows 7 Taskbar about some of the reasons we introduced the new Taskbar and desktop experience in Windows 7. I do encourage you to read these posts and watch the video so that you have some context for the technical material we are going to cover here.

The new Taskbar is probably the most noticeable change to Windows 7 when you first log on. The Windows 7 Taskbar is an application-launching and window-switching mechanism that consolidates the functions of previous Windows Desktop mechanisms, such as Quick Launch, Recent Documents, Notification Area icons, desktop shortcuts, and running application windows. Windows 7 Taskbar offers features like Jump Lists, Preview Handler, and Overlay Icons. But before we start diving into the various Windows 7 Taskbar features, let’s lay the basic foundation to our discussion and define some Windows 7 taskbar terminology.

The basic component is the Taskbar button. The Taskbar button is represented as an icon displayed on the Taskbar. As you can see in the following image, the Taskbar contains several buttons. You can tell what their status is by how they are displayed.Taskbar_buttons1

For example, the Media Player button has no frame or border, but simply sits directly on the Taskbar. This indicates that Media Player is not running. But it is pinned to the Taskbar, and will stay on the Taskbar unless we unpin it. A transparent frame that lets most of the color of the underlying Taskbar through the Windows Explorer button. This indicates that the app is running but is not the active application. The Visual Studio icon has a more opaque rectangular frame underlying its icon indicating that the user is actively using this app. You will also notice that Word has a “stack” of icons representing that multiple instances of Word or multiple Windows are grouped under the same Taskbar button. It is very important to understand the logic that underlies the creation, assignment, and grouping of Taskbar buttons.

A very large number of applications that run on Windows 7 (for example, Office Word 2007 and Visual Studio 2008), were not designed to work with the Windows 7 Taskbar, so how is it that they can play ball with the Taskbar, group multiple instances, and even take advantage of Word Jump Lists? Basically, a behind-the-scenes Application ID (AppID) is automatically computed and assigned to an application once you launch it. Every running application has an AppID assigned to it, either automatically computed for the app by Windows, or set by the app itself. Guess what? It is not a GUID; it is just a string (with a maximum of 128 characters), that either you provide or is being computed by the OS. All windows and applications, including Jump Lists, which have the same AppID are grouped under the same Taskbar button. Therefore, it is important to understand that every component (process, shortcut, window, Taskbar button, and document type – that is, registered file type handler) of your application has the AppID associated with it.

You may ask, "Where do AppIDs come from?" As mentioned before, the OS generates Application IDs for your application using a very simple, yet important to understand heuristic. Since in Windows 7 you can assign AppIDs to individual windows, the OS tries to extrapolate the AppID from a window. Applications usually display at least one window that the OS can query for its AppID. However, most existing apps do not have an AppID attached to each window (or, for that matter, any AppID at all), and therefore the OS falls back to the process to which the window belongs for the AppID. Each process has several properties that the OS can check, like the executable of the process. But even then, the process may not provide a granular enough separation. Different shortcuts may provide different start up command line parameters to the same executable and launch different applications (imagine a “launcher” application) that will be grouped under the same Taskbar button. In such cases, the OS has the ability to look into the specific shortcut that launched the application, to find the executable, the command line parameters, and so on. Note that if you have a register file, this registration points to an application that gets launched once you double click that file. Again, this is another way to calculate the AppID. The following image illustrates this automatic computation process. image

If you are interested in really understanding the internals of the Windows 7 taskbar, a great Channel 9 video describes its underlying architecture. Watch the Rob Jarrett and Ben Bets Windows 7 Taskbar - Behind the Scenes video and, specifically for the Application ID overview, watch Jump into the Windows 7 Taskbar Jump Lists (between 29:30 and 34:40).

While the OS can compute AppIDs for you, you may want to have greater control over the AppID for a given application or even an individual window in your application. Assume that you have an application that hosts (runs) another application (like what happens when you debug an application using Visual Studio). Or you have several different applications or processes that you wish to group under the same Taskbar button. The Taskbar API offers you ways to control the Application ID per application or per window. IN ANY CASE, if you are writing a new application that targets Windows 7, we highly recommend that you provide your own application ID, as we will describe below.

OK, let’s examine the API that allows you to control the AppID associations of your application.

If you want to have a separate Taskbar button for each process (including all windows owned by that process), you can set an explicit AppID for the entire process that affects all windows within the process that do not have their own explicit AppID. Setting the explicit process AppID is very easy. All it takes is a single call to the SetCurrentProcessExplicitAppUserModelID function as shown in the following code snippet:

SetCurrentProcessExplicitAppUserModelID(c_rgszAppID[0]);
Where c_rgszAppID[0] is a pointer to a string. You should note that according to the SDK documentation, “This method must be called during an application's initial startup routine before the application presents any user interface (UI) or makes any manipulation of its Jump Lists.”

In managed code, from the latest Windows API Code Pack Library, you can use the AppID property that is part of the Taskbar object, which you can find in the Microsoft.WindowsAPICodePack.Shell.Taskbar namespace. Using that property you can set and get the application ID of a given application.

Setting the AppID for a window is a bit more complicated (but only a bit). It requires calling the SHGetPropertyStoreForWindow function and then manipulating the resulting IPropertyStore object to retrieve the requested property as shown in the following code snippet:

void SetAppID(HWND hWnd, int iAppID)
{
IPropertyStore *pps;
HRESULT hr = SHGetPropertyStoreForWindow(hWnd, IID_PPV_ARGS(&pps));
if (SUCCEEDED(hr))
{
PROPVARIANT pv;
if (iAppID >= 0)
{
hr = InitPropVariantFromString(c_rgszAppID[iAppID], &pv);
}
else
{
PropVariantInit(&pv);
}
if (SUCCEEDED(hr))
{
hr = pps->SetValue(PKEY_AppUserModel_ID, pv);
PropVariantClear(&pv);
}
pps->Release();
}
}

Here you can see how we extract the current windows property store by calling SHGetPropertyStoreForWindow, passing hWnd as refrence to the window. Next we initiate, InitPropVariantFromString(c_rgszAppID[iAppID], &pv), a property variant with a string that represents the AppID for that window. Finally, we set the value of the new property store to the window.

Unfortunately, the current Windows API Code pack doesn’t support setting specific application IDs per window, although all you need to do is add the following function to the Taskbar.cs file:

private static void SetWindowAppId(string appId)
{
Microsoft.WindowsAPICodePack.Shell.ShellNativeMethods.SetWindowAppId
(OwnerHandle, "name here");
}

Since the Windows API Code Pack provides the source code, you can actually check the specific implementation of SetWindowAppId function and see for yourself that it is very similar to the SetAppID example above. Note you don’t have to use the full qualified assembly name “Microsoft.WindowsAPICodePack.Shell’, but I did to help you navigate the Windows API Code Pack hierarchy.

By the way, the window AppID is dynamic, so it’s entirely possible for a window to show up as part of one Taskbar button and then change its AppID so that it appears on an entirely different Taskbar button. This has interesting effects. For example, the Jump List is attached to a Taskbar button (with a specific AppID), so the same window might show a different Jump List when it is reattached to an entirely different Taskbar button. This potentially can confuse users, so the recommended practice is to set the window AppID and stick to it, using the same process for determining the AppID every time the window displays.

You can find the managed code Taskbar object in the Windows API Code pack project.

[Sasha Goldshtein helped write this post, and you can find his original posting here].


Windows 7 Deep Dive Lab Event

In this post I will deviate from our normal routine of writing about Windows 7 features, APIs, and code samples, and will instead talk a little about an amazing opportunity to attend the Windows 7 "Deep Dive" Development Lab at the Microsoft Campus in Redmond, Washington on 6-8 July 2009.

A Deep Dive lab enables you to work on scenarios of your choice with experts from the Windows 7 product team. This is not a traditional training event. This is a special onetime event and a unique opportunity to meet the people who build Windows 7. The agenda includes a few presentations and some lab time, but our goal is for you to work on your own application(s) with our experts, focusing on how Windows 7 features like Sensor and Location, Taskbar, Multi-Touch, Libraries, Graphics, Ribbon, XPS & Print Path, Performance and Instrumentation, Troubleshooting Pack, and Application Compatibility can add value to your applications.

If accepted into the Deep Dive lab, you will be working on your own applications with members from the Windows 7 product teams. Meetings with specific team members may also be arranged as required and upon request. We are also available to assist you with Windows 7 compatibility issues to ensure that your application is Windows 7 compatible. Each participating group gets its own lab room, which accommodates up to 4 people, in which to develop the solution.

Who can come?

Up to four people from each company, normally developers and architects.

What does it cost?

There is no charge for the event. Microsoft will provide a light breakfast and lunch during the 3-day event, and will also provide one on-site dinner. You are responsible for any other expenses including accommodations, travel costs to Redmond, and evening meals.

How do I nominate my organization?

Due to high demand, Deep Dive developer labs have extremely limited capacity, and enrollment is based on a nomination process. Please complete the nomination form and e-mail it to dpewin7@microsoft.com. Nominations will be evaluated based on the project scenario and its status. The information you provide will also help us to prepare for your arrival at the Lab. You should receive an acknowledgement e-mail within few business days. Once we have verified your nomination form and selected your team as participants, we will send you more detailed event logistics.

Please do NOT make travel arrangements until your participation has been confirmed.

Windows 7 Deep Dive Nomination Form

Primary Contact - Provide primary contact information for communicating information related to the event:

  • Primary Contact Name:
  • Primary Contact E-mail:
  • Primary Contact Phone:

Deep Dive Attendees - List the names of the individuals likely to attend the Deep Dive Lab and their roles on the team:

Project / Product Details - Provide some background information about the application(s) that you wish to work on during the event:

  • Project Name:
  • Scheduled Release Date:
  • Description (Include purpose, software environment, and users):

Windows 7 Features - Provide a list of the Windows 7 features you wish to incorporate into your application:

Please complete the nomination form on the next page and e-mail it to dpewin7@microsoft.com.


Windows 7 RC Training Kit for Developers

This week we released the Windows 7 RC Training Kit for Developers as part of our ongoing effort to give you, all the Windows developers out there, and valuable content to work with while making your application shine on Windows 7. This version of the training kit includes 10 presentations and 8 Hands-On-Labs (HOL), covering most of the Windows 7 light-up features as well as application compatibility topics. Note that the HOL gives you the opportunity to get firsthand experience in programming key Windows 7 Light-Up features, such as the Taskbar, Libraries, Multi-Touch, Sensors and Location, Graphics, Ribbon, Trigger Start Services, Instrumentation and Event Tracing for Windows (ETW). We also provide a brief Application Compatibility overview.

This is an “early preview” to the full set of Windows 7 Training for Developers that will be released shortly after RTM. You can download the training kit and get started, but make sure you have a Windows 7 RC machine to work with, and install Visual Studio 2008 SP 1 and Windows 7 RC SDK as some of the native applications requires libraries from the SDK. image

Modules:

Taskbar

The Windows 7 Taskbar is a differentiating opportunity that allows applications to shine on the Windows 7 platform. The new Taskbar streamlines many end-user scenarios including launching applications, switching between running applications and windows within a single application, managing recent/frequent user destinations, accessing common application tasks, reporting progress and status notifications through the taskbar button, and controlling the application without leaving the taskbar thumbnail. The Taskbar is the end user’s primary point-of-contact for initiating and managing activities; as such, the integration of the new taskbar features into modern Windows 7 applications is a critically important goal. This module talks about the different aspects and APIs associated with programming the Windows 7 Taskbar.

Libraries

Libraries are the new entry points to user data. Libraries are a natural evolution of the 'My Documents' folder concept that blends into the Windows Explorer user experience. A library is a common store of user defined locations that applications can leverage to manage user content as their part of the user experience. Because libraries are not file system locations, you will need to update some applications to work with them like folders. This module explains the basic concepts underlying Windows 7 Libraries, including how to make your application library-aware, how to work with libraries as though they were file system folders, and how to leverage the library system.

Multi-Touch

Windows 7 features improved touch and gesture support that empowers developers to quickly and easily create unique application experiences that go beyond simple mouse pointing, clicking, and dragging. The new multi-touch APIs support rich gestures, such as pan, zoom, and rotate. The Windows 7 Multi-Touch Platform also provides raw touch data inputs and advance manipulation and interties. This module explains the basics of Windows 7 multi-touch and its APIs.

Sensor and Location Platform

Windows 7 has changed how developers use sensors. The Sensor and Location Platform includes native support for sensors, expanded by a new development platform for working with sensors, including location sensors such as GPS devices. Built on the Sensor platform, the new Windows Location APIs enable application developers to access the user’s physical location information. This module explains what the Sensor and Location Platform is and how to work with its APIs.

Ribbon

Windows 7 incorporates the Ribbon interface introduced in Office 2007 throughout the operating system, enabling improved user interface development on the platform. This means that developers can eliminate much of the drudgery of Win32 UI development and deliver a rich, graphical, animated, and highly familiar user interfaces by using a markup-based UI and a small, high-performance, native code runtime. The Ribbon control helps developers improve usability by exposing your application's most frequently accessed features directly to end users. The Ribbon makes it easier for end users to find and use application features because functionality is more visible, resulting in greater productivity. This module shows the different aspects of the Windows 7 Ribbon and provides a guide on how to incorporate the Windows 7 Ribbon into existing applications.

Background Processes, Services, and Tasks

Services and background processes have tremendous influence on the overall performance of the system, and therefore the applications. If we could cut down on the total number of services, we could reduce the total power consumption and increase the overall stability of the system. The Windows 7 Service Control Manager has been extended so that a service can be automatically started and stopped when a specific system event, or trigger, occurs on the system. Trigger-start capabilities remove the need for services to start up automatically at computer startup and then poll or wait for an event to occur. This module explains the different options available to developers for configuring and using trigger-start services.

Windows 7 Instrumentation and Performance

Windows 7 includes new Event Tracing for Windows (ETW) capabilities that developers can take advantage of during the development process to optimize application performance. Instrumentation has always been part of Windows, but Windows 7 includes new ETW underlying technology that makes the task of including instrumentation in your application a whole lot easier. This module describes the different options for using instrumentation in Windows, including the new ETW.

Windows 7 Application Compatibility

Windows 7 is built on top of Windows Vista, which means if your application does not work or if it has some issues when running on Windows Vista, most probably it will have similar issues running on Windows 7. This module is a short overview of the top major issues regarding Windows 7 compatibility, including Data Redirection, Service Isolation, Version Checking, and High DPI.



Windows 7 Libraries – Managed Code

We are wrapping up our comprehensive drilldown into the Windows 7 Libraries API and architecture with one final post about the managed API for working with Windows 7 Libraries. Previously we talked about: Understanding Windows 7 Libraries, Libraries Under the Hood, Light Up with Windows 7 Libraries, Consuming the Contents of Windows 7 Libraries, Stay in Sync with Windows 7 Libraries, Windows 7 Libraries Helpers

In this post we focus on the managed API for working with Windows 7 Libraries. The Windows API Code Pack for the Microsoft .NET Framework Library (Windows API Code Pack) provides a .NET interface into the Windows native API, thereby enabling the 7 key Windows Light-Up features as well as tapping into more advanced shell integration, as we described in the Windows 7 Managed Code APIs post. You can download the Windows Code Pack API

The Windows API Code Pack has a very good managed interface to the Windows Shell, and particularly to the Windows 7 Libraries API. ShellLibrary (a part of the Microsoft.WindowsAPICodePack.Shell dll that you need to add as a reference to your .NET application in order to work with Windows 7 libraries), is the only object that represents Libraries. The image to the left displays the ShellLibrary class.

Now you can start working with Libraries. First, you need to create a Library object using one of the four available constructors. You might want to use the constructor that takes a Known Folder as a parameter. This is to allow developers easy maintenance while developing. Note, however, that most constructors receive an overwrite Boolean. Make sure you don’t overwrite your own existing Documents library (or any other library), since the creation of a new

image

ShellLibrary object saves the library’s XML detention file to the Library’s Known Folder, as we described in Libraries Under the Hood. The following single line of code creates a new ShellLibrary object, thus creating a new Library.
ShellLibrary library = new ShellLibrary(“new test lib1”, true);
 
If you don’t have to create a new library, you can load an existing library to obtain the required ShellLibrary object. Keep in mind that all load functions are static functions that don’t require an already existing ShellLibrary instance. Every load function’s last parameter is a isReadOnly Boolean that you may use when you just need to read a library's contents and without changing it. For example, an application that backs up all your libraries has no need to change the library. The following code snippet is all that is needed to load an existing library:
ShellLibrary library = ShellLibrary.Load("My Pictures", true);
 
OK, you have a ShellLibrary object -- what can you do with it? Well there are few things ways to have fun with libraries. First, you can add or remove specific folders from the library. Remember that libraries are just abstract containers and don’t really hold files, but just point to the actually folders that do hold the files, as explained in the Understanding Windows 7 Libraries post. To add a folder just call the Add function, in a similar way, call the remove function to remove a folder. You can add or remove folders by either using a specific path represented by a string or using a FileSystemFolder object as shown in the following code snippet:
public void Add(FileSystemFolder item);
public void Add(string folderPath);
public bool Remove(FileSystemFolder item);
public bool Remove(string folderPath);
 
Besides managing folders in your library, you can also set the default save location of the library by using the DefaultSaveFolder property. Assuming the library is a ShellLibrary object, the following code snippet returns the default save location of the Library:
String dsfStr = library.DefaultSaveFolder

Note that when setting the default save folder, you need to provide a valid system folder for which you have write and read permission. If this folder is not already part of the library, it will be added to the library and will become the default save location. As a developer, you can also add unsupported folder locations that are not indexed and can’t be indexed.

Another very cool feature is control of the library icon. This one of those features that end users don’t have access to, and it is SO easy to use, as shown in the following code snippet:

library.IconResourceId = new IconReference(icon);

You will have to obtain an IconReference object, but after doing so you get to change the library’s Icon and set your own special icons. This is a really fun feature to play with, as you can see from the following picture:

 image

Another important feature of the ShellLibrary object is the capability to list all the items and folders in a library. The ShellLibrary object implements the IList<FileSystemFolder> interface. This supports enumeration of the folders in the library by calling the GetEnumerator function or by using the foreach statement as shown in the following code snippet that prints the folder’s name and default save location:

foreach (ShellFolder folder in library)
{
Console.WriteLine(
"\t\t{0} {1}",
folder.Name,
defaultSaveFolder == folder.Name ? "*" : "")
}

You can control the library type by using the LibraryType property, and you can elect to pin the library listing to the left navigation pane of Windows Explorer using the IsPinnedToNavigationPane property.

Last, I want to talk about displaying the Library Manager window. It is important to display this window if you wish to create a consistent user experience for managing libraries in Windows Explorer and your application. Since displaying the Library Manager window displays a new dialog window in an existing application, you need to take into account the technology used by the application. The function ShowManageLibraryUI can receive either a Win32 window handle (whnd) that will work great with WinForms, or a WPF windows object for WPF applications.

library.ShowManageLibraryUI(IntPtr.Zero, “title of dialog”, "help text…", true);
 
The last thing we are going to talk about is deleting a library. The ShellLibrary object doesn’t have a self destruct mechanism and therefore you can’t delete a library using the ShellLibrary object. To delete a library you need to delete the library XML definition file. The code snippet below gets a string representing the library name that correlates to same library definition file. See Understanding Windows 7 Libraries for more information.
public static void DeleteLibrary(string name)
{
string librariesPath = Path.Combine(
Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData),
ShellLibrary.LibrariesKnownFolder.RelativePath);

string libraryPath = Path.Combine(librariesPath, name);
string libraryFullPath = Path.ChangeExtension(libraryPath, "library-ms");

File.Delete(libraryFullPath);
}
As you can see, we first use a combination of the Environment.SpecialFolder.ApplicationData and the ShellLibrary ShellLibrary.LibrariesKnownFolder.RelativePath to assemble the folder in which all the libraries definition files are stored. Then we append the library-ms file extension, and finally we delete the file. Remember, by deleting the file, we delete the library; so again, be careful not to delete any important libraries.

We have covered all the important functionality of the Libraries managed code API and, together with the previous posts; you now should have a very good sense of how Windows 7 Libraries work and how to use them in your applications.

In addition, you can get first-hand coding experience with Windows 7 by going through the Windows 7 Libraries Hands-On-Lab (HOL) that is part of the Windows 7 RC Training Kit for Developers. The Library HOL includes the code used in this post, so go ahead and download the training kit.