[英]Issues saving Bitmap for system tray icon C#
我正在嘗試編輯位圖,並將其用作系統任務欄圖標的圖標。 我想知道是否有一種方法可以編輯和使用它,而不必將其另存為本地文件,因為這看起來很混亂,並且在.exe的根目錄中保留了.ico文件。 我的代碼如下。
//To Save icon to disk
bitmap.Save("icon.ico", System.Drawing.Imaging.ImageFormat.Icon);
Icon createdIcon = Icon.FromHandle(bitmap.GetHicon());
bitmap.Dispose();
return createdIcon;
有沒有更優雅的方法可以將其保存為內部資源? 還是在內存流中? 另一件事是,此功能每5分鍾運行一次以更新系統任務欄圖標,並且該圖標必須通過該圖標,這樣我就可以在必須關閉流時進行鍛煉。
任何幫助將不勝感激,因為這給我帶來了困擾。
這個問題比您要解決的要容易。 沒有理由將位圖寫出到磁盤上的文件中。 您可以簡單地省略對Save
方法的調用。
GetHIcon
方法是真正的技巧,因為它允許您將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 /調用Win32函數以銷毀GDI圖標對象( DestroyIcon
)並顯式調用它。
但是,請確保您的應用程序在適當的時候執行此操作,以確保舊圖標被銷毀並釋放關聯的內存!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.