title: WPF C# Extract and Show Default File Icon
body: <p>I am extracting system default icons (16 * 16 only) for some extensions like XLS, XLSX, PDF etc and trying to show that in Image Control. I am noticing that if I take dump of those icons on disk, they look sharp but the icons in my ListBox look somewhat blurred.</p>
  
  <p>Any ideas what could be going on here ? I have tried a lot of suggestions from the posts I read from but couldn't make the problem go </p>
  
  <p>Code Snippet:</p>
  
  <p>Case1 - I am extracting the icon of file through Win32 Pinvoke - result -> blurrred icons</p>
  
  <pre><code>private const uint SHGFI_ICON = 0x100;
      private const uint SHGFI_LARGEICON = 0x0;
      private const uint SHGFI_SMALLICON = 0x1;
      private const int FILE_ATTRIBUTE_NORMAL = 0x80;
      private const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
      [StructLayout(LayoutKind.Sequential)]
      private struct SHFILEINFO
      {
          public IntPtr hIcon;
          public IntPtr iIcon;
          public uint dwAttributes;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
          public string szDisplayName;
          [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
          public string szTypeName;
      };
      [DllImport("shell32.dll")]
      private static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes,   
     ref SHFILEINFO psfi, uint cbSizeFileInfo, uint uFlags);
  
  private static Icon Extract(string fileName)
  {
  var shinfo = new SHFILEINFO();
  
  IntPtr hIcon = SHGetFileInfo(fileName, 0, ref shinfo, (uint)Marshal.SizeOf(shinfo), SHGFI_ICON | SHGFI_SMALLICON);
  //The icon is returned in the hIcon member of the shinfo struct
  var icon = (Icon)Icon.FromHandle(shinfo.hIcon).Clone();
  DestroyIcon(shinfo.hIcon);
  return icon;
  }
  [DllImport("User32.dll")]
  public static extern int DestroyIcon(IntPtr hIcon);
  </code></pre>
  
  <p>Case2 - Dumping Icon objects created above to disk and viewing them in explorer -> the icons are of excellent quality</p>
  
  <pre><code>string filePath = string.Format("C:\\temp\\Icons\\{0}.ico", iconName.Substring(1));
  var stream = new FileStream(filePath, FileMode.OpenOrCreate);
  iconObject.ExtensionSource.ToBitmap().Save(stream, ImageFormat.Bmp);
  stream.Close();
  </code></pre>
  
  <p>ListBox xaml - </p>
  
  <pre><code>&lt;Grid&gt;
          &lt;Grid.RowDefinitions&gt;
              &lt;RowDefinition Height="Auto"/&gt;
              &lt;RowDefinition Height="*"/&gt;
          &lt;/Grid.RowDefinitions&gt;
  
          &lt;StackPanel Orientation="Horizontal"
                      Grid.Row="0"
                      Margin="10"&gt;
              &lt;TextBox Text="{Binding ExtensionNames, Mode=TwoWay}"
                       ToolTip="Comma Separated List of Extensions, Tab out to persist changes.."
                       Margin="5"/&gt;
              &lt;Button Content="Dump All Icons" 
                      Click="Button_DumpAllIconsClick" 
                      Width="100"
                      ToolTip="Dump Path: C:\temp\Icons"
                      Margin="5"/&gt;
  
          &lt;/StackPanel&gt;
          &lt;ListBox ItemsSource="{Binding Icons}"
                   Grid.Row="1"
                   Margin="2"&gt;
              &lt;ListBox.ItemTemplate&gt;
                  &lt;DataTemplate&gt;
                      &lt;StackPanel Orientation="Horizontal"
                                  HorizontalAlignment="Stretch"
                                  Margin="5"&gt;
                          &lt;TextBlock Text="{Binding ExtensionName}"
                                         FontWeight="Bold"
                                         FontSize="20"/&gt;
                          &lt;Image Source="{Binding Path=ExtensionSource,
                                                  Converter={ExtractIconWPF:IconToImageSourceConverter}}"
                                 Margin="5"/&gt;
                      &lt;/StackPanel&gt;
                  &lt;/DataTemplate&gt;
              &lt;/ListBox.ItemTemplate&gt;
              &lt;ListBox.ItemContainerStyle&gt;
                  &lt;Style TargetType="ListBoxItem"&gt;
                      &lt;Setter Property="HorizontalContentAlignment" Value="Stretch"/&gt;
                  &lt;/Style&gt;
              &lt;/ListBox.ItemContainerStyle&gt;
          &lt;/ListBox&gt;
  &lt;/Grid&gt;
  </code></pre>
  
  <p>How I am converting Icon to ImageSource object:</p>
  
  <pre><code>var stream = GetIconStream(iconObject);
  ImageSource source = GetBitMapImage(stream);
  
  public static Stream GetIconStream(Icon icon)
  {
  var iconStream = new MemoryStream();
  
  var bitmap = icon.ToBitmap();
  bitmap.Save(iconStream, ImageFormat.Png);
  
  return iconStream;
  }
  
  public static ImageSource GetBitMapImage(Stream iconStream)
  {
  var bi = new BitmapImage();
  
  bi.BeginInit();
  bi.StreamSource = iconStream;
  bi.EndInit();
  
  return bi;
  }
  </code></pre>
  
  <p>Any pointers will be highly appreciated!</p>
  
  <p>Thanks</p>