Your best source of information and news about microsoft, winvista and hardware on the internet

Vista ARTICLES TOP 50 Spyware Virus Vista SOFT Vista HELP

Sample Code

You are currently browsing the articles from MS Windows Vista Compatible Software matching the category Sample Code.

Fishbowl for Facebook Using the Windows 7 Taskbar for Extra Spice

During Wednesday’s keynote, Brian Goldfarb demoed an amazing Silverlight 4 client for Facebook. Beyond its amazing looks, this Silverlight 4 demo provides a full and complete desktop client application for Windows (and Mac). SilverFace is built on top of Silverlight 4 – also announced during the keynote. If you want a cool Facebook client application to work on from your Windows desktop, you should take a look at the Fishbowl for Facebook Preview. Fishbowl is a great WPF application that you can install and enjoy as a user, and at the same time it is a great code sample for developers whom are looking to write WPF applications that use Windows 7 features.  If you are interested, you can download the source code for Fishbowl.

In today's world, the client’s experience is more important than ever before. Your application doesn’t just have to be fun and interesting; it has to be good looking, polished, and functional, providing a “natural” user experience that just works. As a developer, you need to push the envelope and use any available technical tool that the OS provides or any other available means (if installed on mobile devices) to provide a superior user experience, or users will switch to the next guy. In such a competitive scenario, using the Windows 7 Taskbar to shave a few seconds from day-to-day tasks looks like a very obvious choice.

Both Silverlight 4 demo and Fishbowl applications each provide a great UX and enhance user productivity. Scott Guthrie also announced the Facebook SDK for managed code applications that combines the latest in Web and Client platform innovations with leading Social technologies (services) to help developers plug into Facebook. But, beside the new Facebook SDK and beside the great looks, the Fishbowl application is a great WPF (3.5) example that demonstrates how to write applications that produce amazing experiences on Windows 7.

As a WPF application, Fishbowl runs on multiple Windows versions, including Windows XP, Windows Vista, and Windows 7, and it integrates with the Windows 7 Taskbar and Multitouch. One of the main ideas behind the Taskbar is to provide users with quick and easy access to their content and help them accomplish tasks and navigate between windows easier and with more confidence. For example, JumpList provides a great tool for surfacing common work items and tasks. If you have a task that you perform once or twice a day, taking two or three clicks to perform the task is not that bad. However, if you have a task that you perform 10, 20, or even 30 more times, using JumpList tasks or items in the recent category list goes a long way. Facebook users often check their wall, write notifications and messages, view friends' pictures, and so on. Therefore, in some scenarios, the Taskbar JumpList tasks, icon notification, thumbnail buttons, and other functionality become major tools in the application.

Fishbowl uses the taskbar to provide a quick, easy, and seamless integration with Facebook functionality directly from your Taskbar. Let’s review some of the user functionality before jumping into code behind.

The Fishbowl taskbar offers a few tasks even before you start your application. You can go to Facebook.com, or you can actually “jump” directly and see your wall, friend's picture, and more, as the following image shows.
One of the amazing things in Fishbowl for Facebook is that it changes it functionality between the different modes of the application. Being able to use the taskbar differently for
TaskbarBeforeStart

different scenarios provides an amazing user experience in heavily used application like Fishbowl.

When Fishbowl runs in normal mode, the Taskbar JumpList reflects items and tasks that you can actually perform in the context of a running application, like viewing the last few notifications and messages that you received without opening the application, as shown by the following image.

TaskbarAfterStart If you hover with the mouse above the Fishbowl control, you see the thumbnail preview provided by Windows 7 taskbar. However, Fishbowl uses the thumbnail button again allowing you to both view a preview of the application and act immediately upon the thumbnail preview as shown in the following image.

If you hover with the mouse above the Fishbowl control, you see the thumbnail preview provided by Windows 7 taskbar. However, Fishbowl uses the thumbnail button again allowing you to both view a preview of the application and act immediately upon the thumbnail preview as shown in the following image.

thumbnail button

(And thank you Raman for writing so many PDC tweets J)

Fishbowl also has a mini-mode operation mode. This mode shows just one message in a small window. As you can see in the following image, a small arrow allows you to switch between messages. When you hover over Fishbowl taskbar icon, you can see the preview but you can also control the message, again using the taskbar thumbnail preview.

 minimode

Besides great Taskbar integration, Fishbowl offers a great Multitouch experience, allowing you to scroll between messages using your finger to touch the touch screen. It is a little hard to illustrate Multitouch with screen capture so you will have to trust me on this one.

We've covered most of the Fishbowl features unique to Windows 7, and in the next post I will dive into the API that enabled these Taskbar and Multitouch features. If you are interested, you can download the source code for Fishbowl.

Written by Yochay Kiriaty on November 19th, 2009 with no comments.
Read more articles on Sample Code and Multi-Touch and PDC09 and PDC2009 and Windows API Code Pack and otherSoftware and windows 7 and Microsoft and .Net and Developers and taskbar and Windows.

New Windows API Code Pack Version

I am glad to announce that today we shipped a new version of the Windows API Code Pack – version 1.0.1. This is not a major version with a lot of new features, but rather a minor version focused on fixing bugs, improving performance, adding demos and few features updates (new wrappers…)

But before we dive into this new version of the Windows Code Pack let’s better understand what this Windows API Code Pack is all about.

Windows 7 offers new features like the taskbar, libraries, and the Sensor and Location platform, to name a few. These features enable new scenarios and create new opportunities for developers to make their applications shine on Windows 7. All these great features are exposed via the Win32 native API. Currently there is no “Windows 7” namespace in the .NET Framework, and no easy way to use these features from managed code applications. To help managed code developers access them, we released version 1.0 of the Windows API Code Pack for the .NET Framework in August (just after Windows 7 RTM).

The Windows API Code Pack is a free, managed Source Code Library provided by Microsoft as is. You should consider this library as if you wrote it yourself, as if it is your own code. It is a great starting point and provides a really good and solid solution for managed code developers. It covers a lot of the new Windows 7 features as well as some more fundamental core features from the Windows Vista timeframe. You may think of the Windows API Code Pack as the closest thing to an “official” managed API for Windows. But you need to remember that it’s not a product with 24x7 technical support available from Microsoft Customer Service and Support. We believe it is a great solution, and that the codebase is very solid and high quality.

Our goal with the code pack is to enable managed code developers to take advantage of Windows APIs that are not part of the .NET Framework. We feel that as a shared source that is separate from the .NET runtime libraries, the Windows API Code Pack provides an optimal compromise between the Microsoft Win32 managed wrapper, short time-to-market -we released the Windows API Code Pack just a month after the Win7 RTM, and we ship full source code of the library.

The Windows API Code Pack includes a great deal of managed API for Windows (7). For example:

  • Extensive integration with the Windows Shell namespace, with support for the Windows Shell property system, providing control like explorer browser and access to Windows Libraries
  • A completely 100% feature parity with the native Taskbar API including (but not limited to) JumpLists, Icon Overlay, Progress bar, Thumbnail, custom switcher, Thumbnail Button, etc…
  • Windows Task Dialogs , other controls
  • Support for Direct3D 11.0 and DXGI 1.0/1.1 APIs
  • Support for the Sensor Platform APIs
  • Extended Linguistic Services APIs
  • Windows Restart Manager
  • Power APIs
  • And many other features

Each technology represented in the Windows API Code Pack has multiple demos and examples (including source) in C# and VB. We are planning on releasing updates to the Windows API Code Pack roughly every three months. We will be investing mainly in stability (meaning fixing bugs), fundamentals, testing and documentation, as well as new feature support (based on customer feedback).

You may ask yourself, “Why isn't the Windows API Code Pack part of the .NET Framework?

We ship open source code that we might bring into the runtime sometime in the future, if we feel it's sufficiently core to the entire framework to be worth the size increase. Remember the .NET Framework runs on both Windows Vista and Windows XP. However, Windows 7 is here now, and we want to enable you to access this set of free, open source library sooner rather than later. We’re shipping this library in a community-supported form and, as you can see, we intend to keep updating it. While this version (1.0.1) is a minor release, we are planning on another release in the next few months. In the meantime, you get the best of both worlds in a package that you can use as a whole or in parts without restriction.

Another question you may ask is, “Will .NET 4 replace the need to use the Windows API Code pack?”

When .NET 4 ships, you will be able to use its Windows 7 features such as Taskbar and multitouch integration with WPF, DirectWrite support, and the location API via the Devices namespace. Continue to access other features such as libraries, Restart Manager, and Sensors via the Windows API Code Pack.

Last but not least, we are looking for feedback from the community – that is you the .NET developer using this library to write managed code applications for Windows 7. On the Windows API Code Pack site, you can ask questions, provide feedback, report bugs, and follow open bugs. Your input is critical for the continuation of this library, so please send us your feedback and questions.

To learn more about how to use the Windows API Code Pack check the Windows 7 Training on Channel 9

Written by Yochay Kiriaty on November 18th, 2009 with no comments.
Read more articles on Sample Code and Sensor and Location and Windows API Code Pack and Libraries and otherSoftware and Microsoft and .Net and taskbar and Windows.

Windows 7 RTM – Go Get It

This is it people. Windows 7 RTM is available for download from MSDN & TechNet sites! If you have a MSDN subscription you can get Windows 7 RTM in English. On October 1st, the remaining languages will be released, for more information read - Windows 7 RTM Available Today for MSDN & TechNet Subscribers. You can also get the Windows 7 SDK  and the RTM version of the Windows API Code Pack for .NET Framework.

Make sure you get them all today to start testing your applications, and to make sure your applications are ready for Windows 7 RTM! Now is the time to work on your applications to make sure they are Windows 7 compatible. On top of that, you can use new Windows 7 features such as the Sensor and Location Platform, Taskbar, Libraries, Multi-Touch, the new Graphics APIs, the Windows Ribbon, and many other important and exciting Windows 7 technologies to make your application shine on Windows 7.

New Windows 7 Training Kit for Developers - Get it NOW!

To help you get your application on Windows 7 as soon as possible, we updated the Windows 7 Training Kit for Developers for the RTM version and gave it a new look and better functionality. You can still find all existing topics such as: Taskbar, Sensor and Location, Libraries and Shell, DirectX, Multi-touch, Ribbon, etc. No dev was left behind! The kit is built for both native Win32 Windows7TrainingKit

C++ developers and .NET developers, so now most topics have multiple labs.We also added 6 new Application Compatibility labs: Version Checking, Data Redirection, UIPI, Installer Detection, Session 0 Isolation, and High DPI, to help you get over the most common application compatibility issues. All the topics in the training kit include additional information like whitepapers, links to MSDN, and links to videos from Channel 9.

 Updated Windows Topic Area on Channel 9

We also gave the Windows topic area on Channel 9 a brand new look and functionality to help you to better choose the right Windows 7 content you need. In the new Windows topic area for Channel 9, you can choose from three main topic areas:

NewC9

While we hope you find all this helpful, this is only the start! We are working on more new and exciting content that will be shipped in the following weeks, so stay tuned.

In the meantime, here is some additional useful information:

  • The Windows page on MSDN is the one-stop shop for Windows client developers
  • At Develop for Windows 7, you can find all the information you need about specific technologies like Direct2D, Taskbar, Sensor and Location, Power Shell 2, Windows Ribbon, and many more
  • Windows Application Compatibility is the one page you want to visit to make sure your application runs properly on Windows 7; it includes content and tools to test and fix many application compatibility issues. Directly accessible from that page, is the Windows 7 Application Quality Cookbook
  • Also still very relevant, is the Windows Vista Application Compatibility Cookbook--most Windows 7 compatibility issues are the direct result of the changes introduced in the Windows Vista timeframe, and are included as topics in this Cookbook (UAC, Session 0 Service Isolation, IE Protected Mode, etc.), which is a great starting point for addressing these issues
  • New Windows 7 videos on the Channel 9 Windows page explore specific features and technologies, and are great “windows” to the Windows engineering team
  • As always, the E7 blog is an amazing source of the engineering back story behind Windows 7
  • Last, but not least, for IT-Pro, we have our SPRINGBOARD SERIES, and edge on TechNet

And, of course, continue to watch for new posts.

Written by Yochay Kiriaty on August 6th, 2009 with no comments.
Read more articles on Sample Code and Windows 7 Application Compatibility and Labs and Windows 7 Training Kit and Channel 9 and otherSoftware and .Net and Developers and windows 7 and Microsoft.

Version Checking (Just Don’t Do It)

Version checking is probably one of the most common Application Compatibility issues that both developers and users are facing. This is another post in a series of posts about Getting Ready for Windows 7.

As said, this is probably the most common application compatibility issue that users as well as developers face is when an application fails upon checking the operating system version. A lot can go wrong when version checking is misused. A user might experience a “silent fail” where the application simply fails to load and nothing happens. Or, a user might see a dialog box indicating something to the effect of “you must be running Microsoft Windows XP or later” when in fact, the computer is running Windows 7. Many other consequences to poor version checking can inconvenience users as well.

Applications fail due to version checking for two main reasons:

  • A flaw (bug) in the version checking code, which fails if the minor version is decreased, even if the major version is increased, for example, changing versions from 5.1(Windows XP) to 6.0 (Windows Vista), or if the expected service pack (SP) is not installed, even if you're running a newer operating system (for example, changing versions from Windows XP SP 2 to Windows Vista SP 1). We recommend that you check functionality rather then checking version, as you can read in this post.
  • An intentional blocking that prevents the application from running on operating system versions not tested by its developers. We recommend that you do not block applications from running on future operating systems.

When an application runs on an "incompatible" (due to poor version checking) version of Windows, it will generally display an error message, but it may also exit silently or behave erratically. Often, if we work around the version checking, the application will run well. End-users and IT professionals may apply a fix to let the application think it is running on an older version of Windows.

Working Around The Problem (not really solving the bug)

Compatibility mode: Designed for end users (not for developers to not fix their bugs), compatibility mode is an easy way to work around compatibility issues. When enabled, it applies a set of compatibility fixes that provide a runtime environment more compatible with applications written for older versions of Windows. One of those fixes is the "version lie," which makes the version query functions return the operating system version the user chose in the Compatibility tab of the Properties dialog box instead of the actual Windows version.

To enable compatibility mode:

  • Right-click the executable or shortcut to the executable.
  • Click Properties.
  • Click the Compatibility tab.
  • Enable Run this program in compatibility mode for: and select the operating system version you think the application should be able to run on.
    Some applications consist of several executables. You may need to apply this fix to each one.

image

  • Click OK to close the dialog box.
  • Run the application.

Checking for Features Rather Than Version

As mentioned previously, checking the operating system version is not the best way to confirm that a specific operating system feature is available. This is because the operating system may have had new features added in a redistributable DLL. Rather than using GetVersionEx to determine the operating system platform or version number, it is more effective to test for the presence of the feature itself. For example, we plan to make the Direct2D and DirectWrite APIs and the Ribbon API available in Windows Vista, so there is no need to block your application from using these APIs when running on Windows Vista. You just need to check if these features are available on the Operation System that you are running. If possible, your application should still run if the feature is unavailable, though with reduced functionality or performance.

You can use one of the following techniques to find out if a specific features is available on the given OS.

For Win32 developers:

  • Use LoadLibrary() to load a library which is not yet loaded into your application. If you are interested in a new function of a DLL which is already loaded (for example, kernel32.dll), then call GetModuleHandle() to obtain the module handle. If either of these functions return NULL, then this indicates an error.
  • Use GetProcAddress() to obtain a function pointer. If GetProcAddress() returns NULL, then the function may not exist. Cast the pointer to a function pointer of an appropriate prototype. Some functions, although they exist may actually be stubs that return a "not implemented" error. Be such to check for such errors.

Windows 7 introduces a new timer API - SetWaitableTimerEXProc, which adds one more input variable to the regular SetWaitableTimerProc. The TolerableDelay lets you specific a time tolerance window in which the timer can expire. This is a new in Windows 7, that we will use to demonstrate how to check for feature.

      // define function pointer type
    typedef BOOL (WINAPI *SetWaitableTimerExProc)(
      __in  HANDLE hTimer,
      __in  const LARGE_INTEGER *lpDueTime,
      __in  LONG lPeriod,
      __in  PTIMERAPCROUTINE pfnCompletionRoutine,
      __in  LPVOID lpArgToCompletionRoutine,
      __in  PREASON_CONTEXT WakeContext,
      __in  ULONG TolerableDelay
    );

    LARGE_INTEGER liDueTime;
    liDueTime.QuadPart = 0;
    nt period = 1000;
    unsigned int tolerance = 1000;
    HANDLE hTimer = // Get timer handle

    REASON_CONTEXT reasonContext = {0};
    reasonContext.Version = 0;
    reasonContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
    reasonContext.Reason.SimpleReasonString = L"MyTimer";

    // Get module handle to a module which is already loaded
    HMODULE hKernel32Module = GetModuleHandle(_T("kernel32.dll"));
    if (hKernel32Module == NULL)
        return FALSE;

    // Get Address of function
    SetWaitableTimerExProc pFnSetWaitableTimerEx =
    (SetWaitableTimerExProc) ::GetProcAddress(hKernel32Module,     
        "SetWaitableTimerEx");

    // Check if the function exists    
    if (pFnSetWaitableTimerEx == NULL)
        return FALSE;

    // Call function
    if (!pFnSetWaitableTimerEx(hTimer, &liDueTime, period, NULL, NULL,
            &reasonContext, tolerance)
    { // handle error }

Alternatively, you may use DLL delayed loading and call functions in a __try...__except block. (For more information, see Linker Support for Delay-Loaded DLLs.)

For COM APIs, handle errors returned by CoCreateInstance and QueryInterface.NET framework applications that call Win32 APIs via P/Invoke should handle EntryPointNotFoundException and DllNotFoundException exceptions.

 

If You Must Check OS Version Number

Identifying the current operating system is not the best way to determine whether a particular operating system feature is present. However, if you can’t design your application to check for specific feature availability and the only way to ensure compatibility is through version checking, then please consider the following.

For native applications, you will need to ensure your application's logic will work with newer versions of Windows. Please DO NOT BLOCK on version change! The following is a Win32 code example that uses GetVersionEx. If the major version is greater than 5 (Windows Vista, Windows® Server 2008 R2 and Windows 7), the check passes. If it equals 5, then the minor version should be 1 or greater (Windows XP or Windows Server 2003).

#include <windows.h>
#include <stdio.h>

void main()
{
    OSVERSIONINFO osvi;
    BOOL bIsWindowsXPorLater;

    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

    GetVersionEx(&osvi);

    bIsWindowsXPorLater = 
 ( (osvi.dwMajorVersion > 5) ||
       ( (osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion >= 1) ));

    if(bIsWindowsXPorLater)
  printf("The system meets the requirements.\n");
    else printf("The system does not meet the requirements.\n");
}

However there is a better way to verify the minimum OS version required using VerifiyVersionInfo(). This function compares a set of operating system version requirements to the corresponding values for the currently running version of the system. The following code example uses VerifyVersionInfo to check the operating system version against minimal requirements (Windows XP SP2):

#include <windows.h>
BOOL Is_WinXP_SP2_or_Later () 
{
   OSVERSIONINFOEX osvi;
   DWORDLONG dwlConditionMask = 0;
   int op=VER_GREATER_EQUAL;

   // Initialize the OSVERSIONINFOEX structure.

   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
   osvi.dwMajorVersion = 5;
   osvi.dwMinorVersion = 1;
   osvi.wServicePackMajor = 2;
   osvi.wServicePackMinor = 0;

   // Initialize the condition mask.

   VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION, op );
   VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION, op );
   VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR, op );
   VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMINOR, op );

   // Perform the test.

   return VerifyVersionInfo(
      &osvi, 
      VER_MAJORVERSION | VER_MINORVERSION | 
      VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR,
      dwlConditionMask);
}

In this code you can see how we use the VerifyVersion with a set of conditions to return TRUE incase we run on any OS grater than Windows XP Service Pack 2.

 

For .NET Framework developers, use the ==, !=, <=, <, >, >= operators of the Version object returned by Environment.OSVersion.Version:

// This code checks if the OS is at least Windows XP
  if (Environment.OSVersion.Version < new Version(5, 1))
  {
        MessageBox.Show("Windows XP or later required.",
         "Incompatible Operating System", MessageBoxButtons.OK,
                MessageBoxIcon.Error);
        return;
  }

It is highly recommended that you don’t check for version at all and try looking to work with features. It will prove valuable for the future…

Just incase you want to read more, here are some useful links

You can also download a HOL and code sample for this topic.

Written by Yochay Kiriaty on August 5th, 2009 with no comments.
Read more articles on Sample Code and Windows 7 Application Compatibility and otherSoftware and windows 7 and .Net and Developers and Microsoft.

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.

Written by Yochay Kiriaty on July 2nd, 2009 with no comments.
Read more articles on otherSoftware and Sample Code and windows 7 and taskbar and .Net and Developers and Microsoft.

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.

Written by Yochay Kiriaty on June 25th, 2009 with no comments.
Read more articles on otherSoftware and Sample Code and windows 7 and taskbar and .Net and Developers and Microsoft.

« Older articles

No newer articles