Программируем панель задач Windows 7 (ч.8)

Напечатать страницу
26.06.2009 12:34 | deeper2k

Вчера я рассказал о том, каким образом можно влиять на миниатюры в панели задач Windows 7. Тогда мы отображали только ту часть окна, которая наиболее важна для пользователя. Тем не менее, в определенных ситуациях гораздо полезнее может быть отображение не части окна, а совершенно другая картинка, отображающая состояние приложения.

Например, этой возможностью пользуется Windows Live Messenger. Если мы наведем курсор мыши на значок WLM, то во всплывающем окне он отобразит аватар текущего пользователя.



Давайте разберемся с этой возможностью панели задач Windows 7. Для реализации подобного поведения в .NET Interop Sample Library существует метод SetIconicThumbnail. Именно с его помощью мы можем легко и просто создать собственную маниатюру для нашего окна. Однако, прежде, чем мы начнем его использовать, мы должны разрешить это поведение с помощью метода EnableCustomWindowPreview. В противном случае при выполнении метода SetIconicThumbnail мы получим соответствующее исключение. Сделать это можно прямо в конструкторе формы.

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


Стоит сказать, что размеры изображения, которое мы хотим отобразить в миниатюре ограничены. Это логично, так как представьте, что бы было, если бы миниатюры могли быть размером 1024x768. Эти размеры ограничены значениями 200x120. Изображение может быть меньше этого размера, в этом случае само окно миниатюры также будет уменьшено. Если изображение больше этих размеров, то будет сгенерировано исключение.

В параметрах метода SetIconicThumbnail передается ссылка на текущую форму и изображение (в формате bitmap), которое нужно отобразить. Наша задача - сгенерировать это изображение. И в этом случае у нас полностью развязаны руки - мы можем сгенерировать все, что нам угодно. Это может быть снимок окна с каким-то дополнительным текстом поверх. Это может быть какая-то собственная картинка, содержащая информацию. Это может быть текст с некой статистикой. Все зависит от вашей фантазии.

В демонстрационном приложении я буду генерировать изображение, отображающее состояние с текстом и графически, а также небольшой снимок окна. Для этого я создам bitmap-изображение нужных мне размеров и залью его фоном. После этого нарисую там изображение состояния и снимок окна. Затем я напишу на этом изображении текст состояния и результат передам в метод SetIconicThumbnail.

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);
}


Как видим, код получился достаточно лаконичный. Как результат мы можем увидеть окно со следующим preview.



Что интересно, наше приложение может само в фоне изменять это состояние. При этом, если мышь находится на значке приложения и миниатюра в данный момент отображается, то смена изображения во всплывающем окне происходит плавно, без каких-либо побочных эффектов. Так, например, я могу создать таймер, в обработчике которого можно изменять состояние через определенные промежутки времени.

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]);



В этом случае миниатюра окна нашего приложения будет изменяться динамически, а пользователь может отслеживать это состояние легко и удобно.

Загрузить демо-приложение >>>

Sergey Zwezdin, TheVista.Ru Team
Microsoft Most Valuable Professional, Microsoft Regional Director
июнь 2009

Комментарии

Комментариев нет...
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
160.23 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Мы на Facebook
Мы ВКонтакте
В сервисе IPANN.NET купить прокси для SEO и SMM
Все права принадлежат © MSInsider.ru (ex TheVista.ru), 2019
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.032 секунд (Общее время SQL: 0.01 секунд - SQL запросов: 32 - Среднее время SQL: 0.00031 секунд))