2014-07-11 2 views
1

SystemIcons.Warning을 사용하고 싶지만 내 필요에 비해 너무 큽니다. 크기를 조정하고 싶습니다.C에서 시스템 아이콘 크기 조정

가 나는 시도했다 :

Icon sizedIcon = new Icon(SystemIcons.Warning, new Size(10,10)); 

을하지만, 작동하지 않는, 아이콘이 동일하게 유지됩니다.

제안 사항?

+0

아이콘이나 abitmap으로 필요합니까? – TaW

+0

@TaW 나는 아이콘으로 그것을 필요로한다 – eomeroff

답변

6

.NET Icon 클래스는 Windows 98 및 Windows 2000에 대한 한 번 관련성이있는 지원으로 인해 지난 10 년 간 막혔습니다. Windows는 시스템 아이콘을 어떤 크기로든로드하는 것을 지원하지 않습니다. 기타은 시스템의 기본 아이콘 크기보다 큽니다. 보통 32x32. 크기를 조정하면 필연적으로 나빠질 것입니다.

아이콘이 10x10으로 잘 보이지 않는다는 사실을 명심하십시오. 그것은 현대적인 모니터의 한 모퉁이입니다. 원하는 최종 크기에 가까운 아이콘 크기로 시작하여 조금 더 앞서 나갈 수 있습니다. 필요한 크기를 줄이면 덜 복잡해지며, 여전히 합리적으로 보일 확률은 높아집니다. 가능한 경우 아이콘에 표시 될 수있는 크기를 선택하십시오. 16x16, 32x32, 48x48처럼.

Anyhoo,이 입니다. Windows는 이것을 직접 지원하지 않기 때문에 상당한 해킹 - 오 - 라마가 필요하다는 것을 명심하십시오. 필요한 것은 시스템 DLL 리소스에서 직접 아이콘을 읽는 것입니다. 그리고 더 현대적인 winapi 인 LoadImage()가 .NET이 사용하는 LoadImage() 대신에 사용합니다. XP 이상에서 작동합니다.

프로젝트에 새 클래스를 추가하고이 코드를 붙여 넣습니다

using System; 
using System.Drawing; 
using System.Reflection; 
using System.Runtime.InteropServices; 

public class IconEx : IDisposable { 
    public enum SystemIcons { 
     Application = 100, 
     Asterisk = 104, 
     Error = 103, 
     Exclamation = 101, 
     Hand = 103, 
     Information = 104, 
     Question = 102, 
     Shield = 106, 
     Warning = 101, 
     WinLogo = 100 
    } 

    public IconEx(string path, Size size) { 
     IntPtr hIcon = LoadImage(IntPtr.Zero, path, IMAGE_ICON, size.Width, size.Height, LR_LOADFROMFILE); 
     if (hIcon == IntPtr.Zero) throw new System.ComponentModel.Win32Exception(); 
     attach(hIcon); 

    } 
    public IconEx(SystemIcons sysicon, Size size) { 
     IntPtr hUser = GetModuleHandle("user32"); 
     IntPtr hIcon = LoadImage(hUser, (IntPtr)sysicon, IMAGE_ICON, size.Width, size.Height, 0); 
     if (hIcon == IntPtr.Zero) throw new System.ComponentModel.Win32Exception(); 
     attach(hIcon); 
    } 


    public Icon Icon { 
     get { return this.icon; } 
    } 

    public void Dispose() { 
     if (icon != null) icon.Dispose(); 
    } 

    private Icon icon; 

    private void attach(IntPtr hIcon) { 
     // Invoke the private constructor so we can get the Icon object to own the handle 
     var ci = typeof(Icon).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, 
      null, new Type[] { typeof(IntPtr), typeof(bool) }, null); 
     this.icon = (Icon)ci.Invoke(new object[] { hIcon, true}); 
    } 

    private const int IMAGE_ICON = 1; 
    private const int LR_LOADFROMFILE = 0x10; 
    private const int LR_SHARED = 0x8000; 

    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    private static extern IntPtr GetModuleHandle(string name); 
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    private static extern IntPtr LoadImage(IntPtr hinst, string lpszName, int uType, 
           int cxDesired, int cyDesired, int fuLoad); 
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)] 
    private static extern IntPtr LoadImage(IntPtr hinst, IntPtr resId, int uType, 
           int cxDesired, int cyDesired, int fuLoad); 
} 

샘플 사용 :

using (var icon = new IconEx(IconEx.SystemIcons.Warning, new Size(10, 10))) { 
     e.Graphics.DrawIcon(icon.Icon, 0, 0); 
    } 

그것은 이 SystemIcons.Warning보다 더 잘 수행합니다. 16x16을 사용할 때 삐걱 거리는 소리가 들리지 않습니다.

+0

나는 왜 나는 당신의 대답을 투표하는 것을 귀찮게하는지 모른다. 아침에는 항상 200 대가 넘습니다. 아르헨티나 경기에 대해 유감입니다. – LarsTech

+1

슬프고 슬픈 게임이었습니다. 토요일에 브라질을 완전히 넘어서. –

관련 문제