该问题比解决问题要简单得多。没有理由将位图写入磁盘上的文件。您可以简单地省略对Save
方法的调用。
GetHIcon
method是真正的伎俩,因为它允许您将Bitmap
转换为Icon
,并且您已经找到了一个。
这是我的示例代码。我将一个NotifyIcon
和Timer
控件添加到窗体中,并以明显的方式连接了事件处理程序。 rnd
是Random
的类级别实例,仅用于测试目的。
[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern bool DestroyIcon(IntPtr hIcon);
private void timer1_Tick(object sender, EventArgs e)
{
Icon icon;
// Create a temporary new Bitmap with the size of a notification icon.
using (Bitmap bmp = new Bitmap(SystemInformation.SmallIconSize.Width, SystemInformation.SmallIconSize.Height))
{
// Fill the temporary bitmap with a random number.
using (Graphics g = Graphics.FromImage(bmp))
{
g.DrawString(rnd.Next().ToString(),
SystemFonts.MessageBoxFont,
SystemBrushes.ControlText,
0.0F, 0.0F);
}
// Convert this bitmap to an icon.
icon = Icon.FromHandle(bmp.GetHicon());
}
// Update the notification icon to use our new icon,
// and destroy the old icon so we don't leak memory.
Icon oldIcon = notifyIcon1.Icon;
notifyIcon1.Icon = icon;
DestroyIcon(oldIcon.Handle);
oldIcon.Dispose();
}
完美地工作,不需要临时文件。
编辑:修改上面的代码示例来解决GDI对象泄漏,最终会使您的应用程序瘫痪。取决于计时器设置为打勾的时间间隔(或者您确定图标应该在您的应用程序中更改)的速度有多快。
事实证明,当您使用Icon.FromHandle
创建的图标调用Dispose
方法时,关联的本地GDI对象不会被销毁。我认为这是WinForms实现中的一个错误,因为它无视程序员的期望,但显然Icon.FromHandle
并不是而是假定句柄的所有权。公平地说,文档确实在“备注”部分说明了这一点,但谁读了?
如果你不知道这样做,你的手上就有内存泄漏。要修复它,你必须P/Invoke Win32函数销毁一个GDI图标对象(DestroyIcon
)并明确地调用它。
请确保您的应用程序执行此操作(无论何时适用),以确保旧图标被破坏并释放关联的内存!