tags:

views:

965

answers:

3

Currently I'm getting a native icon by calling SHGetFileInfo. Then, I'm converting it to a bitmap using the following code. The Bitmap eventually gets displayed in the WPF form.

Is there a faster way to do the same thing?

try
        {
            using (Icon i = Icon.FromHandle(shinfo.hIcon))
            {
                Bitmap bmp = i.ToBitmap();
                MemoryStream strm = new MemoryStream();
                bmp.Save(strm, System.Drawing.Imaging.ImageFormat.Png);
                BitmapImage bmpImage = new BitmapImage();
                bmpImage.BeginInit();
                strm.Seek(0, SeekOrigin.Begin);
                bmpImage.StreamSource = strm;
                bmpImage.EndInit();

                return bmpImage;
            }
        }
        finally
        {
            Win32.DestroyIcon(hImgLarge);
        }
+2  A: 
using System.Windows.Interop;

...

using (Icon i = Icon.FromHandle(shinfo.hIcon))
{

    ImageSource img = Imaging.CreateBitmapSourceFromHIcon(
                            i.Handle,
                            new Int32Rect(0,0,i.Width, i.Height),
                            BitmapSizeOptions.FromEmptyOptions());
}
Thomas Levesque
A: 

I belive there's simpler (more managed) way of solving this hilighted here. http://www.pchenry.com/Home/tabid/36/EntryID/193/Default.aspx

The crux is of the solution is here. System.Drawing.Icon formIcon = IconsInWPF.Properties.Resources.Habs; MemoryStream strm = new MemoryStream(); formIcon.Save( strm ); this.Icon = BitmapFrame.Create( strm );

PHnery
A: 

Thomas's code could be simplified even more. Here's the full code with additional error checking:

            Interop.SHGetFileInfo(path, isFile, ref pifFileInfo);
            IntPtr iconHandle = pifFileInfo.hIcon;
            if (IntPtr.Zero == iconHandle)
                return DefaultImgSrc;
            ImageSource img = Imaging.CreateBitmapSourceFromHIcon(
                        iconHandle,
                        Int32Rect.Empty,
                        BitmapSizeOptions.FromEmptyOptions());
            User32.DestroyIcon(iconHandle);
            return img;

The difference is:

  • no need to create Icon object
  • make sure to handle a case where iconHandle is 0 (IntPtr.Zero) by e.g. returning some pre-defined ImageSource object
  • make sure to use win32 api DestroyIcon() if it comes from SHGetFileInfo()
Krzysztof Kowalczyk