該問題比解決問題要簡單得多。沒有理由將位圖寫入磁盤上的文件。您可以簡單地省略對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
)並明確地調用它。
請確保您的應用程序執行此操作(無論何時適用),以確保舊圖標被破壞並釋放關聯的內存!