Developing for the Windows 7 Taskbar – Application ID

    Developing for the Windows 7 Taskbar – Application ID


    Posted: 18 Jun 2009
    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.

    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.

    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].



    More...
    z3r010's Avatar Posted By: z3r010
    18 Jun 2009



 

Our Sites
Site Links
About Us
Windows 7 Forums is an independent web site and has not been authorized, sponsored, or otherwise approved by Microsoft Corporation. "Windows 7" and related materials are trademarks of Microsoft Corp.

© Designer Media Ltd
All times are GMT -5. The time now is 03:48.
Find Us