Recently, I talked about how you can influence the preview windows in the Windows 7 taskbar. Then we displayed only that part of the window that is most important to the user. Nevertheless, in certain situations it may be much more useful to display not part of the window, but a completely different picture showing the state of the application.
For example, Windows Live Messanger takes advantage of this opportunity. If we hover the mouse over the WLM icon, it will display the current user's avatar in a pop-up window.
')
Let's look at this feature of the Windows 7 taskbar. To implement this behavior, the SetIconicThumbnail method exists in the .NET Interop Sample Library. It is with its help that we can easily and simply create our own preview for our window. However, before we start using it, we must enable this behavior using the EnableCustomWindowPreview method. Otherwise, when executing the SetIconicThumbnail method, we will get a corresponding exception. This can be done directly in the form designer.
public Form1()
{
InitializeComponent();
WindowsFormsExtensions.EnableCustomWindowPreview(this);
}
It should be said that the size of the image that we want to display in the preview is limited. This is logical, because imagine what it would be like if the preview could be 1024x768 in size. These dimensions are limited to 200x120. The image may be smaller than this size, in which case the preview window itself will also be reduced. If the image is larger than this size, an exception will be generated.
In the parameters of the SetIconicThumbnail method, a link is sent to the current form and the image (Bitmap) to be displayed. Our task is to generate this bitmap. And in this case, our hands are completely untied - we can generate anything we want. This may be a snapshot of the window, with some additional text on top. This may be some kind of own picture containing information. This may be a text with some statistics. It all depends on your imagination.
In the demo application, I will generate an image that displays the status of the application with text and graphically, as well as a small snapshot of the window. For this, I will create a Bitmap of the sizes I need and fill it with a background. After that I will draw there a state image and a snapshot of the window. Then I will write the state text on this image and transfer the result to the SetIconicThumbnail method.
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);
}
As you can see, the code is rather concise. As a result, we can see a window with the following preview.
Interestingly, our application can change this state in the background itself. At the same time, if the mouse is on the application icon and the preview is currently displayed, then the image change in the pop-up window occurs smoothly, without any side effects. So, for example, I can create a timer in the handler of which I can change the state at regular intervals.
private readonly string[] _stateTexts = new[] { "Deleting..", "Wireless", "Security", "Stop", "Help", "O'kay", "Playing", "Login", "Warning", "Showcase", "Search", "Processing..", "Locked", "Error", "Refreshing.." };
private readonly Bitmap[] _stateImages = new[] { Images._104, Images._110, Images._111, Images._112, Images._113, Images._114, Images._120, Images._125, Images._129, Images._134, Images._17, Images._25, Images._41, Images._50, Images._52 };
private int _currentIndex = 0;
private void timer1_Tick(object sender, EventArgs e)
{
if (_currentIndex + 1 >= _stateImages.Length)
{
_currentIndex = 0;
}
else
{
_currentIndex++;
}
SetState(this, _stateTexts[_currentIndex], _stateImages[_currentIndex]);
}
In this case, the preview window of our application will change dynamically, and the user can monitor this state easily and conveniently.
Demo application:
Taskbar-IconicThumbnail.zip