C#, динамическая NotifyIcon с наложением изображения.

Спрашивают, а возможно ли совместить пример с динамически обновляемой NotifyIcon Копия с примером про наложение изображения Копия, чтобы получить что-то типа такого же эффекта, который делает иконка сетевого соединения в Windows 7 при разрыве соединения?

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

Но если очень хочется, то можно.

Для разнообразия будем считать, что основное изображение у нас уже в формате ICO:

А накладываемое должно быть PNG с прозрачностью. Накладывать будем желтый треугольник с красным восклицательным знаком:

В данном случае, размеры накладываемого изображения я прикидывал исключительно методом тыка, на 14 пикселях особо не разгуляешься.

— Заводим необходимые переменные:

Icon TargetIcon = Properties.Resources.target;
Bitmap TargetBitmap = null;
Bitmap ResultBitmap = null;
Bitmap OverlayBitmap = null;
IconConverter icconv = null;

И не забываем экспортировать функцию DestroyIcon из user32.dll [1]:

[System.Runtime.InteropServices.DllImport("user32.dll",
            CharSet = System.Runtime.InteropServices.CharSet.Auto)]
extern static bool DestroyIcon(IntPtr handle);

— Конвертируем иконку TargetIcon в Bitmap. Делается это при помощи класса IconConverter:

//convert icon to bitmap (target)
icconv = new IconConverter();
TargetBitmap = (Bitmap)icconv.ConvertTo(TargetIcon, typeof(Bitmap));

— Достаем из ресурсов накладываемое изображение и далее поступаем, как в [2]:

//overlay bitmap
OverlayBitmap = Properties.Resources.overlay;

//create result bitmap
ResultBitmap = new Bitmap(TargetBitmap.Width, TargetBitmap.Height,
    PixelFormat.Format32bppArgb);

//create Graphics
Graphics graph = Graphics.FromImage(ResultBitmap);
graph.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;

//Draw overlay images
graph.DrawImage(TargetBitmap, 0, 0);
graph.DrawImage(OverlayBitmap, 0, TargetBitmap.Height-OverlayBitmap.Height);            

//result =)
pbTarget.Image = TargetBitmap;
pbOverlay.Image = OverlayBitmap;
pbResult.Image = ResultBitmap;

Когда надо, преобразуем ResultBitmap, где хранится иконка с наложенным изображением, обратно в Icon, и присваиваем ее соответствующему свойству компонента NotifyIcon:

IntPtr hIcon = ResultBitmap.GetHicon();
System.Drawing.Icon niicon = System.Drawing.Icon.FromHandle(hIcon);
niTest.Icon = niicon;

DestroyIcon(niicon.Handle);

Вот что получилось:

Источники

1. C#, динамическая NotifyIcon, иконка в области уведомления Копия
2. C#, WindowsForms, наложение изображений, изменение размеров изображения. Копия

Код примера на GitHub

Добавить комментарий

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