Программируем Windows 7: Taskbar. Часть 9 – PeekBitmap

    Ранее я писал о возможности панели задач Windows 7 изменять preview для окна. Мы говорили о том, что в preview можно отображать как часть окна, так и собственное изображение. У Windows 7 есть такая приятная особенность, что если мы наведем курсор мыши на preview окна, то все остальные окна скроются, а выделенное окно будет отображаться. Выглядит это следующим образом.



    Панель задач Windows 7 в этом случае также позволяет нам задать собственное поведение. В этом случае мы имеем возможность задать содержимое нашей формы нашим собственным изображением. Например, там мы можем написать какой-то полезный текст. В этом случае сценарий работы может выглядеть следующим образом. У пользователя в панели задач находится приложение, которое что-то выполняет. Он может отслеживать его состояние на основе ProgressBar и OverlayIcon, о которых я писал ранее. Если этой информации ему недостаточно, он может навести курсор мыши на иконку приложение. В этом случае ему отобразится preview, в котором содержится дополнительная информация (о чем я тоже писал). Пользователь может навести на preview нужного окна и в этом случае все окна скроются и на экране останется только выделенное окно. В этом окне мы можем вывести еще больше информации, которая необходима пользователю.

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

    Для того, чтобы реализовать подобный сценарий в нашем приложении мы воспользуемся .NET Interop Sample Library. Для этих целей предназначен метод SetPeekBitmap класса-обертки. Генерировать изображение необходимо в момент времени, когда пользователь наводит на preview окна. Для этих целей переопределим метод WndProc и отловим событие WM_DWMSENDICONICLIVEPREVIEWBITMAP. Как раз в этот момент времени необходимо генерировать изображение.

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


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

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


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



    На самом деле, после это изображение можно устанавливать откуда угодно. Главное, чтобы это изображение также генерировалось в момент обработки указанного выше события. Например, в демонстрационном приложении я также устанавливаю это изображение в таймере. Таким образом я могу навести курсор мыши на preview и наблюдать за тем как изменяется сама форма при срабатывании таймера.

    Кроме того, у метода SetPeekBitmap существует третий параметр логического типа (boolean). Изменяя этот параметр можно указать нужно ли убирать рамку приложения, когда осуществляется подобный просмотр. Например, если я установлю этот параметр в false, то увижу следующий результат.



    Демонстрационное приложение:
    Taskbar-PeekBitmap.zip
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама

    Комментарии 21

      +5
      каюсь, никогда не разрабатывал десктопные приложения, но читаю все ваши статьи — очень интересно даже для такого неподготовленного читателя, как я. спасибо :)
      • НЛО прилетело и опубликовало эту надпись здесь
        –11
        У меня одного в последние пару недель возникает стойкой ощущение, что меня с хабра редиректит на msdn?

        s/habrahabr.ru/windows7community.ru/
        • НЛО прилетело и опубликовало эту надпись здесь
            –4
            К счастью, не завидую. Пока адекватен. А в линуксе подобное есть.
            0
            Меня тоже в Линукс-фэн-статьях минусуют, когда я возникать пытаюсь, что Линукс — система для профессиональных системных администраторов, и только.
            0
            извините за оффтоп: а зеленый прямоугольник в углу это уровень заряда батареи? как-то широковат для трей-иконки, можно ссылку на утилиту?
              +1
              это системная утилита от Lenovo
              +1
              А кто-нибудь знает, в Java библиотека для использования данных финтифлюшек появится?
                0
                Сразу извините за возможно идиотский вопрос, но правда интересно:
                Возможно ли применить ваши статьи на Delphi?
                  –1
                  Вопрос действительно идиотский. Да, возможно.
                    +1
                    Спасибо!
                    Тогда еще один вопрос — а что будет происходить с программой на Windows < Windows 7?
                      +2
                      Кривизна работы программы прямо пропорциональна кривизне рук программиста. Одним словом использовать не статическую линковку а динамическую. Проверять версию операционки и не дергать лишнего.
                        0
                        придется.
                        А все-таки ответ на мой вопрос? :)
                    0
                    в одном из предыдущих постингов была как раз ссылка на готовые компоненты для этих целей.
                    www.gumpi.com/Blog/2009/01/20/Alpha1OfWindows7ControlsForDelphi.aspx

                    хотя на самом деле можно и без них обойтись и использовать COM
                      0
                      Ой, супер! Спасибо!
                    0
                    Я жду " Программируем Windows 7: Taskbar. Часть 349" =)
                      0
                      Части 349 не будет. Я уже говорил, что всего 10 частей.
                        0
                        эх жаль
                          –2
                          не обижай фанатов. ждем новых серий!
                        +1
                        хорошие статьи. главное, что на русском)

                        Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                        Самое читаемое