Работа с треем. Создание иконки из ASCII символов на C#

Здесь я хочу рассказать об одной интересной возможности. А именно, о том, как создать «на лету» и добавить в трей иконку из ASCII символов, т.е. добавить туда произвольный текст, средствами C# и .net. Честно говоря, я не очень хорошо представляю себе, где это может понадобиться на практике, но вдруг кому пригодится.

Для того, чтобы все получилось, нужно не забыть использовать пространства имен

using System.Drawing;
using System.Drawing.Imaging;

Хотя, если что, то Visual Studio скорее всего сама про них вам напомнит.

Кратко о том, как будем создавать иконку:

  1. создаем bmp;
  2. задаем шрифт и его размеры;
  3. объект для рисования на bmp;
  4. создаем кисти нужного цвета;
  5. создаем прямоугольник нужных размеров (естественно, не больше bmp);
  6. рисуем нужный символ (а точнее даже «строчки»);
  7. создаем объект GDI+ из нашей bmp с символом ASCII;
  8. и подставляем его в качестве иконки

В принципе, это все, что нужно. Остальное – это уже нюансы реализации и полет фантазии каждого.

В этом проекте используются:

  • Bitmap – «Инкапсулирует точечный рисунок GDI+, состоящий из данных пикселей графического изображения и атрибутов рисунка. Объект Bitmap используется для работы с изображениями, определяемыми данными пикселей»;
  • Font – «Определяет конкретный формат текста, включая начертание шрифта, его размер и атрибуты стиля. Этот класс не может быть унаследован»;
  • Graphics – «Инкапсулирует поверхность рисования GDI+»;
  • SolidBrush – «Определяет кисть одного цвета. Кисти используются для заливки графических фигур, таких как прямоугольники, эллипсы, круги, многоугольники и контуры. Этот класс не может быть унаследован»;
  • RectangleF – «Содержит набор из четырех чисел с плавающей запятой, определяющих расположение и размер прямоугольника».

Подробнее о них можно посмотреть в MSDN.

Перейдем к коду. В нем относительный интерес представляют следующие участки кода:

public FormForTray()
{
    InitializeComponent();
    //задаем всплывающий текст-подсказку (появляется при наведении указателя на иконку в трее)
    _notifyIcon.Text = "[lexpenz.com]";
    //устанавливаем значок, отображаемый в трее:
    _notifyIcon.Icon = _myIcon;
    //подписываемся на событие клика мышкой по значку в трее
    _notifyIcon.MouseClick += new MouseEventHandler(_notifyIcon_MouseClick);
    //подписываемся на событие изменения размера формы
    this.Resize += new EventHandler(FormForTray_Resize);

    //подписываемся на событие тика таймера
    _timer.Tick += new EventHandler(_timer_Tick);

    //добавляем контекстное меню к значку
    _notifyIcon.ContextMenuStrip = _contextMenuStrip;
    //подписываемся на событие клика по пункту меню "Выход"
    _exitToolStripMenuItem.Click += new EventHandler(_exitToolStripMenuItem_Click);

    //создаем битмапку 16х16
    Bitmap bmp = new Bitmap(16, 16);
    //задаем шрифт и его размеры
    Font font = new Font(FontFamily.GenericSansSerif, 10F);
    //создаем объект класса для рисования "из картинки"
    Graphics graphics = Graphics.FromImage(bmp);
    //создаем кисть для прозрачного фона
    SolidBrush whiteBrush = new SolidBrush(Color.FromArgb(0, 1, 1, 1));
    //красной кистью будем писать буквы
    SolidBrush redBrush = new SolidBrush(Color.Red);

    //создаем прямоугольник 16х16 с начальными координатами (0,0)
    RectangleF canvas = new RectangleF(0, 0, 16, 16);
    //закрашиваем его "фоновой" кистью
    graphics.FillRectangle(whiteBrush, canvas);
    //пишем в нем заданную букву красной кистью
    graphics.DrawString("R", font, redBrush, canvas);
    //преобразуем картинку bmp в иконку
    Icon icon = Icon.FromHandle(bmp.GetHicon());

    //уже привычно задаем начальную картинку
    _notifyIcon.Icon = icon;
    //добавляем сознанную иконку в массив, чтобы каждый раз не создавать её заново
    icc[0] = icon;
    icc[7] = icon;

    //снова "затираем" картинку прозрачным цветом
    graphics.Clear(Color.FromArgb(0, 1, 1, 1));
    graphics.DrawString("O", font, redBrush, canvas);
    icon = Icon.FromHandle(bmp.GetHicon());
    icc[1] = icon;

    graphics.Clear(Color.FromArgb(0, 1, 1, 1));
    graphics.FillRectangle(whiteBrush, canvas);
    graphics.DrawString("S", font, redBrush, canvas);
    icon = Icon.FromHandle(bmp.GetHicon());
    icc[2] = icon;
    icc[3] = icon;

    graphics.Clear(Color.FromArgb(0, 1, 1, 1));
    graphics.FillRectangle(whiteBrush, canvas);
    graphics.DrawString("K", font, redBrush, canvas);
    icon = Icon.FromHandle(bmp.GetHicon());
    icc[4] = icon;

    graphics.Clear(Color.FromArgb(0, 1, 1, 1));
    graphics.FillRectangle(whiteBrush, canvas);
    graphics.DrawString("Y", font, redBrush, canvas);
    icon = Icon.FromHandle(bmp.GetHicon());
    icc[5] = icon;

    graphics.Clear(Color.FromArgb(0, 1, 1, 1));
    graphics.FillRectangle(whiteBrush, canvas);
    graphics.DrawString(".", font, redBrush, canvas);
    icon = Icon.FromHandle(bmp.GetHicon());
    icc[6] = icon;

    graphics.Clear(Color.FromArgb(0, 1, 1, 1));
    graphics.FillRectangle(whiteBrush, canvas);
    graphics.DrawString("U", font, redBrush, canvas);
    icon = Icon.FromHandle(bmp.GetHicon());
    icc[8] = icon;
}
///
/// массив для созданных иконок
///
private Icon[] icc = new Icon[9];
///
/// начальный индекс для отображения элементов из массива
///

И:

///
/// обрабатываем тик
///
void _timer_Tick(object sender, EventArgs e)
{
    _notifyIcon.Icon = icc[iii];
    iii++;
    if (iii == 9)
    iii = 0;
}

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

И как всегда в конце статьи, вот пример кода.

Полезная статья? Их будет больше, если вы поддержите меня!

https://money.yandex.ru/embed/small.xml?account=410011399843532&quickpay=small&yamoney-payment-type=on&button-text=06&button-size=l&button-color=orange&targets=%D0%9F%D0%BE%D0%B4%D0%B4%D0%B5%D1%80%D0%B6%D0%B8%D0%B2%D0%B0%D1%8E+%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82+lexpenz.com&default-sum=50&successURL=

Архив комментариев

2 комментария из прежней версии блога. Архив закрыт для новых ответов.

  1. Павел А.

    Спасибо!!!

  2. Хорошо, то что искал. Спасибо!