2013-03-14 1 views
0

비트 맵을 편집하여 시스템 트레이 아이콘의 아이콘으로 사용하려고합니다. 나는 그것을 편집 할 수있는 방법이 있는지 알고 싶습니다.이 파일을 지저분하게 생각하고 .exe 파일의 루트 디렉토리에 .ico 파일을 남기므로 로컬 파일로 저장하지 않고 사용할 수 있습니다. 내가 가지고있는 코드는 다음과 같습니다.시스템 트레이 아이콘의 비트 맵 저장 문제 C#

//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 분마다 시스템 트레이 아이콘을 업데이트하기 위해 실행되며 아이콘을 전달해야하므로 스트림을 닫아야 할 때 해결할 수 있습니다.

이 도움이 필요하시면 도움을 주시면 대단히 감사하겠습니다.

답변

1

문제는 해결하는 것보다 간단합니다. 비트 맵을 디스크의 파일에 쓰지 않아도됩니다. Save 메소드에 대한 호출을 간단히 생략 할 수 있습니다.

GetHIcon methodBitmapIcon으로 변환 할 수 있으며 이미 발견 했으므로 실질적인 트릭입니다.

다음은 샘플 코드입니다. NotifyIconTimer 컨트롤을 양식에 추가하고 명백한 방식으로 이벤트 처리기를 배선했습니다. 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하고 명시 적으로 호출해야합니다.

응용 프로그램에서 적절한 방법을 사용하여 이전 아이콘이 손상되고 관련 메모리가 해제되는지 확인하십시오!