Windows 7 programming: Taskbar. Part 5 – CustomWindowsManager.

We continue to study possibilities of the task panel in Windows 7. For certain all of you have paid attention that if the same application to start some times, Windows 7 will automatically group them in one button on the task panel. Besides at hover on a icon of this application the task panel will show a set preview for these windows.

However, we see, that the same behaviour is realised for opened tabs in Internet Explorer 8. In this case one copy IE8 (we will lower technical details) and many tabs is actually started. In this case Internet Explorer displays them in the form of several previews. In this case it is very useful, because directly from the task panel it is possible to be switched at once on necessary tab.

Windows 7 - Internet Explorer

 

It is possible to guess, such functionality is simple for implementing and for the our application. It is actual, if in your window the set of other windows (as in a case with IE8) contains. For these purposes in .NET Interop Sample Library there is class CustomWindowsManager.  Let's more in detail consider creation of such application.

So, to begin with it is necessary for us to create the application. Let this application will work in MDI mode. Our purpose - to achieve that all child windows of this application also were displayed in the task panel. After creation of the main and child window let's be engaged in the last.

The moment of display of a window when this window is already created and ready to work is necessary for us. Very well for these purposes OnShown event approaches. In the handler we should create the CustomWindowsManager object and transfer to it Handle an child window, and also the parental window, from the point of view of model MDI.

CustomWindowsManager _windowsManager;
 
protected override void OnShown(EventArgs args)
{
    _windowsManager = 
        CustomWindowsManager.CreateWindowsManager(Handle, MdiParent.Handle);
 
    base.OnShown(args);
}

We will keep the reference to object CustomWindowsManager, it is required to us later. However, it is not enough these actions for correct work. First, we should subscribe for ThumbnailRequested event in which to generate Bitmap, containing display of our window for emerging windows in the task panel. Secondly, we should subscribe for PeekRequested event in which to generate Bitmap..

ThumbnailRequested event contains parametre of type BitmapRequestedEventArgs. This object will operate that will be displayed on the task panel. Most simple, that we can make, it to specify parametre UseWindowScreenshot equal true. In this case the screenshot of a window without your participation will be made. If it is necessary to display any own picture in preview windows, it is possible to take advantage of parametre Bitmap where to put object Bitmap which should be displayed. However, it is necessary to understand, that this object should have strictly set sizes. These sizes we also can receive from BitmapRequestedEventArgs.

_windowsManager.ThumbnailRequested += (o, e) =>
{
    Bitmap bmp = new Bitmap(e.Width, e.Height);
    this.DrawToBitmap(bmp, new Rectangle(0, 0, e.Width, e.Height));
    e.Bitmap = bmp;
};

It is clear, that here we can manipulate this object as to us conveniently. For example, we can impose on preview our picture.

_windowsManager.ThumbnailRequested += (o, e) =>
{
    Bitmap bmp = new Bitmap(e.Width, e.Height);
    this.DrawToBitmap(bmp, new Rectangle(0, 0, e.Width, e.Height));
    Graphics.FromImage(bmp).DrawImage(Images.coffeecup, 35, 5);
    e.Bitmap = bmp;
};

PeekRequested event is intended to allocate a window at mouse hover for it preview in the task panel. Here too there is a parametre of type BitmapRequestedEventArgs. Similarly it is possible to use properties UseWindowScreenshot and Bitmap.

_windowsManager.PeekRequested += (o, e) =>
{
    var result = new Bitmap(e.Width, e.Height);
    DrawToBitmap(result, new Rectangle(0, 0, e.Width, e.Height));
    e.Bitmap = result;
};

 

Pay attention, that I use method DrawToBitmap of the form in these examples. However, I can display preview any other control. For example, I can display TextBox.

Finally, it is necessary to fire WindowClosed method when the window is closed. For this purpose event OnClosed well approaches.

protected override void OnClosed(EventArgs e)
{
    if (_windowsManager != null)
    {
        _windowsManager.WindowClosed();
    }
 
    base.OnClosed(e);
}

After that we have received the following application.

We will see the following if we look at the task panel.

 

However, if we start to change appearance of the form we will see, that preview has not changed. It is caused by that Windows 7 did not request event preview. It is especially critical, if on the form there is a content which constantly changes, for example video. In this case there is a way to update preview manually. For this purpose it is necessary to start InvalidatePreviews method.

private void InvalidateButton_Click(object sender, EventArgs e)
{
    _windowsManager.InvalidatePreviews();
}

 

 

 

This method in each concrete case should be caused during the necessary moments of time. For example, at text updating in TextBox. For video a good variant - to cause it on the timer.

Here so it is easy and simple you can display the quantity of child windows of your application.

Sample application:

No Comments