Developing with the Taskbar in Windows 7
 
Published: 02 Nov 2009
Abstract
In this article, Sergey Zwezdin examines the capabilities of Windows 7 for developers. In particular, he provides a detailed step-by-step overview of developing with the Windows 7 Taskbar by demonstrating how to implement a progress bar, thumb buttons, and window preview.
by Sergey Zwezdin
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 34200/ 65

Introduction

Windows 7 contains a large number of innovations and improvements. These improvements touch on safety, productivity, reliability, etc. A lot of attention is also given to user interface. This operational system is interesting for developers of applications based on Windows platform. One of the basic innovations is an updated task panel. In the new task panel there are really many conceptual changes. Reading this article you will know about innovations of the new task panel, and their program model.

.NET Interop Sample Library

In the context of client Windows applications developer, process of given functionality usage in your own applications is simple enough. Interaction with operation system occurs at unmanaged level through COM-objects. This is the reason to realize managed wraps for .NET applications. All this work has already done and taken place in .NET Interop Sample Library.

The .NET Interop Sample Library consists of a set of components and demonstration applications. We will not give detail information about everyone of them. It is important for us that there are «Vista Bridge Sample Library» project and «Windows7.DesktopIntegration».

There is WindowsFormsExtensions class as a part of the project «Windows7.DesktopIntegration». This class implements a set of extension methods for a form of Windows Forms platform. Unfortunately, at the moment of this article writing in that class there was not WPF applications support. However, this shortage is very simply to be corrected on your own. All that is required in this case is to change the way of getting a handle of window.

We will use this library to construct of all demonstration applications in the article.

Progress bar

One of the most appreciable changes in the task panel of Windows 7 is the possibility to display progress of a task execution (progress bar) in the task panel directly.

Figure 1: Progress bar at task panel in Windows 7

In this figure it is seen very well, that on the task panel the information about copying process is displayed. Such functionality is realized in Windows 7 for files copying, data from a network downloading (Internet Explorer) and in other applications. This functionality can be used and for your own applications. A lot of scenarios can be - displaying of data transformation process, copying, formations of data, construction of reports, generation of images, etc.

WindowsFormsExtensions сlass contains two methods which should take place in this case:    SetTaskbarProgress and SetTaskbarProgressState. The call of the first method allows us to specify the percent of a current task execution.

Listing 1: Setting values for progress bar of task panel of Windows 7

WindowsFormsExtensions.SetTaskbarProgress(this, 35); 

SetTaskbarProgressState method which allows us to set a current state of a progress-bar.

Listing 2: Setting state for progress bar

WindowsFormsExtensions.SetTaskbarProgressState(this, 
  Windows7Taskbar.ThumbnailProgressState.Normal);

There are four available modes: Normal, Indeterminate, Error (displayed by a red color) and Paused (displayed by a yellow color).

Figure 2: States of progress bar

Thumbnail buttons

Another interesting possibility of a new task panel in Windows 7 is the opportunity to add your own buttons to manage application in a preview window. Similar functionality can be noticed when you use Windows 7. For example, analogues buttons are in Windows Media Player. They allow us to switch tracks and stop playing. You can create more then seven such buttons.

Without a doubt, such functionality can be useful not only in Media Player, but also in our applications. Let us look at how we can implement it in our applications. Creation of our buttons should occur at the moment of WM_TaskbarButtonCreated message processing. That is why we should redefine the method WndProc on a form and process moments of this event occurrencef.

Listing 3: Overriding WndProc method

protected override void WndProc(ref Message m)
{
    if (m.Msg == Windows7Taskbar.TaskbarButtonCreatedMessage)
    {
        // initialize buttons
    } 
 
    base.WndProc(ref m);
}

ThumbButtonManager object is needed to initialize buttons. This object manages the behavior and the displaying of these buttons. This object can be created using an extension method CreateThumbButtonManager. After that, it is necessary to take advantage of CreateThumbButton method and create an object of a button. After all buttons will be created, it is necessary to add them on the task panel thanks to AddThumbButtons method.

Listing 4: Creation of the buttons

protected override void WndProc(ref Message m)
{
    if (m.Msg == Windows7Taskbar.TaskbarButtonCreatedMessage)
    {
        InitializeThumbButtons();
    }
 
    base.WndProc(ref m);
}
 
protected void InitializeThumbButtons()
{
    ThumbButtonManager thumbButtonManager = 
        WindowsFormsExtensions.CreateThumbButtonManager(this);
 
    var decreaseThumbButton = thumbButtonManager.CreateThumbButton(1, 
                        Icons.Navigation_First_2, "To reduce the progress");
    decreaseThumbButton.Clicked += delegate
                           {
                            // ..
                           };
 
    thumbButtonManager.AddThumbButtons(decreaseThumbButton);
}

Now, when you start the application you can see that there was one button control. But if we try to press it, we will see that the handler of event will not work. To let it work it is necessary to pass directly to the opportunity of process events to ThumbButtonManager object in WndProc method. As a result, we receive the following simple code.

Listing 5: Handling the pressing of buttons

private ThumbButtonManager _thumbButtonManager; 
protected override void WndProc(ref Message m)
{
    if (m.Msg == Windows7Taskbar.TaskbarButtonCreatedMessage)
    {
        InitializeThumbButtons();
    }
    
    if (_thumbButtonManager != null)
        _thumbButtonManager.DispatchMessage(ref m);
 
 
    base.WndProc(ref m);
}
 
protected void InitializeThumbButtons()
{
    if (_thumbButtonManager == null)
    {
        _thumbButtonManager = WindowsFormsExtensions.
            CreateThumbButtonManager(this);
    }
    
    var decreaseThumbButton = _thumbButtonManager.CreateThumbButton(1, 
        Icons.Navigation_First_2, "To reduce the progress");
    decreaseThumbButton.Clicked += delegate
                       {
                        Progress.Text = 
                            (float.Parse(Progress.Text) - 10).ToString();
                        WindowsFormsExtensions.SetTaskbarProgress(this, 
                            float.Parse(Progress.Text));
                       };
 
    // other buttons
 
    _thumbButtonManager.AddThumbButtons(decreaseThumbButton, 
        normalStateThumbButton, indeterminateStateThumbButton, 
        pauseStateThumbButton, errorStateThumbButton, increaseThumbButton);
}

This application contains 6 buttons to control progress.

Figure 3: Thumbnail buttons

Overlay icons

This possibility is useful if applications have any state from a user point of view. As example of such, applications can be programs for instant messages. For instance, Windows Live Messenger uses this possibility. If you open Windows Live Messenger and change a state, you can see how it is displayed on the task panel.

Figure 4: Overlay icons of Windows Live Messenger

To add a state icon to the main icon of the application, it is necessary to add a resource file in the project and to place there the necessary icons. Also, it is possible to receive Icon objects from another place if it is necessary.

Now you need to use methods of expansion that allows us to set icons for our application. For these purposes SetTaskbarOverlayIcon method is defined. As parameters of this method we should pass our form, an icon and description. Thus, code of a new icon setting up is like the following.

Listing 6: Setting up overlay icon

WindowsFormsExtensions.SetTaskbarOverlayIcon(this, Icons.Error, "Error");

Also, it is possible to remove this icon. For this purpose it is necessary to pass null value instead of the icon.

Listing 7: Clearing overlay icon

WindowsFormsExtensions.SetTaskbarOverlayIcon(thisnull, String.Empty);

You can also imagine another scenario where, instead of an additional icon, any information can be displayed. For example, it can be the current download speed if your software downloads something from a network. Or it can be quantity of new letters in a mail box if it is a mail client.

As the second parameter in SetTaskbarOverlayIcon method object Icon is passed, it is possible to generate this object dynamically. Let us take advantage of a simple code and do it. We will create a method which will generate such an image.

Listing 8: Generating icon dynamically

private static Icon BuildIcon(int param)
{
    Bitmap image = Icons.BLANK2334242;
    Graphics.FromImage(image).DrawString(param.ToString(@"D2"), 
        new Font("Arial", 54), Brushes.White, 10, 25);
    return Icon.FromHandle(image.GetHicon());
}
 
private void ShowStatus(object sender, EventArgs e)
{
    WindowsFormsExtensions.SetTaskbarOverlayIcon(this, BuildIcon(50, "Status");
}

Thus, thanks to BuildIcon method, a new icon which will be generated and displayed on the task panel.

In this example you can see that a text was added to a standard icon and the result was displayed on the task panel. In this demonstration application there is a timer which simulates the work of a download manager, giving out different "speeds" of downloading constantly.

Thumbnail preview

Windows 7 has a convenient functionality to display preview for applications. The mouse hovering over the task panel makes it possible to look a window reduced representation at a window icon for few seconds. It is very convenient when a user has a lot of open windows. By default, in these miniwindows all contents of a window are displayed. However, for some application it would be much more convenient not to show all contents of a window, but only its part. Such functionality is also provided for the task panel of Windows 7 and it is possible to use it for the applications.

Within wrappers for functions from system libraries of Windows there is SetThumbnailClip method which helps us with the implementation of the given functionality. Calling this method, you need to point a current copy of a form and coordinates that limit area of a window.

Listing 9: Setting thumbnail area

private void Clip5_Click(object sender, EventArgs e)
{
  WindowsFormsExtensions.SetThumbnailClip(this, new Rectangle(10, 10, 145, 145));
}

Let us create a small application where we could see possibilities of this functionality. For this purpose we will create an empty application and add some controls there. After the application start its work in a window of preliminary viewing will look as follows.

Figure 5: Preview window

You can see that the whole window is initially displayed. Let us limit the area of display thanks to usage of SetThumbnailClip method. For example, we want to display only TextBoxs which are on the form.

Figure 6: Preview window with selected area

What is interesting, if we have dynamic contents (for example, video) on a form, then it will be displayed in dynamics. In the demonstrated application there are some animated images and they are displayed within the area of preview. Thus, there is no need to do anything else. We can change content of a preview window during the work of application and this is important to mention. For example, at one moment of time we need to display content of any important TextBoxs while at another moment to display an image from a form. Such dynamics give the user an opportunity to get actual information. At last, if you need to see the whole form, you can display all its contents thanks to usage of the same method, but it is necessary to pass the form’s sizes. In this case, in a preview window, the whole window will be displayed again.

Listing 10: Showing all window area

private void NoClip_Click(object sender, EventArgs e)
{
    WindowsFormsExtensions.SetThumbnailClip(this, 
        new Rectangle(new Point(0, 0), Size));
}

However, in certain situations it can be more useful to display not a window part, but an completely different picture. For example, Windows Live Messenger uses this possibility. If we hover over the icon for Windows Live Messenger then the pop-up window will display a current user's avatar.

Figure 7: Custom image in preview area

To implement similar behavior in .NET Interop Sample Library there is the SetIconicThumbnail method. With its help we can create our own kind of a preview area for our window easily and simply. But before we start its usage, it is necessary to enable this behavior. Thanks to EnableCustomWindowPreview Otherwise executing method SetIconicThumbnail we get the following exception. It can be done directly in a form constructor.

Listing 11: Enabling custom window preview

public Form1()
{
    InitializeComponent();
    WindowsFormsExtensions.EnableCustomWindowPreview(this);
}

It is necessary to say that sizes of the image which are displayed in a preview area are limited. These sizes are limited by values 200x120. The image can be less than this size; in this case the area of preview will be reduced too. If an image is more than these sizes the exception will be generated.

In parameters of SetIconicThumbnail method there is a reference to the current form and image (Bitmap) which should be displayed. Our goal is to generate this Bitmap. And in this case we can do whatever we want. We can generate everything what we need. It can be a screenshot of a window with any additional text atop or be any own picture containing information or text with some statistics.

In the demonstration application we will generate an image which will display a state of the application by text and graphic, and also by a small picture of a window. For this purpose let us create an image (Bitmap) with necessary sizes and fill in its background. After that we will draw an image of a state and a window picture there. Then we will write a state text on the image and the result should be passed in SetIconicThumbnail method.

Listing 12: Generating custom image

private static void SetState(Form form, string stateText, Image stateImage)
{
    // blank image
    var preview = new Bitmap(200, 120);
    var g = Graphics.FromImage(preview);
 
    // fill background
    g.DrawImage(Images.background, 0, 0);
 
    // file image of state
    if (stateImage != null)
    {
        g.DrawImage(stateImage.GetThumbnailImage(100, 100, null, IntPtr.Zero), 
            100, 10);
    }
 
    // fill image of form
    g.DrawImage(GetFormImage(form, 50, 60), 10, 10);
 
    // draw text
    g.DrawString(stateText, new Font("Verdana", 18), Brushes.White, 10, 70);
 
    // setting thumbnail
    WindowsFormsExtensions.SetIconicThumbnail(form, preview);
}
 

Apparently, the code has turned out laconic enough. As a result we will see the following representation.

Figure 8: Result of generation custom window preview

What is interesting is that our application can change its state in a background. If a mouse is over an icon of the application and a preview window is displayed at this moment, an image changing then occurs smoothly in a pop-up window without any by-effects. So, for example, it is possible to create a timer where in its handler states will be changed in certain time intervals.

It is necessary to notice also, that if we hover a mouse cursor over a preview area of a window all other windows will disappear and the allocated window will be displayed. It looks as follows.

Figure 9: Peek window

In this case the task panel of Windows 7 also allows us to set up our own behavior. So we have the possibility to assign contents of form by our own image. For example, we can write any useful text. In this case, the work scenario can look as follows. A user in the task panel has an application which is executing something. It can trace its state on the basis of ProgressBar and OverlayIcon. If this information is not enough, you can hover a mouse cursor on an icon of the application. As a result, you see a preview area with additional information. A user can hover over a preview area of the necessary window and, in this case, all windows will disappear and on the screen there will be only an allocated window. In this window we can display even more information which is necessary for a user.

To implement a similar scenario in our application we will take advantage of .NET Interop Sample Library. SetPeekBitmap method of a class-wrapper is intended for these purposes. When the user hovers a mouse over a preview area of a window it is necessary to generate an image. For these purposes we will redefine WndProc method and get the following:

WM_DWMSENDICONICLIVEPREVIEWBITMAP message. Just during this moment of time it is necessary to generate the image.

Listing 13: Catching WM_DWMSENDICONICLIVEPREVIEWBITMAP message

protected override void WndProc(ref Message m)
{
    if (m.Msg == WM_DWMSENDICONICLIVEPREVIEWBITMAP)
    {
        WindowsFormsExtensions.SetPeekBitmap(this, 
            GeneratePeekBitmap(this, Images._111), true);
    }
 
    base.WndProc(ref m);
}

In this case, we call a method which will generate the necessary image. Generation of this image does not represent any complexity. Generally we can copy a picture of our window in this Bitmap and draw necessary information over it. Let us fill in this area with a background and draw an icon of a state over it in the demonstrational application.

Listing 14: Generating peek image

private static Bitmap GeneratePeekBitmap(Form form, Image stateImage)
{
    var preview = new Bitmap(form.ClientSize.Width, form.ClientSize.Height);
 
    var g = Graphics.FromImage(preview);
 
    g.DrawImage(Images.background.GetThumbnailImage(
        form.ClientSize.Width, form.ClientSize.Height, null, IntPtr.Zero), 0, 0);
    
    if (stateImage != null)
    {
        Size thumbSize = new Size(100, 100);
        g.DrawImage(
            stateImage.GetThumbnailImage(thumbSize.Width, 
              thumbSize.Height, null, IntPtr.Zero), 
            form.ClientSize.Width / 2 - thumbSize.Width / 2, 
            form.ClientSize.Height / 2 - thumbSize.Height / 2);
    }
 
    return preview;
}

Pay attention to display such representation correctly since the sizes of an image should coincide with the sizes of a form. After that we get an application which looks as follows.

Figure 10: Custom peek window preview

Actually, such image can be installed from any place of application. The main thing is that this image should be generated at the moment of the processing event specified above. For example, in the demonstration application we also set this image in the timer. Thus, we can hover a mouse cursor over a preview area and observe how the form changes at the timer operation.

Besides, SetPeekBitmap method has a third parameter of boolean type. Changing this parameter, it is possible to specify whether it is necessary to clean an application border when similar viewing is carried out. 

Conclusion

In this article, the main possibilities of the task panel of Windows 7 programming have been considered. Without a doubt, realization of these possibilities in your applications will demand certain efforts. However, these efforts can be hardly compared with the convenience of work with your application and number of unnecessary actions at work with your application that can be avoided.



User Comments

Title: Source Code & Windows 7 Lib   
Name: Willy
Date: 2011-01-13 9:07:34 PM
Comment:
hi sergey, your article is amazing
please send me the source code, I need to improved my application, email me at skylancer3id@yahoo.com

I wonder where is download the windows 7 library for C# visual studio .net 2008, my application running on it.

many thanks.
Willy
Title: Re: Attach Full Source Code   
Name: Sergey Zwezdin
Date: 2010-03-08 12:54:15 AM
Comment:
Ashish, send me mail-request, please?
sergey@zwezdin.com
Title: Attach Full Source Code   
Name: Ashish Kumar
Date: 2010-03-07 3:26:16 AM
Comment:
hi...
please attach full source code with this article.
please.........
Title: reviews   
Name: r4 dsi
Date: 2009-11-30 5:43:34 AM
Comment:
Windows 7 is more than what Vista should have been, it's where Microsoft needed to go. How much damage Vista did and whether Windows 7 is enough for people to finally abandon Windows XP are questions that nobody has the answers to right now.
Title: Amazing !   
Name: Aamod Thakur
Date: 2009-11-06 4:15:19 AM
Comment:
Amazing Article, Very Informative.

Thanks Sergey

Product Spotlight
Product Spotlight 





Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2021 ASPAlliance.com  |  Page Processed at 2021-01-24 11:06:54 PM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search