Здесь я хочу рассказать об одной интересной возможности. А именно, о том, как создать «на лету» и добавить в трей иконку из ASCII символов, т.е. добавить туда произвольный текст, средствами C# и .net. Честно говоря, я не очень хорошо представляю себе, где это может понадобиться на практике, но вдруг кому пригодится.
Для того, чтобы все получилось, нужно не забыть использовать пространства имен
using System.Drawing;
using System.Drawing.Imaging;
Хотя, если что, то Visual Studio скорее всего сама про них вам напомнит.
Кратко о том, как будем создавать иконку:
- создаем bmp;
- задаем шрифт и его размеры;
- объект для рисования на bmp;
- создаем кисти нужного цвета;
- создаем прямоугольник нужных размеров (естественно, не больше bmp);
- рисуем нужный символ (а точнее даже «строчки»);
- создаем объект GDI+ из нашей bmp с символом ASCII;
- и подставляем его в качестве иконки
В принципе, это все, что нужно. Остальное – это уже нюансы реализации и полет фантазии каждого.
В этом проекте используются:
- 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;
}
Как видно из них, то мигание обеспечивается тупо сменой индекса, бегающего по массиву иконок и своевременным его обнулением. Прозрачной кисть делается указанием использования альфа-канала. Ничего сложного. Возможно, даже слишком просто.
И как всегда в конце статьи, вот пример кода.
Полезная статья? Их будет больше, если вы поддержите меня!
Архив комментариев
2 комментария из прежней версии блога. Архив закрыт для новых ответов.
Спасибо!!!
Хорошо, то что искал. Спасибо!