Мигающее окно в панели задач с помощью функции FlashWindowEx

Иконка Панель задач

Ранее я писал про то как в  свернуть  приложение WinForms в трей панели задач. Сегодня же я расскажу про то, как неактивное приложение находящееся на самой панели задач может обратить к себе внимание пользователя путем так называющегося мигающего (flash) окна. Использовать для этого мы будем Windows API функцию   FlashWindowEx, которая находиться в библиотеке User32.

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

Обычно окно должно мигать до тех пор пока пользователь не вернет ему фокус. Но можно также указать сколько раз окно должно мигнуть, или же остановить мигание когда посчитаете нужным.

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

Использование функции FlashWindowEx не интегрировано в .NET Framework, и что бы вызывать ее нам придется использовать PInvoke.

Ниже представлен статический класс FlashWindow, который я взял здесь. Он позволяет легко использовать функционал метода FlashWindowEx.

public static class FlashWindow
{
    [DllImport("user32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool FlashWindowEx(ref FLASHWINFO pwfi);

    [StructLayout(LayoutKind.Sequential)]
    private struct FLASHWINFO
    {
        /// <summary>
        /// The size of the structure in bytes.
        /// </summary>
        public uint cbSize;
        /// <summary>
        /// A Handle to the Window to be Flashed. The window can be either opened or minimized.
        /// </summary>
        public IntPtr hwnd;
        /// <summary>
        /// The Flash Status.
        /// </summary>
        public uint dwFlags;
        /// <summary>
        /// The number of times to Flash the window.
        /// </summary>
        public uint uCount;
        /// <summary>
        /// The rate at which the Window is to be flashed, in milliseconds. If Zero, the function uses the default cursor blink rate.
        /// </summary>
        public uint dwTimeout;
    }

    /// <summary>
    /// Stop flashing. The system restores the window to its original stae.
    /// </summary>
    public const uint FLASHW_STOP = 0;

    /// <summary>
    /// Flash the window caption.
    /// </summary>
    public const uint FLASHW_CAPTION = 1;

    /// <summary>
    /// Flash the taskbar button.
    /// </summary>
    public const uint FLASHW_TRAY = 2;

    /// <summary>
    /// Flash both the window caption and taskbar button.
    /// This is equivalent to setting the FLASHW_CAPTION | FLASHW_TRAY flags.
    /// </summary>
    public const uint FLASHW_ALL = 3;

    /// <summary>
    /// Flash continuously, until the FLASHW_STOP flag is set.
    /// </summary>
    public const uint FLASHW_TIMER = 4;

    /// <summary>
    /// Flash continuously until the window comes to the foreground.
    /// </summary>
    public const uint FLASHW_TIMERNOFG = 12;

    /// <summary>
    /// Flash the spacified Window (Form) until it recieves focus.
    /// </summary>
    /// <param name="form">The Form (Window) to Flash.</param>
    /// <returns></returns>
    public static bool Flash(System.Windows.Forms.Form form)
    {
        // Make sure we're running under Windows 2000 or later
        if (Win2000OrLater)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL | FLASHW_TIMERNOFG, uint.MaxValue, 0);
            return FlashWindowEx(ref fi);
        }
        return false;
    }

    private static FLASHWINFO Create_FLASHWINFO(IntPtr handle, uint flags, uint count, uint timeout)
    {
        FLASHWINFO fi = new FLASHWINFO();
        fi.cbSize = Convert.ToUInt32(Marshal.SizeOf(fi));
        fi.hwnd = handle;
        fi.dwFlags = flags;
        fi.uCount = count;
        fi.dwTimeout = timeout;
        return fi;
    }

    /// <summary>
    /// Flash the specified Window (form) for the specified number of times
    /// </summary>
    /// <param name="form">The Form (Window) to Flash.</param>
    /// <param name="count">The number of times to Flash.</param>
    /// <returns></returns>
    public static bool Flash(System.Windows.Forms.Form form, uint count)
    {
        if (Win2000OrLater)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL, count, 0);
            return FlashWindowEx(ref fi);
        }
        return false;
    }

    /// <summary>
    /// Start Flashing the specified Window (form)
    /// </summary>
    /// <param name="form">The Form (Window) to Flash.</param>
    /// <returns></returns>
    public static bool Start(System.Windows.Forms.Form form)
    {
        if (Win2000OrLater)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_ALL, uint.MaxValue, 0);
            return FlashWindowEx(ref fi);
        }
        return false;
    }

    /// <summary>
    /// Stop Flashing the specified Window (form)
    /// </summary>
    /// <param name="form"></param>
    /// <returns></returns>
    public static bool Stop(System.Windows.Forms.Form form)
    {
        if (Win2000OrLater)
        {
            FLASHWINFO fi = Create_FLASHWINFO(form.Handle, FLASHW_STOP, uint.MaxValue, 0);
            return FlashWindowEx(ref fi);
        }
        return false;
    }

    /// <summary>
    /// A boolean value indicating whether the application is running on Windows 2000 or later.
    /// </summary>
    private static bool Win2000OrLater
    {
        get { return System.Environment.OSVersion.Version.Major >= 5; }
    }
}

Про функцию FlashWindowEx важно знать то, что она будет работать только на Windows 2000 или выше.

Класс FlashWindow предоставляет три публичных метода, пример использования которых показан ниже:

// Заставить окно мигать до тех пор пока ему не вернут фокус
FlashWindow.Flash(this);

// Заставить окно мигнуть  3 раза
FlashWindow.Flash(this, 3);

// Начать мигание
FlashWindow.Start(this);

// Остановить мигание
FlashWindow.Stop(this);

Стоит отметить, что в коде приведенном выше переменная this соответствует текущей форме класса System.Windows.Forms.Form.

В результате в панели задач получаем мигающую оранжевым цветом иконку программы:

Пример мигающей иконки в панели задач Windows  Мигающее окно в панели задач с помощью функции FlashWindowEx

2 комментариев

  1. Дмитрий:

    А вот если форма, которую мы хотим мигать, является дочерней у другой формы. То мигание останавливается даже если фокус получило родительское окно. И соответственно, если мы свернем дочернюю форму не сворачивая родительскую, то эффект мигания не сработает вообще. Как бы это победить?

  2. Большой выбор бизнес-идеи 2018 года для малого и среднего бизнеса с минимальными вложениями. Бизнес-идеи представляют собой концепции, которые помогают начать собственное дело. Главное, это правильно выбрать бизнес-идеи на сайте.

Добавить комментарий для Бизнес-идеи 2018 Отменить ответ

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>