문제는 해결하는 것보다 간단합니다. 비트 맵을 디스크의 파일에 쓰지 않아도됩니다. 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 개체 누수를 해결하기 위해 위 코드 샘플을 수정하십시오. Timer가 틱하도록 설정된 간격 (또는 앱에서 아이콘이 변경되어야한다고 결정하는 경우)에 따라 얼마나 빨리 달라집니다.
Icon.FromHandle
을 사용하여 만든 아이콘에서 Dispose
메서드를 호출하면 연관된 기본 GDI 개체가 소멸되지 않습니다. 나는 그것이 프로그래머의 기대에 어긋나 기 때문에 WinForms 구현의 버그라고 생각하지만, 분명히 Icon.FromHandle
은 이 아니고은 핸들의 소유권을 가정합니다. 공정하게하기 위해서, 문서 은으로 "비고"섹션에서 이것을 말하고 누가 그것을 읽습니까?
이것을 알지 못하는 경우 손에 메모리가 누출됩니다. 이 문제를 해결하려면 GDI 아이콘 개체 (DestroyIcon
)를 파기하기 위해 Win32 함수를 P/Invoke하고 명시 적으로 호출해야합니다.
응용 프로그램에서 적절한 방법을 사용하여 이전 아이콘이 손상되고 관련 메모리가 해제되는지 확인하십시오!