We continue to explore the capabilities of the taskbar in Windows 7. Surely all of you noticed that if you run the same application several times, Windows 7 automatically groups them into one button on the taskbar. In addition, when you hover over the icon for this application, the taskbar will show a preview set for these windows.
However, we see that the same behavior is implemented for open tabs in Internet Explorer 8. In this case, one instance of IE8 is actually running (we’ll skip the technical details) and many tabs. In this case, Internet Explorer displays them in the form of several previews. In this case, it is very useful, because right from the taskbar, you can immediately switch to the desired tab.
')
As you might guess, this functionality is easy to implement for your application. This is true if your window contains a set of other windows (as is the case with IE8). For these purposes, the .NET Interop Sample Library contains the class CustomWindowsManager. Let's take a closer look at the creation of such an application.
So, first we need to create an application. Let this application work in MDI mode. Our goal is to ensure that all child windows of this application are also displayed in the taskbar. After creating the main and child windows, let's do it last.
We need a window display moment when this window has already been created and is ready to go. The OnShown event is very well suited for this purpose. In the handler, we need to create an instance of the CustomWindowsManager object and pass it the Handle of the child window, as well as the parent window, from the point of view of the MDI model.
CustomWindowsManager _windowsManager;
protected override void OnShown(EventArgs args)
{
_windowsManager =
CustomWindowsManager.CreateWindowsManager(Handle, MdiParent.Handle);
base.OnShown(args);
}
We will save the reference to the CustomWindowsManager object, we will need it later. However, these actions are not enough for correct operation. First, we have to subscribe to the ThumbnailRequested event, in which we generate a Bitmap containing the display of our window for pop-up windows in the taskbar. Secondly, we have to subscribe to the PeekRequested event, in which we generate a Bitmap containing the display of our window to select it at the time of mouse-over on the preview window in the taskbar.
The ThumbnailRequested event contains a parameter of type BitmapRequestedEventArgs. This object will control what will be displayed on the taskbar. The simplest thing we can do is set the UseWindowScreenshot parameter to true. In this case, a screenshot of the window will be made without your participation. If you want to display some kind of your own image in the preview window, you can use the Bitmap parameter, where to put your Bitmap object, which should be displayed. However, you need to understand that this object must have strictly defined dimensions. We can also get these sizes 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 it is convenient for us. For example, we can impose our picture on preview.
_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;
};
The PeekRequested event is intended to highlight a window when you hover the mouse over its preview in the taskbar. There is also a parameter of type BitmapRequestedEventArgs. Similarly, you can use the UseWindowScreenshot and Bitmap properties.
_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;
};
Note that in these examples I use the form's DrawToBitmap method. However, I can display a preview of any other control. For example, I can display a textbox.
Well, finally, you must call the WindowClosed method when the window is closed. The OnClosed event is well suited for this.
protected override void OnClosed(EventArgs e)
{
if (_windowsManager != null)
{
_windowsManager.WindowClosed();
}
base.OnClosed(e);
}
After that we got the following application.
If we look at the taskbar, we will see the following.
However, if we start to change the appearance of the form, we will see that the preview has not changed. This is because Windows 7 did not request a preview event. This is especially critical if the form contains content that is constantly changing, such as video. In this case, there is a way to update the preview forcibly. To do this, call the InvalidatePreviews method.
private void InvalidateButton_Click(object sender, EventArgs e)
{
_windowsManager.InvalidatePreviews();
}
This method in each case should be called at the right time. For example, when updating text in TextBox. For videos, a good option is to call it on a timer.
This is how you can easily and simply display the number of child windows of your application.
Demo application:
Taskbar-WindowsManager.zip