Здесь я хочу рассказать об одной интересной возможности. А именно, о том, как создать «на лету» и добавить в трей иконку из ASCII символов, т.е. добавить туда произвольный текст, средствами C# и .net. Честно говоря, я не очень хорошо представляю себе, где это может понадобиться на практике, но вдруг кому пригодится.
Для того, чтобы все получилось, нужно не забыть использовать пространства имен
1 2 |
using System.Drawing; using System.Drawing.Imaging; |
Хотя, если что, то Visual Studio скорее всего сама про них вам напомнит.
Кратко о том, как будем создавать иконку:
- создаем bmp;
- задаем шрифт и его размеры;
- объект для рисования на bmp;
- создаем кисти нужного цвета;
- создаем прямоугольник нужных размеров (естественно, не больше bmp);
- рисуем нужный символ (а точнее даже «строчки»);
- создаем объект GDI+ из нашей bmp с символом ASCII;
- и подставляем его в качестве иконки
В принципе, это все, что нужно. Остальное – это уже нюансы реализации и полет фантазии каждого.
В этом проекте используются:
- Bitmap – «Инкапсулирует точечный рисунок GDI+, состоящий из данных пикселей графического изображения и атрибутов рисунка. Объект Bitmap используется для работы с изображениями, определяемыми данными пикселей»;
- Font – «Определяет конкретный формат текста, включая начертание шрифта, его размер и атрибуты стиля. Этот класс не может быть унаследован»;
- Graphics – «Инкапсулирует поверхность рисования GDI+»;
- SolidBrush – «Определяет кисть одного цвета. Кисти используются для заливки графических фигур, таких как прямоугольники, эллипсы, круги, многоугольники и контуры. Этот класс не может быть унаследован»;
- RectangleF – «Содержит набор из четырех чисел с плавающей запятой, определяющих расположение и размер прямоугольника».
Подробнее о них можно посмотреть в MSDN.
Перейдем к коду. В нем относительный интерес представляют следующие участки кода:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
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]; /// /// начальный индекс для отображения элементов из массива /// |
И:
1 2 3 4 5 6 7 8 9 10 |
/// /// обрабатываем тик /// void _timer_Tick(object sender, EventArgs e) { _notifyIcon.Icon = icc[iii]; iii++; if (iii == 9) iii = 0; } |
Как видно из них, то мигание обеспечивается тупо сменой индекса, бегающего по массиву иконок и своевременным его обнулением. Прозрачной кисть делается указанием использования альфа-канала. Ничего сложного. Возможно, даже слишком просто.
И как всегда в конце статьи, вот пример кода.
Полезная статья? Их будет больше, если вы поддержите меня!